Re: Polling Callback, Threads [Attn: Michael Thornburgh]
Re: Polling Callback, Threads [Attn: Michael Thornburgh]
- Subject: Re: Polling Callback, Threads [Attn: Michael Thornburgh]
- From: Michael Thornburgh <email@hidden>
- Date: Thu, 11 Dec 2003 17:19:04 -0800
in your IOProc, you're doing this:
[client->aQueue writeBytesWithoutBlockingFrom:client->tempBuffer
length:(frameCount * sizeof(Float32))];
you're missing the number of channels there for the length, so (if the
buffer is stereo) you're only writing the first half of it into the
MTCQ.
i also see that you're writing client->tempBuffer instead of the actual
audio sent to your IOProc. i assume you'll eventually have something
to take the inInputData and interleave any multiple streams into a
single-stream buffer (client->tempBuffer) with the expected number of
channels.
if you only cared about the first stream, your IOProc could look like
this:
OSStatus recordIOProc(AudioDeviceID inDevice, const AudioTimeStamp*
inNow, const AudioBufferList* inInputData, const AudioTimeStamp*
inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp*
inOutputTime, void* inClientData)
{
Recorder *client = (Recorder *)inClientData;
AudioBuffer firstBuffer = inInputData->mBuffers[0];
[client->aQueue writeBytesWithoutBlockingFrom:firstBuffer.mData
length:firstBuffer.mDataByteSize];
return kAudioHardwareNoError;
}
and then you keep track of the number of channels represented in the
MTCQ by listening for appropriate notifications from the HAL (and
flushing it when the number of channels changes).
-mike
ps: if it was me, i'd change the "waitUntilDone:" to "YES" and allow
the size of the MTCircularQueue to limit how far behind you can get.
the main thread's NSRunLoop can probably hold as many of your
performSelectorOnMainThread:withObject:waitUntilDone:s as you can throw
at it, so you could still suffer from the farther-and-farther
more-and-more problem i mentioned earlier.
On Dec 11, 2003, at 4:21 PM, Daniel Todd Currie wrote:
So I've been working with MTCircularQueue for a couple hours now and I
have implemented the queue read as such:
- (void)runBufferDrain
{
unsigned byteCount = 1024 * sizeof(Float32);
Float32 *dspBuffer = malloc(byteCount);
while(1)
{
NSAutoreleasePool *drainPool = [[NSAutoreleasePool alloc]
init];
[aQueue readBytesTo:dspBuffer length:byteCount];
NSData *floatDataObject = [NSData dataWithBytes:dspBuffer
length:byteCount];
[audioDelegate
performSelectorOnMainThread:@selector(processAudioBuffer:)
withObject:floatDataObject waitUntilDone:NO];
[drainPool release];
}
}
I have it running entirely in it's own thread, so the while loop
should not be significantly held up at any point.
The problem is that it is taking twice as long as it should to collect
the buffer. 512 samples / 44100 samples per second should be
capturing a buffer every 11.61 milliseconds. However, the while
condition is looping every 23 milliseconds. When I was sending the
buffer out directly from the callback using
performSelectorOnMainThread, it was indeed sending about every 11
milliseconds. My CoreAudio callback is as follows (part of the
Recorder class):
OSStatus recordIOProc(AudioDeviceID inDevice, const AudioTimeStamp*
inNow, const AudioBufferList* inInputData, const AudioTimeStamp*
inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp*
inOutputTime, void* inClientData)
{
Recorder *client = (Recorder *)inClientData;
unsigned frameCount = (inInputData->mBuffers[0].mDataByteSize /
inInputData->mBuffers[0].mNumberChannels) / sizeof(Float32);
[client->aQueue writeBytesWithoutBlockingFrom:client->tempBuffer
length:(frameCount * sizeof(Float32))];
return kAudioHardwareNoError;
}
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.