• 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
AudioConverterFillComplexBuffer() and its AudioConverterComplexInputDataProc
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AudioConverterFillComplexBuffer() and its AudioConverterComplexInputDataProc


  • Subject: AudioConverterFillComplexBuffer() and its AudioConverterComplexInputDataProc
  • From: Chris Adamson <email@hidden>
  • Date: Tue, 17 Apr 2012 15:27:49 -0400

OK, question on AudioConverterFillComplexBuffer() for anyone who might have done what I'm doing, namely, replacing an Audio Queue with your own in-line conversion:

* Is there any limit to how much data can be returned by the AudioConverterComplexInputDataProc callback?

My method gets repeatedly called with a fairly typical blob of compressed audio data: void* for the data, plus an array of packet descriptions and a numPackets count. I need to convert this to LPCM, so I have an AudioConverterRef set up. The call looks like this:

err = AudioConverterFillComplexBuffer(_converterSettings.audioConverter,
                                      MyConverterCallback,
                                      &_converterSettings,
                                      &ioOutputDataPacketCount,
                                      &convertedData,
                                      NULL);

Since I don't provide the encoded data to this function, and instead have to provide it via the MyConverterCallback function, I basically store off the encoded data in my _converterSettings object, and then use the callback to simply hand back that data. This is prior to the AudioConverterFillComplexBuffer() call, of course:

_converterSettings.sourceData = (void*) data;
_converterSettings.sourceNumBytes = numBytes;
_converterSettings.sourceNumPackets = numPackets;
_converterSettings.sourcePacketDescriptions = packetDescriptions;

So, in the callback, I can just return that info that I saved off:

OSStatus MyConverterCallback(AudioConverterRef inAudioConverter,
                             UInt32 *ioDataPacketCount,
                             AudioBufferList *ioData,
                             AudioStreamPacketDescription **outDataPacketDescription,
                             void *inUserData) {
    MyAudioConverterSettings *userDataConverterSettings = (MyAudioConverterSettings*) inUserData;
    ioData->mBuffers[0].mData = userDataConverterSettings->sourceData;
    ioData->mBuffers[0].mNumberChannels = userDataConverterSettings->sourceFormat.mChannelsPerFrame;
    ioData->mBuffers[0].mDataByteSize = userDataConverterSettings->sourceNumBytes;
    *ioDataPacketCount = userDataConverterSettings->sourceNumPackets;
    if (outDataPacketDescription) {
        *outDataPacketDescription = userDataConverterSettings->sourcePacketDescriptions;
    }
}

But here's the thing. It's possible that the input data, when decoded, could be larger than the convertedData output buffer that receives the result of the AudioConverterFillComplexBuffer() call. In my own testing, when I have a fairly small (64 KB) convertedData output buffer, I get lots of glitching as packets are apparently skipped, but with a big buffer (512 KB), it sounds great. 

However, there's no apparent limit on how much data the callback can provide. If the using a smaller convertedData buffer means I only want to return enough input packets to fill the output buffer, I could buffer the rest of my input packets for the next callback (perhaps requiring some rewriting of offsets in the packet descriptions array, ugh). But the ioDataPacketCount only sets a minimum number of packets that must be returned, not a maximum that won't overflow the receiving buffer.

Is the converter doing its own buffering of extra input if it gets more than it needs (maybe just skipping the next callback), or just dropping it on the floor?

If the converter has an upper limit to how much data it can take at once, is there a strategy for signaling to my callback how much data it can return without overflowing AudioConverterFillComplexBuffer()'s output buffer? Perhaps get the kAudioConverterPropertyCalculateInputBufferSize property prior to the converter call and only return that much data from the callback? Or is there away to allocate an appropriately-sized convertedData output buffer on each call, based on how much input the converter will be receiving from the callback?

Thanks in advance…

--Chris
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: Re: Avila/Adamson CoreAudio book
  • Next by Date: Visual feedback from volume changes
  • Previous by thread: Re: AUval '1.2.1b3' fails, but '1.6.1a' is OK! - [fixed]
  • Next by thread: Visual feedback from volume changes
  • Index(es):
    • Date
    • Thread