AudioQueueStop后,音频队列无法再次启动

时间:2013-09-07 21:38:00

标签: audio audio-recording audiotoolbox

我可以设置音频队列进行录制,而AudioQueueStart可以很好地开始录制。

但是在调用AudioQueueStop之后,我发现无法再次启动相同的音频队列,而是需要为另一个录制开始创建一个新的音频队列和缓冲区。

停止后可以重复使用相同的音频队列吗?

感谢。

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。仔细研究文档并未发现任何有关此问题根源的线索,但查看示例代码所有记录队列仅使用一次 - 没有迹象表明它们可以重复使用。

文档中唯一的提示是,在将队列与AudioQueuePause暂停后,AudioQueueStart用于 RESUME

录制队列似乎是为一次性使用而设计的,需要在最后处理(AudioQueueDispose)并为任何后续录制重新创建。

答案 1 :(得分:0)

尽管没有任何文档,但似乎确实有这样的方法。

它要求确保在异步调用AudioQueueStop之后,正确处理仍在队列中的任何数据。

因此,在停止录音的调用中,我们有一个状态变量(recordingState)来跟踪发生了什么。鉴于此函数和回调在不同的线程中执行,我们尝试通过同步到当前类(在此示例中称为Listener)来避免任何可能的复杂性:

-(void) stopRecording
{
    @synchronized(self)
    {
        if(self.recordingState != RecordingStateRunning) {return;}

        self.recordingState = RecordingStateStopping;
        AudioQueueStop(self.audioQueue, false);
    }
}

实验表明,在对AudioQueueStop的异步调用(即参数inImmediate设置为false)之后,回调将被调用几次,因此我们有机会整理:

static void AQInputCallback(void *inUserData,
                        AudioQueueRef inAQ,
                        AudioQueueBufferRef inBuffer,
                        const AudioTimeStamp *inStartTime,
                        UInt32 inNumberPacketDescriptions,
                        const AudioStreamPacketDescription *inPacketDescs)
{
    Listener *listener = (__bridge Listener *) inUserData;

    @synchronized(listener)
    {
        if(listener.recordingState == RecordingStateRunning)
        {
            // Do audio processing here.
            // ...
        }
        else if(listener.recordingState == RecordingStateStopping)
        {
            listener.recordingState = RecordingStateStopped;

            // Do tidying here.
            // ...
        }

        AudioQueueEnqueueBuffer(listener.audioQueue, inBuffer, 0, NULL);
    }
}