1

何らかの理由で、デバッグ中にブレークポイントで停止すると、オーディオキューの再生が停止するようです。

  1. AudioQueueはオーディオ出力を再生します。
  2. ブレークポイントをトリガーして、iPhoneアプリを一時停止します。
  3. その後の再開では、オーディオは再生されなくなります。
  4. (ただし、AudioQueueコールバック関数はまだ呼び出されています。)
  5. (AudioSessionまたはAudioQueueエラーは見つかりません。)

デバッガーは(たとえば、電話の着信ではなく)アプリケーションを一時停止するため、これは通常のiPhoneの中断ではないため、このソリューションのようにAudioSessionの中断コールバックはトリガーされません

私は22kHzで4096サンプルの3つのAudioQueueバッファーを使用しており、それらを循環的に埋めています。

マルチスレッドモードとシングルスレッドモードの両方で問題が発生します。

  • デバッグセッション中にAudioSessionsまたはAudioQueuesを一時停止および再開できないという既知の問題はありますか?
  • 「キューに入れられたバッファ」が不足していて、AudioQueueオブジェクトを破棄/強制終了していますか(ただし、AQコールバックはトリガーされません)。

誰かがiPhoneAudioQueuesの内部の仕組みについての洞察を持っていますか?

4

1 に答える 1

0

過去数日間それをいじった後、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;
}
于 2010-09-23T01:15:15.690 に答える