• 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: Examples for AudioFileStream and AudioConverter?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Examples for AudioFileStream and AudioConverter?


  • Subject: Re: Examples for AudioFileStream and AudioConverter?
  • From: Nick Zitzmann <email@hidden>
  • Date: Wed, 10 Sep 2008 12:26:46 -0600

Apparently nobody had any sample code, so I'm posting my code in the hope that someone will tell me what I need to do to get this to work. Again, I can get the AudioFileStream working just fine, but I'm doing AudioConverterFillComplexBuffer() completely wrong, and I need to know how to do this correctly.

The MP3 data I get from the application can be anywhere from less than a kilobyte to several megabytes in size, and is often in VBR format. The data is stored inside an internal data structure's srcBasicDescription, which is an AudioStreamBasicDescription.

SDFillOutASBDForLPCM() is a function that internally calls FillOutASBDForLPCM() in the CoreAudio headers using the same arguments. I just did that so I can keep C and C++ code segregated.

What am I doing wrong here and how do I correct it?

typedef struct
{
	UInt32 numberBytes;
	UInt32 numberDataPackets;
	const void *inputData;
	AudioStreamPacketDescription *packetDescriptions;
	UInt32 sizePerPacket;
	UInt32 numberChannels;
} SDComplexBufferInfo;


static void SDPropertyListenerProc(void *inClientData, AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 *ioFlags)
{
SwfdecMacOSXAudioDecoder *decoder = (SwfdecMacOSXAudioDecoder *)inClientData;
UInt32 size;
OSStatus err;

if (inPropertyID == kAudioFileStreamProperty_DataFormat)
{
size = (UInt32)sizeof(AudioStreamBasicDescription);
err = AudioFileStreamGetProperty(inAudioFileStream, inPropertyID, &size, &decoder->srcBasicDescription);
if (err != noErr)
swfdec_audio_decoder_error(SWFDEC_AUDIO_DECODER(decoder), "Failed to get basic description of audio: %d", err);
}
else if (inPropertyID == kAudioFileStreamProperty_PacketSizeUpperBound) // this will probably never be reached, since the MP3 format doesn't have packet tables
{
size = (UInt32)sizeof(UInt32);
err = AudioFileStreamGetProperty(inAudioFileStream, inPropertyID, &size, &decoder->srcSizePerPacket);
if (err != noErr)
swfdec_audio_decoder_error(SWFDEC_AUDIO_DECODER(decoder), "Failed to get packet size: %d", err);
}
}



OSStatus SDConverterComplexInputDataProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData)
{
SDComplexBufferInfo *info = (SDComplexBufferInfo *)inUserData;
UInt32 maxPackets = info->numberBytes/info->sizePerPacket;

if (*ioNumberDataPackets > maxPackets)
*ioNumberDataPackets = maxPackets;

ioData->mBuffers[0].mData = (void *)info->inputData;
ioData->mBuffers[0].mDataByteSize = info->numberBytes;
ioData->mBuffers[0].mNumberChannels = info->numberChannels;

if (outDataPacketDescription)
{
if (info->packetDescriptions)
*outDataPacketDescription = info->packetDescriptions;
else
*outDataPacketDescription = NULL;
}
return noErr;
}



static void SDPacketsProc(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions)
{
SwfdecMacOSXAudioDecoder *decoder = (SwfdecMacOSXAudioDecoder *)inClientData;
OSStatus err;
AudioStreamBasicDescription outputFormat;
UInt32 outputSizePerPacket;
const UInt32 outputBufferSize = 32768;
unsigned char *outputBuffer = malloc(outputBufferSize*sizeof(unsigned char));
UInt32 numOutputPackets;
SwfdecBuffer *buffer;
SDComplexBufferInfo inBufferInfo;

SDFillOutASBDForLPCM(&outputFormat, 44100.0, 2, 16, 16, false, false);
outputSizePerPacket = outputFormat.mBytesPerPacket; // should always be non-zero since we're not using VBR
numOutputPackets = outputBufferSize/outputSizePerPacket;

if (decoder->audioConverter == NULL)
{
err = AudioConverterNew(&decoder->srcBasicDescription, &outputFormat, &decoder->audioConverter);
if (err != noErr)
{
swfdec_audio_decoder_error(SWFDEC_AUDIO_DECODER(decoder), "Couldn't create audio converter: %d", err);
return;
}
}

inBufferInfo.numberBytes = inNumberBytes;
inBufferInfo.numberDataPackets = inNumberPackets;
inBufferInfo.inputData = inInputData;
inBufferInfo.packetDescriptions = inPacketDescriptions;
inBufferInfo.numberChannels = decoder- >srcBasicDescription.mChannelsPerFrame;
if (decoder->srcBasicDescription.mBytesPerPacket == 0) // true if VBR
{
if (decoder->srcSizePerPacket == 0) // true if MP3, since this is not known for MP3 files
{
UInt32 size = (UInt32)sizeof(UInt32);

err = AudioConverterGetProperty(decoder->audioConverter, kAudioConverterPropertyMaximumInputPacketSize, &size, &inBufferInfo.sizePerPacket); // why does this apparently always return 8192?
}
else
inBufferInfo.sizePerPacket = decoder->srcSizePerPacket; // VBR audio
}
else
inBufferInfo.sizePerPacket = decoder- >srcBasicDescription.mBytesPerPacket; // CBR audio

while (1)
{
AudioBufferList fillBufferList;
UInt32 ioOutputDataPackets = numOutputPackets;

fillBufferList.mNumberBuffers = 1;
fillBufferList.mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame;
fillBufferList.mBuffers[0].mDataByteSize = outputBufferSize;
fillBufferList.mBuffers[0].mData = outputBuffer;
err = AudioConverterFillComplexBuffer(decoder->audioConverter, SDConverterComplexInputDataProc, &inBufferInfo, &ioOutputDataPackets, &fillBufferList, NULL);
if (err != noErr)
{
swfdec_audio_decoder_error(SWFDEC_AUDIO_DECODER(decoder), "Couldn't fill the converter's buffer: %d", err);
return;
}
if (ioOutputDataPackets == 0)
break;
}

buffer = swfdec_buffer_new_for_data(outputBuffer, outputBufferSize);
swfdec_buffer_queue_push(decoder->queue, buffer);
}


Nick Zitzmann
<http://seiryu.home.comcast.net/>
S/MIME signature available upon request




_______________________________________________ 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
  • Follow-Ups:
    • Re: Examples for AudioFileStream and AudioConverter?
      • From: William Stewart <email@hidden>
References: 
 >Examples for AudioFileStream and AudioConverter? (From: Nick Zitzmann <email@hidden>)
 >Re: Examples for AudioFileStream and AudioConverter? (From: james mccartney <email@hidden>)
 >Re: Examples for AudioFileStream and AudioConverter? (From: William Stewart <email@hidden>)

  • Prev by Date: Retrieving cover art
  • Next by Date: Re: Audio playback at a specific position?
  • Previous by thread: Re: Examples for AudioFileStream and AudioConverter?
  • Next by thread: Re: Examples for AudioFileStream and AudioConverter?
  • Index(es):
    • Date
    • Thread