【发布时间】:2011-11-10 10:26:42
【问题描述】:
我正在尝试从 MP3 文件中提取线性 PCM 数据。 在 iOS 5 之前,我可以使用 AudioToolbox 框架,特别是 ExtAudioFileRead 函数成功地做到这一点。 但是,在 iOS 5 中,ExtAudioFileRead 函数给出的结果与在 iOS 4 中完全不同。
首先,它无法读取源 MP3 文件中的所有数据包。 例如,它只读取了 1637 个数据包,而源 MP3 文件总共有 2212 个数据包。
第二,从函数中得到的PCM值与iOS 4中得到的完全不同。
我不知道我做错了什么:( 同样的框架,同样的功能,同样的代码……却完全不同的结果? 我怀疑这是 iOS 5 的错误,所以我已经向 Apple 报告了这个问题。 但是 Apple 已经 2 周没有回复我的错误报告了!
这是导致问题的代码。 执行代码后,我希望 pcmBuffer 中有正确的 PCM 数据。 在 iOS 4 中,代码给出了我期望的结果。 但是在 iOS 5 中,结果就完全不同了,而且是错误的。
请有人帮帮我!
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);
【问题讨论】:
-
我也遇到了同样的问题,你找到解决办法了吗?
-
这段代码在 iOs 6.1 上运行良好,当时我进行了修改以允许立体声输入。也就是说,我更改了双通道、16 位音频的通道数和每个数据包的字节数。
标签: objective-c ios