ExtAudioFileWrite m4a / aac在双核设备(ipad 2,iphone 4s)上失败

我写了一个循环来编码由我的应用程序生成的PCMaudio数据使用扩展audio文件服务的AAC。 编码发生在后台线程同步,而不是实时。

这个编码在ipad 1和iphone 3gs / 4上完全适用于ios 4和5.但是,对于双核设备(iphone 4s,ipad 2),第三次调用ExtAudioFileWrite会导致编码线程崩溃,没有堆栈跟踪,也没有错误代码。

这是有问题的代码:

数据格式

AudioStreamBasicDescription AUCanonicalASBD(Float64 sampleRate, UInt32 channel){ AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = sampleRate; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; audioFormat.mChannelsPerFrame = channel; audioFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); audioFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); audioFormat.mFramesPerPacket = 1; audioFormat.mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); audioFormat.mReserved = 0; return audioFormat; } AudioStreamBasicDescription MixdownAAC(void){ AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 44100.0; audioFormat.mFormatID = kAudioFormatMPEG4AAC; audioFormat.mFormatFlags = kMPEG4Object_AAC_Main; audioFormat.mChannelsPerFrame = 2; audioFormat.mBytesPerPacket = 0; audioFormat.mBytesPerFrame = 0; audioFormat.mFramesPerPacket = 1024; audioFormat.mBitsPerChannel = 0; audioFormat.mReserved = 0; return audioFormat; } 

渲染循环

 OSStatus err; ExtAudioFileRef outFile; NSURL *mixdownURL = [NSURL fileURLWithPath:filePath isDirectory:NO]; // internal data format AudioStreamBasicDescription localFormat = AUCanonicalASBD(44100.0, 2); // output file format AudioStreamBasicDescription mixdownFormat = MixdownAAC(); err = ExtAudioFileCreateWithURL((CFURLRef)mixdownURL, kAudioFileM4AType, &mixdownFormat, NULL, kAudioFileFlags_EraseFile, &outFile); err = ExtAudioFileSetProperty(outFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &localFormat); // prep AllRenderData *allData = &allRenderData; writeBuffer = malloc(sizeof(AudioBufferList) + (2*sizeof(AudioBuffer))); writeBuffer->mNumberBuffers = 2; writeBuffer->mBuffers[0].mNumberChannels = 1; writeBuffer->mBuffers[0].mDataByteSize = bufferBytes; writeBuffer->mBuffers[0].mData = malloc(bufferBytes); writeBuffer->mBuffers[1].mNumberChannels = 1; writeBuffer->mBuffers[1].mDataByteSize = bufferBytes; writeBuffer->mBuffers[1].mData = malloc(bufferBytes); memset(writeBuffer->mBuffers[0].mData, 0, bufferBytes); memset(writeBuffer->mBuffers[1].mData, 0, bufferBytes); UInt32 framesToGet; UInt32 frameCount = allData->gLoopStartFrame; UInt32 startFrame = allData->gLoopStartFrame; UInt32 lastFrame = allData->gLoopEndFrame; // write one silent buffer ExtAudioFileWrite(outFile, bufferFrames, writeBuffer); while (frameCount < lastFrame){ // how many frames do we need to get if (lastFrame - frameCount > bufferFrames) framesToGet = bufferFrames; else framesToGet = lastFrame - frameCount; // get dem frames err = theBigOlCallback((void*)&allRenderData, NULL, NULL, 1, framesToGet, writeBuffer); // write to output file ExtAudioFileWrite(outFile, framesToGet, writeBuffer); frameCount += framesToGet; } // write one trailing silent buffer memset(writeBuffer->mBuffers[0].mData, 0, bufferBytes); memset(writeBuffer->mBuffers[1].mData, 0, bufferBytes); processLimiterInPlace8p24(limiter, writeBuffer->mBuffers[0].mData, writeBuffer->mBuffers[1].mData, bufferFrames); ExtAudioFileWrite(outFile, bufferFrames, writeBuffer); err = ExtAudioFileDispose(outFile); 

pcm框架已正确创build,但ExtAudioFileWrite在第二次/第三次调用时失败。

有任何想法吗? 谢谢!

我有一个非常类似的问题,我试图使用扩展audio文件服务,以streamPCM声音到iPad 2上的m4a文件。除了每次调用ExtAudioFileWrite返回错误代码-66567(kExtAudioFileError_MaxPacketSizeUnknown) 。 我最终发现的解决scheme是将“编解码器制造商”设置为软件而不是硬件。 所以放置

 UInt32 codecManf = kAppleSoftwareAudioCodecManufacturer; ExtAudioFileSetProperty(FileToWrite, kExtAudioFileProperty_CodecManufacturer, sizeof(UInt32), &codecManf); 

就在您设置客户端数据格式之前。

这将使我相信,苹果的硬件编解码器只能支持非常特定的编码,但软件编解码器可以更可靠地做你想做的。 就我而言,m4a的软件编解码器转换比LPCM格式文件完全相同的文件长50%。

有谁知道苹果是否指定了什么地方他们的audio编解码器硬件能够? 看起来,软件工程师被困在播放在AudioStreamBasicDescription和AudioChannelLayout为客户端设置〜20参数的长达数小时的猜谜游戏和文件的每一个可能的排列,直到有些作品…