(Reposted as smaller message)
Dear list
I'm writing an "external" (a plug-in) for Max/MSP to allow me to process audio with a specified Audio Unit. So far the external loads the AU and initializes it and Max supplies me with audio buffers. I'm just stumped as to how to actually process those buffers with the AU.
Max sends the audio a routine in my external (below), as 2 small buffers of non-interleaved Float 32 data. Ideally, I would like to just process those buffers directly with my Audio Unit using the AudioUnitRender call, have the AU do in-place processing, then send it back out. But AudioUnitRender returns the "not connected" error (-10876) if the Audio Unit isn't part of a graph, or there's no AURenderCallback installed.
I don't need an AUGraph — I just want the one Audio Unit loaded and not connected to any input or output device, as Max handles that. But if I'm right, then using an AURenderCallback means having to manage my own internal state & buffers in a rather cumbersome way. The trouble is that Max supplies me with audio in its own time and expects processed audio in return immediately, but the AU will only send a callback when it's ready, which may not be at the same time as Max. In other words: both Max and the AURenderCallback call different routines in their own time — how do I make them talk to one another?
Thanks, Michael
Below is a snippet of code to give you an idea:
t_int *au2_perform(t_int *w) { //This is the routine that Max calls when it has more audio for me to process char s[256]; t_au *x; int i,j; ComponentResult result; AudioUnitRenderActionFlags actionFlags = 0; int numFramesToProcess = (int)(w[5]); x = (t_au*)w[6]; // x is just a pointer to a struct containing my state variables
for ( i = 0; i < kNumChannels; i++) { x->x_theAudioData->mBuffers[i].mDataByteSize = numFramesToProcess * sizeof(Float32); }
// Point to the supplied audio buffers x->x_theAudioData->mBuffers[0].mData = (t_float *)(w[2]); // left-channel buffer of audio (NB: t_float is a Float32) x->x_theAudioData->mBuffers[1].mData = (t_float *)(w[3]); // right-channel buffer of audio
// In the loop below, AudioUnitRender returns a "not connected" error. // So what's the easiest, least time-consuming way, to get my AudioUnit to *just process these darned buffers*? for ( j = 0; j < kNumChannels; j++) { result = AudioUnitRender (x->x_au, &actionFlags, &(x->x_myTimeStamp), 0, numFramesToProcess, x->x_theAudioData); }
// increment time stamp etc... } |