How Audio Queue stop current playing task and start play another AudioQueueBuffer immediately?

490 Views Asked by At

NEED: I have an audio queue and two AudioQueueBuffer. How can I play NO.2 AudioQueueBuffer immediately in the midst of NO.1 AudioQueueBuffer playing. I have tried AudioQueueStop or AudioQueueReset. it take a long time to process, NO.2 AudioQueueBuffer playing too late.

-(void)playBuffer:(AudioBuffer *)buffer format:(const AudioStreamBasicDescription *)format
{
    AudioQueueStop(_audioQueue, YES);//this line consuming too much time
    AudioQueueDispose(_audioQueue, YES);
    AudioQueueRef newAudioQueue;
    AudioQueueBufferRef queueBuffer;
    AudioQueueNewOutput(format, audioQueueOutputCallback, (__bridge void*)self,
                        nil, nil, 0, &newAudioQueue);
    OSStatus status;
    status = AudioQueueAllocateBuffer(newAudioQueue, buffer->mDataByteSize, &queueBuffer);

    memcpy(queueBuffer->mAudioData, buffer->mData, buffer->mDataByteSize);
    queueBuffer->mAudioDataByteSize=buffer->mDataByteSize;
    status = AudioQueueEnqueueBuffer(newAudioQueue, queueBuffer, 0, NULL);

    Float32 gain=1.0;
    AudioQueueSetParameter(newAudioQueue, kAudioQueueParam_Volume, gain);
    AudioQueueStart(newAudioQueue, nil);
    AudioQueueFreeBuffer(newAudioQueue, queueBuffer);
    _audioQueue = newAudioQueue;
}

so my question is:Is it possible audio queue play next audio buffer immediately?Or Is audio queue don't match this task And I need a alternative?

1

There are 1 best solutions below

1
ooOlly On BEST ANSWER

finally I just dispose audioQueue asynchronously. But I think AVAudioUint maybe a better solution for my situation.

- (void)playBuffer:(AudioBuffer *)buffer format:(const AudioStreamBasicDescription *)format
{
    oldAudioQueue = _audioQueue;
    if (oldAudioQueue){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            AudioQueuePause(oldAudioQueue);
            //AudioQueueStop(oldAudioQueue, YES);//this line consuming too much time, will barries thread
            AudioQueueDispose(oldAudioQueue, YES);
            oldAudioQueue = nil;
        });
    }

    AudioQueueRef newAudioQueue;
    AudioQueueBufferRef queueBuffer;
    AudioQueueNewOutput(format, audioQueueOutputCallback, (__bridge void*)self,
                        nil, nil, 0, &newAudioQueue);

    OSStatus status;
    status = AudioQueueAllocateBuffer(newAudioQueue, buffer->mDataByteSize, &queueBuffer);

    memcpy(queueBuffer->mAudioData, buffer->mData, buffer->mDataByteSize);
    queueBuffer->mAudioDataByteSize=buffer->mDataByteSize;
    status = AudioQueueEnqueueBuffer(newAudioQueue, queueBuffer, 0, NULL);

    Float32 gain=1.0;
    AudioQueueSetParameter(newAudioQueue, kAudioQueueParam_Volume, gain);
    AudioQueueStart(newAudioQueue, nil);
    AudioQueueFreeBuffer(newAudioQueue, queueBuffer);
    _audioQueue = newAudioQueue;
}