代码之家  ›  专栏  ›  技术社区  ›  zerojarvis

iPhone播放AudioQueue在调试期间在断点处暂停后停止/无法继续

  •  1
  • zerojarvis  · 技术社区  · 15 年前

    出于某种原因,在调试期间在断点处停止似乎会终止我的音频队列播放。

    1. AudioQueue将播放音频 输出。
    2. 触发断点以 暂停我的iPhone应用程序。
    3. 函数仍在被调用。)

    由于调试器暂停了应用程序(例如,不是一个来电),所以这不是典型的iPhone中断,所以 AudioSession interruption callbacks do not get triggered like in this solution .

    我正在使用 three AudioQueue buffers

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

    • 是否存在在调试会话期间无法暂停和恢复AudioSessions或AudioQueues的已知问题?

    有人了解iPhone音频队列的内部工作原理吗?

    1 回复  |  直到 8 年前
        1
  •  0
  •   zerojarvis    15 年前

    在玩了几天之后,在发布到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;
    }