2010-09-22 24 views
1

出於某種原因,似乎在調試過程中停在斷點處會導致我的音頻隊列播放停止。iPhone回放AudioQueue在調試過程中在斷點處暫停後無法繼續/失敗

  1. AudioQueue將播放音頻 輸出。
  2. 觸發一個斷點到 暫停我的iPhone應用程序。
  3. 後續 恢復,音頻不再播放。
  4. (然而,AudioQueue回調 功能仍然得到調用。)
  5. (無AudioSession或AudioQueue發現 錯誤。)

因爲調試暫停應用(而不是呼入電話,例如),這不是一個典型的iPhone中斷,所以​​3210。

我使用three AudioQueue buffers在22kHz的4096個採樣並以循環方式填充它們。

對於多線程和單線程模式都會出現問題。

  • 是否有一些已知的問題,在調試會話期間無法暫停和恢復AudioSessions或AudioQueues?
  • 用完「排隊緩衝區」並且它正在銷燬/殺死AudioQueue對象(但不應觸發我的AQ回調)。

任何人都可以洞察iPhone AudioQueues的內部工作原理嗎?

回答

0

在過去幾天玩過它之後,在發佈到StackOverflow之前,我在今天就想出了答案。去搞清楚!

只需撥打我的「準備功能」

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

所以檢測何時AudioQueue可能再次重現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; 
} 
相關問題