Extended Audio File Services可以看做是对Audio File Services的封装,当时更多的实际开发我们用它来做音频文件类型的转换。ExtAudioFile具有几下特点:
- 1、ExtAudioFile 是AudioUnit的一个组件,它提供了将原始音频数据编码为WAV,caff等编码格式的音频数据,同时提供写入文件的接口
- 2、同时它还提供了从文件中读取数据解码为PCM音频数据的功能
- 3、编码和解码支持硬编解码和软编解码
- 4、不能操作PCM裸数据
- 5、对应的数据结构对象为 ExtAudioFileRef
- 6、该对象具有编码和封装两大功能
打开和关闭音频数据
打开文件:
OSStatus ExtAudioFileOpenURL ( CFURLRef inURL, ExtAudioFileRef _Nullable *outExtAudioFile );
复制代码
当操作完以后,通过Dispose来回收资源,区分于其他的Close:
OSStatus ExtAudioFileDispose ( ExtAudioFileRef inExtAudioFile );
复制代码
读取音频数据
和“Audio ToolBox”的其他属性操作一样,Ext接口提供的属性操作也是分为两步,先获取属性基本信息,如大小:
OSStatus ExtAudioFileGetPropertyInfo ( ExtAudioFileRef inExtAudioFile, ExtAudioFilePropertyID inPropertyID, UInt32 *outSize, Boolean *outWritable );
复制代码
然后在获得属性内容:
OSStatus ExtAudioFileGetProperty ( ExtAudioFileRef inExtAudioFile, ExtAudioFilePropertyID inPropertyID, UInt32 *ioPropertyDataSize, void *outPropertyData );
复制代码
或者设置属性内容:
OSStatus ExtAudioFileSetProperty ( ExtAudioFileRef inExtAudioFile, ExtAudioFilePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData );
复制代码
_outputFormat.mSampleRate = 44100;
_outputFormat.mBitsPerChannel = 16;
_outputFormat.mChannelsPerFrame = 2;
_outputFormat.mFormatID = kAudioFormatMPEGLayer3;
UInt32 descSize = sizeof(AudioStreamBasicDescription);
ExtAudioFileGetProperty(_audioFileRef, kExtAudioFileProperty_FileDataFormat, &descSize, &_inputFormat);
_inputFormat.mSampleRate = _outputFormat.mSampleRate;
_inputFormat.mChannelsPerFrame = _outputFormat.mChannelsPerFrame;
_inputFormat.mBytesPerFrame = _inputFormat.mChannelsPerFrame* _inputFormat.mBytesPerFrame;
_inputFormat.mBytesPerPacket = _inputFormat.mFramesPerPacket*_inputFormat.mBytesPerFrame;
ExtAudioFileSetProperty(_audioFileRef,
kExtAudioFileProperty_ClientDataFormat,
sizeof(AudioStreamBasicDescription),
&_inputFormat),
复制代码
kExtAudioFileProperty_Xxxx : 源文件的相关属性,也就是原来什么格式的数据(MP3/AAC),他的基本属性。
kExtAudioFileProperty_ClientXxx: 读出时的数据格式,Ext在读出时会自动帮我们做编解码操作,这个是处理后的结果
所以在读取之前,一定要记得设置“kExtAudioFileProperty_ClientDataFormat”属性,设置其输出的数据格式,
struct AudioBufferList
{
UInt32 mNumberBuffers;
AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements
#if defined(__cplusplus) && CA_STRICT
public:
AudioBufferList() {}
private:
// Copying and assigning a variable length struct is problematic so turn their use into a
// compile time error for eacy spotting.
AudioBufferList(const AudioBufferList&);
AudioBufferList& operator=(const AudioBufferList&);
#endif
};
typedef struct AudioBufferList AudioBufferList;
struct AudioBuffer
{
UInt32 mNumberChannels;
UInt32 mDataByteSize;
void* __nullable mData;
};
typedef struct AudioBuffer AudioBuffer;
复制代码
写入文件内容
写入和读取类似,只是要预先填好BufferList的内容:
OSStatus ExtAudioFileWrite ( ExtAudioFileRef inExtAudioFile, UInt32 inNumberFrames, const AudioBufferList *ioData );
复制代码
同时写入还有个非阻塞的版本,当调用“ ExtAudioFileDispose ”会最终保证所有数据都写入到磁盘中。
OSStatus ExtAudioFileWriteAsync ( ExtAudioFileRef inExtAudioFile, UInt32 inNumberFrames, const AudioBufferList *ioData );
复制代码