Question: Is it possible to write the output of an AudioStream to a .wav file as it's streaming?
rohancherukuri14 opened this issue · 5 comments
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!
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 #317 (comment)) 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
.
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]
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])
Thanks @0xdevalias - yup, this functionality is now part of v0.9.12:
from pedalboard.io import AudioStream, AudioFile
from pedalboard import Reverb, Chorus, Distortion, Pedalboard
input_device_name = AudioStream.default_input_device_name
DURATION = 10 # seconds
# Make a Pedalboard:
board = Pedalboard([Chorus(), Distortion(), Reverb()])
CHUNK_SIZE = 512
with AudioStream(input_device_name) as stream:
with AudioFile("output.wav", "w", stream.sample_rate, stream.num_input_channels) as f:
while f.frames < (f.samplerate * DURATION):
f.write(board.process(stream.read(CHUNK_SIZE), stream.sample_rate, reset=False))