1

所以,我需要反转一些音频 *.caf 文件,

我已经看到这样做的方法应该是:

您不能只反转字节数据。我使用 CoreAudio 和 AudioUnits 也达到了同样的效果。使用 ExtFileReader C API 将文件读入 lPCM 缓冲区,然后您可以根据需要反转缓冲区。

但我找不到任何使用的文档

ExtFileReader C API

因此,如果我有一个 *.caf 文件,如何将其读入线性 PCM,我已经检查了Core Audio 概述,但找不到如何完成此操作?

那么,我怎样才能将我的 caf 文件读入线性 PCM?

谢谢!

4

1 回答 1

2

ExtendedAudioFile 在 AudioToolbox 框架中。将文件读入您​​想要的任何格式都非常简单。这是读入 32 位浮点非交错线性 PCM 的快速(编译但未经测试)示例:

    #import <AudioToolbox/AudioToolbox.h>

...

    ExtAudioFileRef audioFile = NULL;
    CFURLRef url = NULL;
    OSStatus err = ExtAudioFileOpenURL(url, &audioFile);

    AudioStreamBasicDescription asbd;
    UInt32 dataSize = sizeof(asbd);
    // get the audio file's format
    err = ExtAudioFileGetProperty(audioFile, kExtAudioFileProperty_FileDataFormat, &dataSize, &asbd);

    // now set the client format to what we want on read (LPCM, 32-bit floating point)
    AudioStreamBasicDescription clientFormat = asbd;
    clientFormat.mFormatID = kAudioFormatLinearPCM;
    clientFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked;
    clientFormat.mBitsPerChannel = 32;
    clientFormat.mBytesPerPacket = 4;
    clientFormat.mFramesPerPacket = 1;
    clientFormat.mBytesPerFrame = 4;

    err = ExtAudioFileSetProperty(audioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(clientFormat), &clientFormat);

    // okay, now the ext audio file is set up to convert samples to LPCM on read
    // get the total number of samples
    SInt64 numFrames = 0;
    dataSize = sizeof(numFrames);
    err = ExtAudioFileGetProperty(audioFile, kExtAudioFileProperty_FileLengthFrames, &dataSize, &numFrames);

    // prepare an audio buffer list to hold the data when we read it from the file

    UInt32 maxReadFrames = 4096; // how many samples will we read in at a time?
    AudioBufferList *bufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (asbd.mChannelsPerFrame - 1));
    bufferList->mNumberBuffers = asbd.mChannelsPerFrame;
    for (int ii = 0; ii < bufferList->mNumberBuffers; ++ii) {
        bufferList->mBuffers[ii].mDataByteSize = maxReadFrames * sizeof(float);
        bufferList->mBuffers[ii].mData = malloc(bufferList->mBuffers[ii].mDataByteSize);
        bzero(bufferList->mBuffers[ii].mData, bufferList->mBuffers[ii].mDataByteSize);
        bufferList->mBuffers[ii].mNumberChannels = 1;
    }

    while(numFrames > 0) {
        UInt32 framesToRead = (maxReadFrames > numFrames) ? numFrames : maxReadFrames;
        err = ExtAudioFileRead(audioFile, &framesToRead, bufferList);
        // okay, your LPCM audio data is in `bufferList` -- do whatever processing you'd like!
    }

    // clean up
    for (int ii = 0; ii < bufferList->mNumberBuffers; ++ii) {
        free(bufferList->mBuffers[ii].mData);
    }
    free(bufferList);
    ExtAudioFileDispose(audioFile);
于 2013-01-03T22:16:19.493 回答