I am trying to extract Linear PCM data from an MP3 file. Prior to iOS 5, I could do this successfully using the AudioToolbox infrastructure, in particular the ExtAudioFileRead function. However, in iOS 5, the ExtAudioFileRead function gives a completely different result than in iOS 4.
Firstly, he cannot read all the packages in the MP3 source file. For example, it reads only 1637 packets, while the original MP3 file contains 2212 packets.
Secondly, the PCM values obtained from the function are completely different from the values obtained in iOS 4.
I can’t understand what I did wrong :( The same structure, the same function and the same code ... but completely different results? I doubt this is an iOS 5 error, so I already reported this Apple problem. But Apple did not respond to my error messages for 2 weeks!
Here is the code that causes the problem. After executing the code, I expect to have the correct PCM data in pcmBuffer. In iOS 4, the code gives the result that I expected. But in iOS 5, the result is completely different and wrong.
Please help me!
OSStatus status;
ExtAudioFileRef fileRef;
CFURLRef fileURL = (CFURLRef)[NSURL fileURLWithPath:filePath];
status = ExtAudioFileOpenURL((CFURLRef)fileURL, &fileRef);
AudioStreamBasicDescription dataFormat;
dataFormat.mSampleRate = SAMPLE_RATE;
dataFormat.mFormatID = kAudioFormatLinearPCM;
dataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
dataFormat.mFramesPerPacket = 1;
dataFormat.mChannelsPerFrame = 1;
dataFormat.mBitsPerChannel = 16;
dataFormat.mBytesPerPacket = 2;
dataFormat.mBytesPerFrame = 2;
UInt32 propDataSize;
AudioStreamBasicDescription originalDataFormat;
propDataSize = (UInt32)sizeof(originalDataFormat);
status = ExtAudioFileGetProperty(fileRef, kExtAudioFileProperty_FileDataFormat, &propDataSize, &originalDataFormat);
SInt64 numPackets;
propDataSize = sizeof(numPackets);
status = ExtAudioFileGetProperty(fileRef, kExtAudioFileProperty_FileLengthFrames, &propDataSize, &numPackets);
propDataSize = (UInt32)sizeof(dataFormat);
status = ExtAudioFileSetProperty(fileRef, kExtAudioFileProperty_ClientDataFormat, propDataSize, &dataFormat);
numPackets = (SInt64)numPackets / (SInt64)(originalDataFormat.mSampleRate / SAMPLE_RATE);
size_t bufferSize = (size_t)(numPackets * sizeof(SInt16));
SInt16 *pcmBuffer = (SInt16 *)malloc(bufferSize);
AudioBufferList bufList;
bufList.mNumberBuffers = 1;
bufList.mBuffers[0].mNumberChannels = 1;
bufList.mBuffers[0].mDataByteSize = bufferSize;
bufList.mBuffers[0].mData = pcmBuffer;
ExtAudioFileSeek(fileRef, 0);
UInt32 totalFramesRead = 0;
do {
UInt32 framesRead = numPackets - totalFramesRead;
bufList.mBuffers[0].mData = pcmBuffer + (totalFramesRead * (sizeof(SInt16)));
ExtAudioFileRead(fileRef, &framesRead, &bufList);
totalFramesRead += framesRead;
if(framesRead == 0) {
break;
}
NSLog(@"read %lu frames\n", framesRead);
} while (totalFramesRead < numPackets);
int totalPackets = totalFramesRead;
status = ExtAudioFileDispose(fileRef);
NSLog(@"numPackets : %lld, totalPackets : %d", numPackets, totalPackets);