Re: Polling Callback, Threads [Attn: Michael Thornburgh]
Re: Polling Callback, Threads [Attn: Michael Thornburgh]
- Subject: Re: Polling Callback, Threads [Attn: Michael Thornburgh]
- From: Daniel Todd Currie <email@hidden>
- Date: Thu, 11 Dec 2003 19:27:53 -0800
Yah, I'm taking care of the interleaving in the first stage of my DSP
method.
I've fixed the problems you've suggested; now that I think about it,
waitUntilDone:YES is certainly the correct way to implement this.
However, this is still taking far too long and is giving me an
unchanging result of 25.570 Hz. I'm going to take a closer look at the
actual buffer data at various stages, but I have to step out for the
evening. Do you have any guesses as to why these buffers are taking so
long to get picked up by the MTCQ? I haven't changed the pre-MTCQ
version, so I'm using it as the control for performance testing; the
MTCQ version is still functioning at half the speed of the pre-MTCQ
version. If it is only picking up every other buffer, that would
explain why it is going half the speed, but it still shouldn't result
in the 25.570 Hz problem. You may want to wait until I have some more
conclusive data.
Thanks for your help,
Daniel
On 2003 Dec 11, at 17:19, Michael Thornburgh wrote:
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.
_______________________________________________
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.