AudioToolBox中ExtAudioFile的使用

CoreAudio中和讀寫音頻文件有關(guān)的有ExtAudioFileAudioFile,這里介紹ExtAudioFile讀寫音頻文件的相關(guān)API和操作。

基礎(chǔ)知識介紹

音頻數(shù)據(jù)格式

pcm、aacopus等,代表音頻的原始數(shù)據(jù),是音頻的數(shù)字信號。

文件格式

aif、caf、mp3等,文件存儲可以壓縮數(shù)據(jù)進行存儲如mp3,其中caf是指Core Audio Format,里面可以存儲所CoreAudio支持的數(shù)據(jù)格式。

讀文件

讀文件分為3步:

  1. 打開文件
  2. 讀取數(shù)據(jù)
  3. 關(guān)閉文件

打開文件

ExtAudioFile可以直接設(shè)置音頻數(shù)據(jù)格式(ClientDataFormat),如果有不同的采樣率、數(shù)據(jù)類型等,它會自動幫我們完成格式轉(zhuǎn)換的過程。

- (void)openFile:(NSString *)filePath format:(AudioStreamBasicDescription *)format {
    CFURLRef cfurl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)filePath, kCFURLPOSIXPathStyle, false);

    _dataFormat = format;

    // 打開文件
    OSStatus result = ExtAudioFileOpenURL(cfurl, &_fileId);
    printf("ExtAudioFileOpenURL result %d \n", result);

    // 讀取文件格式
    UInt32 propSize = sizeof(AudioStreamBasicDescription);
    result = ExtAudioFileGetProperty(_fileId, kExtAudioFileProperty_FileDataFormat, &propSize, &_fileFormat);
    printf("get absd: %d \n", result);

    // 設(shè)置音頻數(shù)據(jù)格式
    propSize = sizeof(AudioStreamBasicDescription);
    result = ExtAudioFileSetProperty(_fileId, kExtAudioFileProperty_ClientDataFormat, propSize, _dataFormat);
    printf("set absd: %d \n", result);
}

讀取數(shù)據(jù)

將數(shù)據(jù)讀到AudioBufferList里面,inNumberFrames表示音頻幀數(shù)。

- (void)readData:(void *)data length:(int)length {
    AudioBufferList ioData = {};
    AudioBuffer buffer = {};
    buffer.mData = data;
    buffer.mDataByteSize = length;
    buffer.mNumberChannels = _dataFormat->mChannelsPerFrame;

    ioData.mBuffers[0] = buffer;
    ioData.mNumberBuffers = 1;

    UInt32 inNumberFrames = length / _dataFormat->mBytesPerFrame;

    OSStatus result = ExtAudioFileRead(_fileId, &inNumberFrames, &ioData);
    printf("ExtAudioFileRead %d \n", result);
}

關(guān)閉文件

使用完需要關(guān)閉文件,這是一個好習(xí)慣。

- (void)closeFile {
    ExtAudioFileDispose(_fileId);
}

寫文件

寫文件也有3步:

  1. 創(chuàng)建文件
  2. 寫入數(shù)據(jù)
  3. 關(guān)閉文件

創(chuàng)建文件

需要按文件的類型創(chuàng)建文件。

- (void)createFile:(NSString *)filePath type:(AudioFileTypeID)type format:(AudioStreamBasicDescription *)format {
    CFURLRef cfurl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)filePath, kCFURLPOSIXPathStyle, false);

    _dataFormat = format;

    // 創(chuàng)建文件
    OSStatus result = ExtAudioFileCreateWithURL(cfurl, type, format, NULL, kAudioFileFlags_EraseFile, &_fileId);
    printf("ExtAudioFileCreateWithURL result %d \n", result);

    // 設(shè)置音頻數(shù)據(jù)格式
    UInt32 propSize = sizeof(AudioStreamBasicDescription);
    result = ExtAudioFileSetProperty(_fileId, kExtAudioFileProperty_ClientDataFormat, propSize, _dataFormat);
    printf("set absd: %d \n", result);
}

寫入數(shù)據(jù)

寫入有兩個函數(shù)ExtAudioFileWriteAsyncExtAudioFileWrite,看名字就知道了,一個是非阻塞的,一個是阻塞的,非阻塞的在關(guān)閉文件的時候會寫完數(shù)據(jù)。

- (void)writeData:(void *)data length:(int)length {
    AudioBufferList ioData = {};
    AudioBuffer buffer = {};
    buffer.mData = data;
    buffer.mDataByteSize = length;
    buffer.mNumberChannels = _dataFormat->mChannelsPerFrame;

    ioData.mBuffers[0] = buffer;
    ioData.mNumberBuffers = 1;

    UInt32 inNumberFrames = length / _dataFormat->mBytesPerFrame;

    OSStatus result = ExtAudioFileWriteAsync(_fileId, inNumberFrames, &ioData);
    printf("ExtAudioFileWriteAsync %d \n", result);
}

關(guān)閉文件

- (void)closeFile {
    ExtAudioFileDispose(_fileId);
}

倉庫地址:https://github.com/zhonglaoban/AudioFile

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容