Воспроизведение с iPhone AudioQueue останавливается / не может продолжаться после паузы в точке останова во время отладки - PullRequest
1 голос
/ 22 сентября 2010

По какой-то причине кажется, что остановка на точке останова во время отладки убьет мое воспроизведение аудио-очереди.

  1. AudioQueue будет воспроизводить аудио-вывод.
  2. Инициирование точки останова для приостановкиприложение для iPhone.
  3. Последующее возобновление, звук больше не воспроизводится.
  4. (Однако функции обратного вызова AudioQueue по-прежнему вызывают.)
  5. (Нет ошибок AudioSession или AudioQueueнайдено.)

Поскольку отладчик приостанавливает приложение (например, вместо входящего телефонного звонка), это не типичное прерывание iPhone, поэтому Обратные вызовы прерывания AudioSession не запускаются, как вэто решение .

Я использую три буфера AudioQueue при 4096 выборках при 22 кГц и заполняю их по кругу.

Проблема возникает для многопоточныходнопоточный режим.

  • Существует ли известная проблема, из-за которой невозможно приостановить и возобновить AudioSessions или AudioQueues во времясеанс отладки?
  • У него заканчиваются "буферы в очереди" и он уничтожает / убивает объект AudioQueue (но тогда мой обратный вызов AQ не должен срабатывать).

У кого-либо есть пониманиево внутреннюю работу iPhone AudioQueues?

1 Ответ

0 голосов
/ 23 сентября 2010

Проработав последние несколько дней перед публикацией в 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;
}
...