[Audio] Python Pedalboard를 활용해 Audio를 바꾸기

2024. 10. 10. 22:44Developers 공간 [Shorts]/Vision & Audio

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

 

이번 글에서는 Pedalboard 패키지를 활용해 아래와 같은 처리를 하는 방법을 정리하고자 합니다.

** https://github.com/spotify/pedalboard

  • 오디오를 빠르게/느리게
  • 오디오에 다양한 Effect를 적용

2. Why? (원인)

  • X

3. How? (해결책)

 

기존에 Pedalboard를 활용해 오디오를 불러오는 경우 아래와 같이 진행할 수 있었습니다.

from pedalboard.io import AudioFile
import torch
import soundfile as sf

with AudioFile(input_file) as f:
    audio=f.read(f.frames)
    audio=torch.from_numpy(audio)
    in_sr=f.samplerate
    
sf.write(output_file, audio[0], in_sr)

** 본 글과는 상관없지만, 위는 input_file을 읽어 output_file로 저장해주는 코드인데, audio[0]를 해준 이유는 Soundfile패키지로 저장을 하려면 mono 데이터여야 하기 때문입니다. 아래의 방법을 활용하면 stereo 데이터를 저장하는데 사용할 수도 있습니다.

 

이제 이와 비슷한 구조를 활용해 아래와 같은 처리를 해보겠습니다. 참고로, 해당 글에서사용하는 input_fileoutput_file은 아래와 같이 주었습니다.

input_file = "./input.mp3"
output_file = "./output.wav"

 


 

a. 오디오를 빠르게/느리게

 

먼저 BPM의 변화를 확인하기 위해서는 essentia 패키지를 아래와 같이 활용했습니다.

import essentia.standard as es

audio = es.MonoLoader(filename=file)() 
bpm_cal, _, beats_confidence, _, _ = rhythm_extractor = es.RhythmExtractor2013(method="multifeature")(audio)
print("BPM : {}".format(bpm_cal))

 

이제 Pedalboard를 활용해 1.2배 빠르게 하는 방법은 아래와 같습니다. 

fast_rate = 1.2

with AudioFile(input_file) as f:
    with AudioFile(output_file, 'w', f.samplerate*fast_rate, f.num_channels) as o : 
        while f.tell() < f.frames:
            chunk = f.read(f.samplerate)
            
            o.write(chunk)

즉, input_file에서 불러와 output_file로 저장하는데, 각각의 sample rate만큼의 chunk에 대해 더 높은 sample rate의 오디오로 저장해주면

  • 실제 sample rate보다 더 높은 sample rate라고 예상하고
  • 기존의 오디오 chunk들을 저장하게됩니다.

따라서 오디오 자체가 더 빠르게 만들어질 수 있습니다.

 

역시나 반대로 Pedalboard를 활용해 0.8배로 느리게 하는 방법은 아래와 같습니다.

slow_rate = 0.8

with AudioFile(input_file) as f:
    with AudioFile(output_file, 'w', f.samplerate*slow_rate, f.num_channels) as o : 
        while f.tell() < f.frames:
            chunk = f.read(f.samplerate)
            
            o.write(chunk)

 


 

b. 오디오에 다양한 Effect를 적용

 

음악 같은 경우 Compressor, Chorus, Reverb 등등 다양한 처리를 통해 효과를 주어야 하는 경우가 있습니다.

 

Pedalboard를 활용해 ReverbChorus를 주어 저장하는 방법은 아래와 같습니다.

from pedalboard import Pedalboard, Chorus, Reverb

board = Pedalboard([Chorus(), Reverb(room_size=0.25)])

with AudioFile(input_file) as f:
    with AudioFile(output_file, 'w', f.samplerate, f.num_channels) as o : 
        while f.tell() < f.frames:
            chunk = f.read(f.samplerate)
            effected = board(chunk, f.samplerate, reset=False)
            
            o.write(effected)

 

위에 더해 Compressor, Gain, Filter, Phaser, Convolution 등의 효과에 대한 예시는 아래와 같습니다.

from pedalboard import *

board = Pedalboard([
    Compressor(threshold_db=-50, ratio=25),
    Gain(gain_db=30),
    Chorus(),
    LadderFilter(mode=LadderFilter.Mode.HPF12, cutoff_hz=900),
    Phaser(),
    Convolution("./guitar_amp.wav", 1.0),
    Reverb(room_size=0.25),
])

with AudioFile(input_file) as f:
    with AudioFile(output_file, 'w', f.samplerate, f.num_channels) as o : 
        while f.tell() < f.frames:
            chunk = f.read(f.samplerate)
            effected = board(chunk, f.samplerate, reset=False)
            
            o.write(effected)

 

728x90
반응형