0

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
ooOlly
  • 1,997
  • 21
  • 31

1 Answers1

0

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;
}
ooOlly
  • 1,997
  • 21
  • 31
  • 2
    In my situation, I must play incoming different `AudioBuffer`, when new `AudioBuffer` coming, APP must stop old audio and play the new – ooOlly Mar 02 '17 at 06:40