由于某种原因,似乎在调试过程中在断点处停止会杀死我的音频队列播放。


AudioQueue将播放音频
输出。
触发一个断点来
暂停我的iPhone应用程序。
后续的
恢复,不再播放音频。
(但是,AudioQueue回调
函数仍在被调用。)
(没有AudioSession或AudioQueue
发现错误。)


由于调试器会暂停应用程序(例如,而不是打入电话),因此这不是典型的iPhone中断,因此AudioSession interruption callbacks do not get triggered like in this solution

我正在以22kHz的4096个样本使用three AudioQueue buffers,并以循环方式填充它们。

多线程和单线程模式均会出现问题。


是否存在一些已知问题,您无法在调试会话期间暂停和恢复AudioSessions或AudioQueues?
它是否耗尽了“排队缓冲区”,并且正在销毁/杀死AudioQueue对象(但是,我的AQ回调不应该触发)。


任何人都了解iPhone AudioQueues的内部运作方式吗?

最佳答案

在玩了几天之后,在发布到StackOverflow之前,我今天才找到答案。去搞清楚!

只需调用我的“准备功能”来重新创建AudioQueue

SetupNewQueue(mDataFormat.mSampleRate, mDataFormat.mChannelsPerFrame);
StartQueue(true);


因此,检测您的AudioQueue何时可能“死亡”。就我而言,我将数据写入输入缓冲区,以通过AudioQueue回调“拉”。如果在一定时间内没有发生这种情况,或者在X字节的输入缓冲区已满之后,我将重新创建AudioQueue。

这似乎解决了当您遇到调试断点时音频“停止/失败”的问题。

这些功能的简化版本如下:

void AQPlayer::SetupNewQueue(double inSampleRate, UInt32 inChannelsPerFrame)
{
    //Prep AudioStreamBasicDescription
    mDataFormat.mSampleRate = inSampleRate;
    mDataFormat.SetCanonical(inChannelsPerFrame, YES);

    XThrowIfError(AudioQueueNewOutput(&mDataFormat, AQPlayer::AQBufferCallback, this,
                                    NULL, kCFRunLoopCommonModes, 0, &mQueue), "AudioQueueNew failed");

    // adjust buffer size to represent about a half second of audio based on this format
    CalculateBytesForTime(mDataFormat, kBufferDurationSeconds, &mBufferByteSize, &mNumPacketsToRead);
    ctl->cmsg(CMSG_INFO, VERB_NOISY, "AQPlayer Buffer Byte Size: %d, Num Packets to Read: %d\n", (int)mBufferByteSize, (int)mNumPacketsToRead);

    mBufferWaitTime = mNumPacketsToRead / mDataFormat.mSampleRate * 0.9;

    XThrowIfError(AudioQueueAddPropertyListener(mQueue, kAudioQueueProperty_IsRunning, isRunningProc, this), "adding property listener");

    //Allocate AQ buffers (assume we are using CBR (constant bitrate)
    for (int i = 0; i < kNumberBuffers; ++i) {
        XThrowIfError(AudioQueueAllocateBuffer(mQueue, mBufferByteSize, &mBuffers[i]), "AudioQueueAllocateBuffer failed");
    }
...
}




OSStatus AQPlayer::StartQueue(BOOL inResume)
{
// if we are not resuming, we also should restart the file read index
    if (!inResume)
        mCurrentPacket = 0;

    // prime the queue with some data before starting
    for (int i = 0; i < kNumberBuffers; ++i) {
        mBuffers[i]->mAudioDataByteSize = mBuffers[i]->mAudioDataBytesCapacity;
        memset( mBuffers[i]->mAudioData, 0, mBuffers[i]->mAudioDataByteSize );

        XThrowIfError(AudioQueueEnqueueBuffer( mQueue,
                                mBuffers[i],
                                0,
                                NULL ),"AudioQueueEnqueueBuffer failed");
    }

    OSStatus status;
    status = AudioSessionSetActive( true );
    XThrowIfError(status, "\n\n*** AudioSession failed to become active *** \n\n");

    status = AudioQueueStart(mQueue, NULL);
    XThrowIfError(status, "\n\n*** AudioQueue failed to start *** \n\n");

    return status;
}

关于ios - iPhone播放AudioQueue调试期间在断点处暂停后停止/无法继续,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3771979/

10-09 19:32