2012-01-03 34 views
6

我寫了一個循環編碼通過我的應用程序使用的AAC擴展音頻文件服務產生的PCM音頻數據。編碼在後臺線程中同步發生,而不是實時發生。ExtAudioFileWrite到M4A/AAC未能上雙核設備(iPad 2的,iPhone 4S的)

的編碼工作完美無缺的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幀被適當地創建,但ExtAudioFileWrite失敗第二/第三時間它被稱爲。

任何想法?謝謝!

+0

你可以發佈你如何填充緩衝區以及如何調用ExtAudioFileWrite? – sbooth 2012-01-05 02:27:22

+0

經過多次的挫折和蘋果的幫助之後,我的同事發現了這個問題。顯然,在較新的iOS設備(iPad 2和iPhone 4S)上,44.1 kHz不是AAC編碼的有效採樣率,至少使用外部音頻文件服務。 48千赫工作得很好。我已經提交給蘋果作爲一個錯誤,希望他們會照顧它。 – roperklacks 2012-01-12 04:28:55

回答

17

我有,我正在試圖使用擴展音頻文件服務,以流PCM聲音轉換成M4A文件在iPad 2似乎一切所不同的是ExtAudioFileWrite每次調用返回的錯誤代碼工作的一個非常類似的問題 - 66567(kExtAudioFileError_MaxPacketSizeUnknown)。我最終發現的解決方案是將「編解碼器製造商」設置爲軟件而不是硬件。所以,放置

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

將客戶端設置數據格式之前。

這將導致我相信,蘋果的硬件編解碼器只能支持非常特殊的編碼,但軟件編解碼器可以更可靠地做你想做的。就我而言,軟件編解碼器轉換爲m4a的時間比將完全相同的文件寫入LPCM格式的時間長50%。

有誰知道蘋果是否指定了自己的音頻編解碼器的硬件能夠某處?看來,軟件工程師被卡住打在AudioStreamBasicDescription和AudioChannelLayout客戶端和文件到每一個可能的排列直到有工作設定〜20個參數的時間長的猜謎遊戲...

+0

我花了兩天的時間調試爲什麼AAC編碼在iPhone 4S上的多個應用程序中突然停止工作,但不是我的其他iOS設備。這個伎倆。我不知道你是如何計算出來的,但對你很感謝,並希望你在SO上發表更多。 – 2012-05-01 01:47:53

+0

我只是通過擴展音頻文件服務參考挖掘並嘗試設置變量的每個組合,直到工作:P很高興我能夠幫助!現在,如果有人可以解釋爲什麼這些設備的硬件功能如此不一致...... – user1021430 2012-05-02 02:24:24

+0

男人......你的巨大榮譽。我想知道我的代碼中ExtAudioFileWrite崩潰時沒有回溯的情況,究竟發生了什麼如此嚴重的錯誤。謝謝你的幫助。我已經填補了一個錯誤,對此感謝。希望它會與roperklacks的另一個bug報告合併。再次感謝。 – Dan1one 2012-09-18 04:22:41

相關問題