Sorry to keep bugging... still working through this in bits and spurts. It's possible I'll end up relying on an ADC support incident to connect the last few dots, but so long as I think there are still things I can try, I'm going to plug away...
FWIW, your message talks about getting the bytes-available callback... I'm not currently using a callbacks-driven approach with the CFReadStream and have instead just been doing CFReadStreamRead in an ad hoc manner. Listening to you and reading the
CFNetwork Programming Guide, I guess setting up a run loop and getting callbacks is the preferred approach...
Buffering totally makes sense for getting packets over to the queue. After all, I get a callback with packets from the AudioFileStream before I get any callbacks from the AudioQueue to fill its buffers, so I need to hang on to those packets. Moreover, it looks like I typically get multiple "handle packets" callbacks before each "fill queue buffer" callback, so it seems like I need to combine all those packets together to service the callback (though I think you argued for an alternative strategy of just holding onto those buffers and servicing them later if necessary).
Those packet callbacks provide an array of AudioStreamPacketDescriptions, plus a big ol' pointer to audio data. The example in the
Audio Queue Programming Guide has the luxury of a 1-to-1 correspondence of queue callbacks to fetched audio data (since it reads from the file as part of the queue callback), so it can put the audio data pointer right into the AudioQueueBuffer's mAudioData as part of the AudioFileReadPackets call, and provide the packet descriptions in the AudioQueueEnqueueBuffer call).
That's not the case for streaming, which is what seems like my current hard part. On the one hand, it seems that to service the queue callback, ie, to have
one array of packet descriptions and
one pointer to audio data, that I need to be building those up on the packet callbacks... which I guess means memcpy'ing over the audio data from each packet callback to a big old buffer, and all the packet descriptions to a bigger and bigger array? Or is this why you instead recommend holding onto queue buffers, not servicing them on the callback, and instead filling them on some other schedule?
Anyways, sorry for the nagging... thanks for previous help.
--Chris
On Apr 3, 2008, at 12:53 AM, Jens Alfke wrote:
I wouldn't handle either of those tasks in a loop, frankly. Instead, do some buffering in between. The flow of control kind of looks like this, in a sort of made-up non-procedural pseudocode (apparently there are languages, like Occam, that look something like this):
* WHEN there's data available on the CFReadStream AND your intermediate packet buffer isn't full, THEN feed the bytes into the AudioFileStream and push the output packets into the packet buffer.
* WHEN the AudioQueue has spare buffers*, AND your packet buffer has enough packets in it, THEN fill up an AudioQueue buffer with packets and enqueue it.