使用 AudioToolBox 将 Wave 文件保存到 NSFileWrapper
Posted
技术标签:
【中文标题】使用 AudioToolBox 将 Wave 文件保存到 NSFileWrapper【英文标题】:Using AudioToolBox to save Wave file to NSFileWrapper 【发布时间】:2012-10-31 16:23:22 【问题描述】:我已使用 AudioToolBox 框架中的 ExtAudioFileCreateWithURL 和 ExtAudioFileWrite 将我的样本保存到文件中。但是现在我需要将它保存到 NSFileWrapper,因为我现在使用的是 NSDocument:
- (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);
【问题讨论】:
【参考方案1】:在大多数情况下,使用外部文件是最佳解决方案。请注意,NSData
具有未缓存和映射文件的初始化程序。在大多数情况下,您显然希望最小化 I/O,同时又不消耗大量内存(并且您必须密切关注缓存内存的增长)。更进一步,考虑如何为这些重量级资产(子 NSFileWrappers、链接)以另一种方式表示文件包装器对象,因为文档的文件可能不是非常小的文件(例如单循环)。
如果内存不是问题(例如,您只处理小样本和有限的文件和文档),那么您可以使用 AudioFileInitializeWithCallbacks
,它适用于 Wave(但不是所有格式) .这允许您在内存中处理自己的缓冲区,用于表示内存中整个文件的连续分配。然后创建NSData
表示很容易——只需监控您的内存使用情况并确保独占读/写访问。请注意,NSData
不需要创建深层副本——并将其纳入您的设计中。在 OS X 上使用此选项显然会更加灵活。在这种情况下,请确保您知道自己实际写了多少。一个好的基于磁盘的解决方案(上图)很可能可以为您节省大量写入磁盘的时间。
无论如何,这比大多数基于 NSFileWrapper
的实现需要更多的思考,因为每个文档的音频文件资产可能很快就会超过 100 MB。
【讨论】:
谢谢贾斯汀。由于音频文件很少更改,我已经使用子 NSFileWrappers 来最小化写入。如果 fileWrapperOfType 已经找到一个有效的 NSFileWrapper ,它会跳过它。我的最终解决方案是使用 ExtAudioFileCreateWithURL 保存到用户与之交互的外部文件,但滚动我自己的 saveWAVFileToMemory 例程以在我的 NSFileWrapper 中存储音频时使用。这在导出期间为用户提供了更多文件格式选择,但允许我使用 NSFileWrappers 进行内部保存。 @DaveStephenson 对实际实现的解释表示赞赏——干杯。不客气。以上是关于使用 AudioToolBox 将 Wave 文件保存到 NSFileWrapper的主要内容,如果未能解决你的问题,请参考以下文章
Xcode - AudioToolbox/AudioToolbox.h 文件未找到