spotify / pedalboard

🎛 🔊 A Python library for audio.
https://spotify.github.io/pedalboard
GNU General Public License v3.0
4.96k stars 249 forks source link

Question: Is it possible to write the output of an AudioStream to a .wav file as it's streaming? #328

Open rohancherukuri14 opened 1 month ago

rohancherukuri14 commented 1 month ago

I want to be able to write the audio that is being sent to my output device from an AudioStream to a .wav file in real-time, or somehow record the audio and write it after. I've been looking online and don't see any clear way to do this. Thanks!

psobot commented 1 month ago

Hi @rohancherukuri14!

You're correct, there isn't currently a way to do this with Pedalboard alone. I've proposed a potential change to the AudioStream class (see https://github.com/spotify/pedalboard/pull/317#issuecomment-2079999624) that would allow AudioStream to buffer audio in-memory, which could then be written to a file; but this hasn't been built yet.

If you need this functionality, I'd recommend using pyAudio and streaming the results into a buffer that you can then write with AudioFile.

rohancherukuri14 commented 1 month ago

Hi! Thank you for the quick response! How exactly would I do this? Would I specify the audio buffer as the output to the buffer? Or just append stream to the buffer?

For context, I'm using a pretty simple example:

input_device_name = 'External Microphone'
output_device_name = 'External Headphones'
start_time = time.time()

while True:
    with AudioStream(input_device_name, output_device_name, allow_feedback=True) as stream:

        stream.plugins.append(Chorus())
        stream.plugins.append(Distortion())
        stream.plugins.append(Reverb())

        while len(stream.plugins) > 0:
            del stream.plugins[0]
rohancherukuri14 commented 1 month ago

I also tried using the .process() method to write to an ndarray, but the buffer still has all zeroes after recording:

from pedalboard.io import AudioStream
from pedalboard import Reverb, Chorus, Distortion
import soundcard as sc
import soundfile as sf
import time
import pyaudio
import numpy as np

input_device_name = 'External Microphone'
output_device_name = 'External Headphones'
start_time = time.time()

SAMPLE_RATE = 48000  # Hz
DURATION = 10  # seconds

start_time = time.time()
# Calculate the total number of samples
total_samples = int(SAMPLE_RATE * DURATION)

# Initialize a 32-bit floating point audio buffer for stereo (2 channels)
audio_buffer = np.zeros((total_samples, 2), dtype=np.float32)

while time.time() - start_time < DURATION:
    with AudioStream(input_device_name, output_device_name, allow_feedback=True) as stream:

        stream.plugins.append(Chorus())
        stream.plugins.append(Distortion())
        stream.plugins.append(Reverb())

        audio_buffer = stream.plugins.process(audio_buffer, SAMPLE_RATE, buffer_size=len(audio_buffer), reset=False)

        while len(stream.plugins) > 0:
            del stream.plugins[0]

print(audio_buffer[audio_buffer != 0])