【问题标题】:iOS audio manipulation - play local .caf file backwardsiOS 音频操作 - 向后播放本地 .caf 文件
【发布时间】:2011-07-15 13:51:15
【问题描述】:

我想加载本地 .caf 音频文件并反转音频(向后播放)。我已经收集到我基本上需要从 this 之类的帖子中翻转一组缓冲区数据

但是,我不确定如何从给定的音频文件中访问此缓冲区数据。我有一点用 AVaudioPlayer 和 ObjectAL(一个 obj-c openAL 库)播放声音的经验,但我不知道如何访问像这个缓冲区数据数组这样的较低级别的东西。

我能否举个例子说明我将如何访问该数组?

【问题讨论】:

标签: ios iphone core-audio


【解决方案1】:

您的问题归结为here 描述的相同问题,该问题由P-i 在您的问题下方的评论中链接。 Kiran 回答了这个问题,并在这里为您重新发布了他的答案。 Kiran 的回答是准确的,但您可能需要更多详细信息才能决定如何继续,因为您从 CAF 文件开始。

最简单的音频文件格式,线性脉冲编码调制 (LPCM),是最容易逐字节或逐样本读取的。这意味着它是最容易逆转的。 Kiran 的解决方案就是这样做的。

但是,CAF 格式是一种容器/包装器格式。虽然您的 CAF 文件可能包含 WAV 文件,但它也可能包含无法以相同方式操作的压缩文件格式。

您应该考虑首先将 CAF 文件转换为 WAV,然后将其反转,如其他解决方案所示。有各种库可以为您进行这种转换,但一个好的起点可能是AudioToolbox framework,其中包括Audio Converter Services。或者,如果您可以从一开始就使用 WAV 文件格式,则可以避免转换为 WAV 的需要。

如果您发现 Kiran 的示例代码给您一个错误,您可能需要了解更多信息(Core Audio 很挑剔)。一个很好的起点是Core Audio 'Bible', "Learning Core Audio",由Chris Adamson 和Kevin Avila 编写。那本书使用出色的样本建立了您对数字声音的了解。您还应该查看 Michael Tyson 所写的任何内容,他在 github 上启动了 Amazing Audio Engine 项目,并编写了 AudioBus。

【讨论】:

    【解决方案2】:

    我开发了一个示例应用程序,它记录用户所说的内容并向后播放。我已经使用 CoreAudio 来实现这一点。链接到应用代码。

    因为每个样本的大小为 16 位(2 字节)(单声道)。您可以通过从记录结束开始并向后读取将其复制到不同的缓冲区来一次加载每个样本。当您到达数据的开头时,您已经反转了数据并且播放将被反转。

    // set up output file
    AudioFileID outputAudioFile;
    
    AudioStreamBasicDescription myPCMFormat;
    myPCMFormat.mSampleRate = 16000.00;
    myPCMFormat.mFormatID = kAudioFormatLinearPCM ;
    myPCMFormat.mFormatFlags =  kAudioFormatFlagsCanonical; 
    myPCMFormat.mChannelsPerFrame = 1;
    myPCMFormat.mFramesPerPacket = 1;
    myPCMFormat.mBitsPerChannel = 16;
    myPCMFormat.mBytesPerPacket = 2;
    myPCMFormat.mBytesPerFrame = 2;
    
    
    AudioFileCreateWithURL((__bridge CFURLRef)self.flippedAudioUrl,
                       kAudioFileCAFType,
                       &myPCMFormat,
                       kAudioFileFlags_EraseFile,
                       &outputAudioFile);
    // set up input file
    AudioFileID inputAudioFile;
    OSStatus theErr = noErr;
    UInt64 fileDataSize = 0;
    
    AudioStreamBasicDescription theFileFormat;
    UInt32 thePropertySize = sizeof(theFileFormat);
    
    theErr = AudioFileOpenURL((__bridge CFURLRef)self.recordedAudioUrl,kAudioFileReadPermission, 0, &inputAudioFile);
    
    thePropertySize = sizeof(fileDataSize);
    theErr = AudioFileGetProperty(inputAudioFile, kAudioFilePropertyAudioDataByteCount, &thePropertySize, &fileDataSize);
    
    UInt32 dataSize = fileDataSize;
    void* theData = malloc(dataSize);
    
    //Read data into buffer
    UInt32 readPoint  = dataSize;
    UInt32 writePoint = 0;
    while( readPoint > 0 )
    {
       UInt32 bytesToRead = 2;
    
    AudioFileReadBytes( inputAudioFile, false, readPoint, &bytesToRead, theData );
    AudioFileWriteBytes( outputAudioFile, false, writePoint, &bytesToRead, theData );
    
    writePoint += 2;
    readPoint -= 2;
    }
    
    free(theData);
    AudioFileClose(inputAudioFile);
    AudioFileClose(outputAudioFile);
    

    【讨论】:

    • 录音后音频不反转,无法播放音频文件
    【解决方案3】:

    我认为这个示例代码可以帮助你。

    Mixer Host Sample Code

    它将从包中加载两个 caf 文件并播放。它包含一个函数调用 readAudioFilesIntoMemory,如您所说,它将一个 caf 文件加载到数据数组中。

    整个程序是core audio的一个例子,希望对你有帮助:)

    【讨论】:

    • 使用 MixerHost 代码的唯一问题是函数 readAudioFilesIntoMemory 会将完整的音频文件读入手机内存。对于大型音频文件,这可能是不可能的。您可以使用循环缓冲区将文件的部分内容仅读取到内存中。我分享了一个简单的例子here
    【解决方案4】:

    为什么不让 CoreAudio 的 AudioConverter 为您做呢?请参阅这篇关于 "Getting PCM from MP3/AAC/ALAC File" 和 Apple 的 Core Audio Essentials 的帖子

    【讨论】:

      【解决方案5】:

      您可以使用 libsox for iphone 框架轻松应用音频效果。

      它包含一个示例项目,展示了如何做到这一点。

      libsox ios

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多