-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Hi, first of all, thanks for sharing your excellent project. There's really is nothing as comprehensive out there!
I have a question about the callback api since I'm in the midst of a preliminary effort to try to cythonize libpd and enable sound input/ouput via portaudio.
Your example, 'test_playback.py', which I got to work, shows how numpy generated data can be use to generate sound.
In my case, I have an libpd api sound generation function libpd_process_double which I think I have to embed in the portaudio callback as follows:
cimport libpd
cimport libportaudio
from cpython cimport array
from libc.stdio cimport printf, fprintf, stderr, FILE
DEF N_TICKS = 1
DEF SAMPLE_RATE = 44100
DEF CHANNELS_IN = 1
DEF CHANNELS_OUT = 2
DEF BLOCKSIZE = 64
DEF IN_BUF = CHANNELS_IN * BLOCKSIZE
DEF OUT_BUF = CHANNELS_OUT * BLOCKSIZE
cdef struct UserAudioData:
# one input channel, two output channels
double inbuf[N_TICKS * BLOCKSIZE * CHANNELS_IN]
# block size 64, one tick per buffer
double outbuf[N_TICKS * BLOCKSIZE * CHANNELS_OUT]
# stereo outputs are interlaced, s[0] = RIGHT, s[1] = LEFT, etc..
# globals
cdef UserAudioData data
cdef int audio_callback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const libportaudio.PaStreamCallbackTimeInfo* timeInfo,
libportaudio.PaStreamCallbackFlags statusFlags,
void *userData ):
"""Called by the PortAudio engine when audio is needed.
It may called at interrupt level on some machines so don't do anything
that could mess up the system like calling malloc() or free().
"""
# Cast data passed through stream to our structure.
cdef UserAudioData *data = <UserAudioData*>userData
cdef float *out = <float*>outputBuffer
cdef unsigned int i;
libpd.libpd_process_double(N_TICKS, data.inbuf, data.outbuf)
# dsp perform routine
for i in range(framesPerBuffer * CHANNELS_OUT):
if (i % 2):
out[i] = data.outbuf[i]
else:
out[i] = data.outbuf[i]
return 0Any attempts to have libpd_process_double write to UserAudioData outside the callback just doesn't work properly in this case.
I would love to use your library which has a much more robust cythonized wrapping of the portaudio api. However I can't decide if I need to write my own version of your <PaStreamCallback*>_stream_callback which is handled by StreamCallback to address my use case. I would appreciate any advice to this end.
Thanks in advance for any help!
S