iosaudioaudioqueueaudioqueueservices

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


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?


Solution

  • 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;
    }