【问题标题】:EZAudio : how to store an AudioBufferList struct to an NSMutableArray for later use?EZAudio:如何将 AudioBufferList 结构存储到 NSMutableArray 以供以后使用?
【发布时间】:2015-03-15 18:30:18
【问题描述】:

我正在使用 EZAudio 库在 Objective-C 中创建一个 iPhone 应用程序。

我使用 EZMicrophone 类和 EZRecorder 类将音频保存到磁盘。 但是我希望延迟录制和保存,因此我必须将在 EZMicrophone 使用的委托方法中接收到的 AudioBufferList 结构传递给 NSMutableArray。

我在将委托方法中收到的 AudioBufferList 结构传递给 NSMutableArray 以供以后使用时遇到问题。

我将 AudioBufferList 结构封装在一个 NSValue 中。

来源

这是委托方法:

- (void)microphone:(EZMicrophone *)microphone
     hasBufferList:(AudioBufferList *)bufferList
    withBufferSize:(UInt32)bufferSize
withNumberOfChannels:(UInt32)numberOfChannels {

    NSValue *audioData = [NSValue valueWithBytes:bufferList objCType:@encode(AudioBufferList)];

    [self.listOfBufferList addObject:audioData];

}

这里是接收AudioBufferList的NSMutableArray的方法

- (void)createAudioFile {

    for(int i = 0;i<self.listOfBufferList.count;i++) {

        AudioBufferList bufferList;
        [self.listOfBufferList[i] getBytes:&bufferList length:BufferSize];
        [self.recorder appendDataFromBufferList:&bufferList
                                 withBufferSize:BufferSize];
    }

[self.recorder closeAudioFile];

}

我得到了错误:

错误:当我使用我的应用播放文件时,无法从音频文件 (-66567) 中读取音频数据

但是当:

[self.recorder appendDataFromBufferList:&bufferList
                                     withBufferSize:BufferSize];

在委托方法中是正确的,音频文件读取没有任何问题,所以我的问题是,我如何将 AudioBufferList 结构封装到一个不会在过程中丢失的对象中,因为我知道为了我的应用程序,我需要这两种不同的方法。

此外,当我调试应用程序时,在 createAudioFile 方法中,我可以看到结构变量已正确复制,但缓冲区 (void*) 与委托方法中的缓冲区不同。 (内容和地址不同)

这是我试图通过方法传递的核心音频类型 AudioBufferList 和 AudioBuffer。

struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements

};
typedef struct AudioBufferList  AudioBufferList;

struct AudioBuffer
{
    UInt32  mNumberChannels;
    UInt32  mDataByteSize;
    void*   mData;
};
typedef struct AudioBuffer  AudioBuffer;

非常感谢您的帮助,我当然可以了解更多详情。

【问题讨论】:

    标签: ios objective-c ezaudio


    【解决方案1】:

    您应该将 AudioBufferLists 保存在 c 数组中。你可以例如创建一个包含 AudioBufferLists 数量的结构和包含缓冲区列表的数组。 如果您知道要使用的缓冲区列表的最大数量,则可以定义具有该大小的数组并将添加到数组中的实际数字存储在 number 成员中。

    struct MyBufferLists
    {
        UInt32      mNumberBufferLists;
        AudioBufferList mBufferLists[9]; // enter your max number instead of 9
    };
    

    将此结构添加到您需要它的类中。

    【讨论】:

    • 我实际上不知道我要使用的 AudioBufferList 编号,因为该应用程序将全时录制。
    • EZAudio 是否提供某种可以使用的 RingBuffer?
    • 您多久调用一次 createAudioFile?您只想在录制结束时调用它吗?
    • 是的,我只在用户告诉应用停止录制时才调用它。然后开始新的录制
    • 然后将整个音频数据保存在内存中。这可能会带来问题,如果录制时间很长,您将用完空间。我建议如下:直接在麦克风回调中将音频数据保存到 tmp 文件中。然后在用户完成后将该文件移动到正确的位置,或者如果用户取消则删除该文件。即使将音频数据存储在 tmp 文件中,也要检查可用空间并在用户空间不足时警告用户。
    猜你喜欢
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2011-05-06
    • 2011-04-13
    • 2016-06-26
    • 2012-02-29
    相关资源
    最近更新 更多