После игры с ним в течение последних нескольких дней, прежде чем отправлять в 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;
}