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: Fri, 12 Dec 2003 16:34:20 -0800
at least with the code you included earlier, it wasn't that you were
writing every other buffer, but that you were writing only the first
half of every buffer into the MTCQ, but then trying to take out a whole
buffer's worth. so it'll take two half-fills before enough is
available to satisfy the full-size withdrawal. the reason that's
happening is that you're writing frameCount*sizeof(Float32) bytes.
most likely, frameCount is 512, so you're writing 512 Float32s. on the
input (assuming one stereo stream), there are 512 *frames* of two
Float32 samples, or 1024 Float32 samples total. on the consumer end,
you're reading 1024*sizeof(Float32) bytes out. so that's where the
half-speed comes from.
also, in the code you included earlier, the audio data (in inInputData)
was never making it to the MTCQ. it appeared that you were sending the
same data over and over to your DSP (whatever already happened to be in
client->tempBuffer). that could explain your unchanging result.
-mike
On Dec 11, 2003, at 7:27 PM, Daniel Todd Currie wrote:
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.
_______________________________________________
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.