2012-10-31 69 views
3

我用ExtAudioFileCreateWithURL和ExtAudioFileWrite從AudioToolBox框架,以我的樣品保存到一個文件。但現在我需要把它保存到NSFileWrapper因爲我現在用NSDocument:使用AudioToolBox到波形文件保存到NSFileWrapper

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError 

有沒有辦法使用ExtAudioFileXXX功能與NSMutableData對象,以便我可以使用NSFileWrapper initRegularFileWithContents:(NSData*)contents方法?

剝離下來的代碼保存到文件(工作):

AudioStreamBasicDescription file_desc; 
FillOutASBDForLPCM(file_desc, _sample_rate, _channel_count, 32, 32, true, false); 
OSStatus rv = ExtAudioFileCreateWithURL(url, kAudioFileWAVEType, &file_desc, NULL, kAudioFileFlags_EraseFile, &fout); 
if (rv == noErr){ 
    int buff_size = sizeof(AudioBufferList) + sizeof(AudioBuffer); 
    AudioBufferList* bufferList = (AudioBufferList*)malloc(buff_size); 
    bufferList->mNumberBuffers = 1; 
    bufferList->mBuffers[0].mData = _samples; 
    bufferList->mBuffers[0].mNumberChannels = _channel_count; 
    bufferList->mBuffers[0].mDataByteSize = _channel_count * _frame_count * sizeof(float); 
    ExtAudioFileWrite(fout, _frame_count, bufferList); 
    free(bufferList); 
    ExtAudioFileDispose(fout); 
} 

回答

0

使用外部文件是在大多數情況下的最佳解決方案。請注意,NSData具有未緩存和映射文件的初始值設定項。您顯然會希望在大多數情況下儘量減少I/O,同時不會消耗大量內存(並且需要關注緩存內存的增長)。一步,考慮如何可以代表你的文件包裝對象,這些沉重的資產(子NSFileWrappers,鏈接),另一種方式,因爲一個文檔的文件很可能不是一個平凡的小文件(如單週期)。

如果內存不是問題(例如,您只處理小樣本和有限文件和文檔),那麼您可以使用AudioFileInitializeWithCallbacks,它可以與Wave(但不是所有格式)一起使用。這允許你在內存中處理你自己的緩衝區,用於連續分配內存中的整個文件。然後創建NSData表示法很簡單 - 只需監視您的內存使用情況並確保獨佔的讀取/寫入訪問。請注意,NSData不需要創建深層副本 - 並將其納入您的設計中。在OS X上使用這個選項顯然會有更多的靈活性。在這種情況下,確保你知道你實際寫了多少。很可能,一個好的基於磁盤的解決方案(上面)可以爲您節省大量的寫入磁盤的工作。

不管怎麼說,這將需要比大多數NSFileWrapper基於實現更多的思考,因爲你可能會超過每文檔的音頻文件100資產MB相當迅速。

+1

感謝賈斯汀。由於音頻文件很少發生變化,我已經使用子NSFileWrappers來最小化寫入。如果fileWrapperOfType已經找到一個有效的NSFileWrapper,它會跳過它。我最終的解決辦法是使用ExtAudioFileCreateWithURL保存到用戶與之交互的外部文件,但推出自己的saveWAVFileToMemory程序存儲在我的NSFileWrapper音頻時使用。這爲用戶在導出期間提供了更多的文件格式選擇,但允許我使用NSFileWrappers進行內部保存。 –

+0

@DaveStephenson實際執行解釋讚賞 - 歡呼聲。別客氣。 – justin