2010-09-22 1 views
1

По некоторым причинам кажется, что остановка в точке останова во время отладки приведет к укушению воспроизведения звуковой очереди.Воспроизведение iPhone AudioQueue останавливается/не может продолжаться после паузы в точке останова во время отладки

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

Поскольку отладчик приостанавливает приложения (а не входящего телефонного звонка, например), это не типичное прерывание iPhone, поэтому AudioSession interruption callbacks do not get triggered like in this solution.

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

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

  • Есть ли известная проблема, что вы не можете приостановить и возобновить AudioSessions или AudioQueues во время сеанса отладки?
  • Заканчивается ли это «буферизация в очереди», и это уничтожает/убивает объект AudioQueue (но тогда мой обратный вызов AQ не должен запускаться).

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

ответ

0

После игры с ним в течение последних нескольких дней, прежде чем отправлять в StackOverflow, я понял ответ только сегодня. Иди цифра!

Просто воссоздать снова звуковые сообщения вызывая мою «функцию подготовки»

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

Так обнаружить, когда ваша очередь звукового может иметь «умер». В моем случае я бы записывал данные во входной буфер, чтобы «вытащить» обратный вызов 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; 
} 
Смежные вопросы