• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Polling Callback, Threads [Attn: Michael Thornburgh]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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.

References: 
 >Polling Callback, Threads [Attn: Michael Thornburgh] (From: Daniel Todd Currie <email@hidden>)
 >Re: Polling Callback, Threads [Attn: Michael Thornburgh] (From: Michael Thornburgh <email@hidden>)
 >Re: Polling Callback, Threads [Attn: Michael Thornburgh] (From: Daniel Todd Currie <email@hidden>)
 >Re: Polling Callback, Threads [Attn: Michael Thornburgh] (From: Michael Thornburgh <email@hidden>)
 >Re: Polling Callback, Threads [Attn: Michael Thornburgh] (From: Daniel Todd Currie <email@hidden>)
 >Re: Polling Callback, Threads [Attn: Michael Thornburgh] (From: Michael Thornburgh <email@hidden>)
 >Re: Polling Callback, Threads [Attn: Michael Thornburgh] (From: Daniel Todd Currie <email@hidden>)

  • Prev by Date: RE: Subsampling with AudioConverter?
  • Next by Date: Re: [Semi-OT] 192kHz/96kHz soundcard recommendations ?
  • Previous by thread: Re: Polling Callback, Threads [Attn: Michael Thornburgh]
  • Next by thread: Sample rate conversions how ?
  • Index(es):
    • Date
    • Thread