Hi all -
I'm having no luck converting a VBR MP3 network stream into an uncompresed format file. Been banging my head on it for a few days.
The mp3 stream could be either 1 or 2 channels. Currently I'm having trouble getting just 1 channel to work.
I think where I'm going wrong is in determining the number of frames to send to ExtAudioFileWrite.
I'm trying to write to the file inside the Audio File Stream service callback:
static void SR_MyAFSPacketsProc ( void *inClientData,
UInt32 inNumberBytes, UInt32 inNumberPackets,
const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions ) {
}
Because the input file stream is a VBR MP3, inPacketDescriptions[0].mVariableFramesInPacket is always 0. And the mp3StreamASBD's mFramesPerPacket makes no sense. Also mBytesPerFrame is 0 (I understand this is to be expected for the compressed mp3 format)
For my stream's ASBD mFramesPerPacket is 576 and a callback to the AudioFileStream service packet callback may offer 12235 bytes in 233 packets. If I use the stream's mFramesPerPacket of 576 * 233 packets, I get 134208 frames. 134208 frames for 12235 bytes seems a bit off.
Anyone out there have a suggestion how to determine the number of frames to pass to ExtAudioFileWrite?
I think I'm doing everything else correctly:
This is the ASBD I am using for the output file:
dstFormat.mSampleRate = sampleRate;
dstFormat.mChannelsPerFrame = channelCount;
dstFormat.mFormatID = kAudioFormatLinearPCM;
dstFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
dstFormat.mBitsPerChannel = 16;
dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mFramesPerPacket = 1;
In the AudioFileStream Property listener callback for kAudioFileStreamProperty_ReadyToProducePackets, I use the output file ASBD to both create the file (ExtAudioFileCreateWithURL) and to set the clientDataFormat on that file (ExtAudioFileSetProperty with kExtAudioFileProperty_ClientDataFormat).
NSURL *url = "" fileURLWithPath:@"/testout/lpcmout.caf"];
CFURLRef sourceURL = (__bridge CFURLRef) url;
SR_CheckError(ExtAudioFileCreateWithURL(sourceURL, kAudioFileCAFType, &sr_fileDesc, NULL, kAudioFileFlags_EraseFile, &sr_audioFile), "create output file failed");
SR_CheckError(ExtAudioFileSetProperty(sr_audioFile, kExtAudioFileProperty_ClientDataFormat,
sizeof (AudioStreamBasicDescription), &sr_fileDesc), "Couldn't set client data format on input ext file");
Thank you-
Matt