سؤال

So ,I need to reverse some audio *.caf file,

I have seen that the way to do it should be:

You cannot just reverse the byte data. I have achieved the same effect using CoreAudio and AudioUnits. Use ExtFileReader C API to read the file into lPCM buffers and then you can reverse the buffers as needed.

But I cannot find any documentation of the use of

ExtFileReader C API

So if I have a *.caf file, how can I read it in to a linear PCM, I have checked the Core Audio overview but cant find how to accomplish this?

How can i then, read my caf file to linear PCM?

thanks!

هل كانت مفيدة؟

المحلول

ExtendedAudioFile is in the AudioToolbox framework. It's pretty straightforward to read in a file to whatever format you'd like. Here's a quick (compiles, but not tested) example of reading in to 32-bit float non-interleaved Linear 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top