美文网首页音频音视频从入门到放弃
几种播放音频文件的方式(四) —— 音频队列服务(Audio Q

几种播放音频文件的方式(四) —— 音频队列服务(Audio Q

作者: 刀客传奇 | 来源:发表于2017-12-27 14:35 被阅读700次

    版本记录

    版本号 时间
    V1.0 2017.12.26

    前言

    ios系统中有很多方式可以播放音频文件,这里我们就详细的说明下播放音乐文件的原理和实例。感兴趣的可以看我写的上面几篇。
    1. 几种播放音频文件的方式(一) —— 播放本地音乐
    2. 几种播放音频文件的方式(二) —— 音效播放
    3. 几种播放音频文件的方式(三) —— 网络音乐播放

    音频队列作用

    它是AudioToolbox中的API,它用来播放网络流媒体文件,可以做到音频的播放和录制。


    音频队列的组成

    音频队列主要由三部分组成:

    • 三个缓冲器buffer
      • 每个缓冲器都是一个存储音频数据的临时仓库。
    • 一个缓冲队列Buffer Queue
      • 一个包含音频缓冲器的有序队列
    • 一个回调callBack
      • 自定义的队列回调函数。

    具体工作流程如下图所示:

    在音频播放缓冲队列中,将音频读取到缓冲器中,一旦一个缓冲器填充满之后就放到缓冲队列中,然后继续填充其他缓冲器;当开始播放时,则从第一个缓冲器中读取音频进行播放;一旦播放完之后就会触发回调函数,开始播放下一个缓冲器中的音频,同时填充第一个缓冲器放;填充满之后再次放回到缓冲队列。下面具体说一下工作流程。

    • 1.创建AudioQueue,创建BufferArray数组,用于存放AudioQueueBufferRef
    • 2.通过AudioQueueAllocateBuffer创建AudioQueueBufferRef一般2-3个,放入到BufferArray数组中。
    • 3.有数据时从buffer数组取出一个buffer,memcpy数据后用AudioQueueEnqueueBuffer方法把buffer插入AudioQueue中。
    • 4.AudioQueue中存在Buffer后,调用AudioQueueStart播放。(具体等到填入多少buffer后再播放可以自己控制,只要能保证播放不间断即可)。
    • 5.AudioQueue播放音乐后消耗了某个buffer,在另一个线程回调并送出该buffer,把buffer放回BufferArray供下一次使用。
    • 6.返回步骤3继续循环直到播放结束。

    音频队列主要API

    1. 创建AudioQueue

    
    /*!
        @function   AudioQueueNewOutput
        @abstract   Creates a new audio queue for playing audio data.
        @discussion
            To create an playback audio queue, you allocate buffers, then queue buffers (using
            AudioQueueEnqueueBuffer). The callback receives buffers and typically queues them again.
            To schedule a buffer for playback, providing parameter and start time information, call
            AudioQueueEnqueueBufferWithParameters.
           
        @param      inFormat
            A pointer to a structure describing the format of the audio data to be played. For
            linear PCM, only interleaved formats are supported. Compressed formats are supported.
        @param      inCallbackProc
            A pointer to a callback function to be called when the audio queue has finished playing
            a buffer.
        @param      inUserData
            A value or pointer to data that you specify to be passed to the callback function.
        @param      inCallbackRunLoop
            The event loop on which inCallbackProc is to be called. If you specify NULL, the
            callback is called on one of the audio queue's internal threads.
        @param      inCallbackRunLoopMode
            The run loop mode in which to call the callback. Typically, you pass
            kCFRunLoopCommonModes. (NULL also specifies kCFRunLoopCommonModes). Other
            possibilities are implementation specific. You can choose to create your own thread with
            your own run loops. For more information on run loops, see Run Loops or CFRunLoop
            Reference.
        @param      inFlags
            Reserved for future use. Pass 0.
        @param      outAQ
            On return, this variable contains a pointer to the newly created playback audio queue
            object.
        @result     An OSStatus result code.
    */
    
    第一个参数表示需要播放的音频数据格式类型,是一个AudioStreamBasicDescription对象,是使用AudioFileStream或者AudioFile解析出来的数据格式信息;
    第二个参数AudioQueueOutputCallback是某块Buffer被使用之后的回调;
    第三个参数为上下文对象;
    第四个参数inCallbackRunLoop为AudioQueueOutputCallback需要在的哪个RunLoop上被回调,如果传入NULL的话就会再AudioQueue的内部RunLoop中被回调,所以一般传NULL就可以了;
    第五个参数inCallbackRunLoopMode为RunLoop模式,如果传入NULL就相当于kCFRunLoopCommonModes,也传NULL就可以了;
    第六个参数inFlags是保留字段,目前没作用,传0;
    第七个参数,返回生成的AudioQueue实例;
    return:返回值用来判断是否成功创建(OSStatus == noErr)。
    
    extern OSStatus             
    AudioQueueNewOutput( const AudioStreamBasicDescription *inFormat,
                          AudioQueueOutputCallback        inCallbackProc,
                         void * __nullable               inUserData,
                           CFRunLoopRef __nullable         inCallbackRunLoop,
                           CFStringRef __nullable          inCallbackRunLoopMode,
                           UInt32                          inFlags,
                          AudioQueueRef __nullable * __nonnull outAQ)          
    
    
    
    /*!
        @function   AudioQueueNewOutputWithDispatchQueue
        @abstract   Creates a new audio queue for playing audio data.
        @discussion
            To create an playback audio queue, you allocate buffers, then queue buffers (using
            AudioQueueEnqueueBuffer). The callback receives buffers and typically queues them again.
            To schedule a buffer for playback, providing parameter and start time information, call
            AudioQueueEnqueueBufferWithParameters.
           
        @param      outAQ
            On return, this variable contains a pointer to the newly created playback audio queue
            object.
        @param      inFormat
            A pointer to a structure describing the format of the audio data to be played. For
            linear PCM, only interleaved formats are supported. Compressed formats are supported.
        @param      inFlags
            Reserved for future use. Pass 0.
        @param      inCallbackDispatchQueue
            The dispatch queue from which inCallbackBlock is to be called.
        @param      inCallbackBlock
            A pointer to a callback block to be called when the audio queue has finished playing
            a buffer.
        @result     An OSStatus result code.
    */
    参数和上面基本相同,只是把RunLoop换成了dispatch queue
    AudioQueueNewOutputWithDispatchQueue(AudioQueueRef __nullable * __nonnull outAQ,
                                        const AudioStreamBasicDescription *inFormat,
                                        UInt32                          inFlags,
                                        dispatch_queue_t                inCallbackDispatchQueue,
                                        AudioQueueOutputCallbackBlock   inCallbackBlock)
    

    2. 创建Buffer

    /*!
        @function   AudioQueueAllocateBuffer
        @abstract   Asks an audio queue to allocate a buffer.
        @discussion
            Once allocated, the pointer to the buffer and the buffer's size are fixed and cannot be
            changed. The mAudioDataByteSize field in the audio queue buffer structure,
            AudioQueueBuffer, is initially set to 0.
            
        @param      inAQ
            The audio queue you want to allocate a buffer.
        @param      inBufferByteSize
            The desired size of the new buffer, in bytes. An appropriate buffer size depends on the
            processing you will perform on the data as well as on the audio data format.
        @param      outBuffer
            On return, points to the newly created audio buffer. The mAudioDataByteSize field in the
            audio queue buffer structure, AudioQueueBuffer, is initially set to 0.
        @result     An OSStatus result code.
    */
    第一个参数方法传入AudioQueue实例
    第二个参数Buffer大小
    第三个传出的BufferArray实例;
    
    extern OSStatus
    AudioQueueAllocateBuffer(AudioQueueRef    inAQ,
                              UInt32    inBufferByteSize,
                              AudioQueueBufferRef __nullable * __nonnull outBuffer)  
    
    
    /*!
        @function   AudioQueueAllocateBufferWithPacketDescriptions
        @abstract   Asks an audio queue to allocate a buffer with space for packet descriptions.
        @discussion
            Once allocated, the pointer to the buffer and the buffer's size are fixed and cannot be
            changed. The mAudioDataByteSize field in the audio queue buffer structure,
            AudioQueueBuffer, is initially set to 0.
            
        @param      inAQ
            The audio queue you want to allocate a buffer.
        @param      inBufferByteSize
            The desired size of the new buffer, in bytes. An appropriate buffer size depends on the
            processing you will perform on the data as well as on the audio data format.
        @param      inNumberPacketDescriptions
            The desired capacity of the packet description array in the new buffer.
        @param      outBuffer
            On return, points to the newly created audio buffer. The mAudioDataByteSize field in the
            audio queue buffer structure, AudioQueueBuffer, is initially set to 0.
        @result     An OSStatus result code.
    */
    比上面的方法多了一个inNumberPacketDescriptions,这个参数可以指定生成的Buffer中PacketDescriptions的个数
    extern OSStatus
    AudioQueueAllocateBufferWithPacketDescriptions(
                                        AudioQueueRef           inAQ,
                                        UInt32                  inBufferByteSize,
                                        UInt32                  inNumberPacketDescriptions,
                                        AudioQueueBufferRef __nullable * __nonnull outBuffer)
    

    3. 释放buffer

    /*!
        @function   AudioQueueFreeBuffer
        @abstract   Disposes of an audio queue buffer.
        @discussion
            This function disposes of the buffer allocated by AudioQueueAllocateBuffer. Disposing of
            an audio queue also automatically disposes of any associated buffers and timeline
            objects. Call this function only if you want to dispose of a particular buffer while
            continuing to use an audio queue. You can dispose of buffers only when the associated
            queue is stopped (that is, not processing audio data).
        @param      inAQ
            The queue from which the buffer was allocated.
        @param      inBuffer
            The buffer to be disposed.
        @result     An OSStatus result code.
    */
    第一个参数AudioQueue实例
    第二个参数指定的buffer
    
    extern OSStatus
    AudioQueueFreeBuffer(               AudioQueueRef           inAQ,
                                        AudioQueueBufferRef     inBuffer)
    

    4. 插入buffer

    /*!
        @function   AudioQueueEnqueueBuffer
        @abstract   Assigns a buffer to an audio queue for recording or playback.
        @discussion
            If the buffer was allocated with AudioQueueAllocateBufferWithPacketDescriptions,
            the client should provide packet descriptions in the buffer's mPacketDescriptions
            and mPacketDescriptionCount fields rather than in inPacketDescs and
            inNumPacketDescs, which should be NULL and 0, respectively, in this case.
            
            For an input queue, pass 0 and NULL for inNumPacketDescs and inPacketDescs,
            respectively. Your callback will receive packet descriptions owned by the audio queue.
    
        @param      inAQ
            The audio queue you are assigning the buffer to.
        @param      inBuffer
            The buffer to queue (that is, to be recorded into or played from).
        @param      inNumPacketDescs
            The number of packet descriptions pointed to by the inPacketDescs pointer. Applicable
            only for output queues and required only for variable-bit-rate (VBR) audio formats. Pass
            0 for input queues (no packet descriptions are required).
        @param      inPacketDescs
            An array of packet descriptions. Applicable only for output queues and required only for
            variable-bit-rate (VBR) audio formats. Pass NULL for input queues (no packet
            descriptions are required).
        @result     An OSStatus result code.
    */
    第一个参数AudioQueue实例
    第二个参数指定的Buffer
    第三个参数数据包的个数
    第四个参数数据包描述
    
    extern OSStatus
    AudioQueueEnqueueBuffer(            AudioQueueRef                       inAQ,
                                        AudioQueueBufferRef                 inBuffer,
                                        UInt32                              inNumPacketDescs,
                                        const AudioStreamPacketDescription * __nullable inPacketDescs)
    
    
    /*!
        @function   AudioQueueEnqueueBufferWithParameters
        @abstract   Assigns a buffer to an audio queue for playback, providing parameters
                    and start time information.
        @discussion
            You can exert some control of the buffer queue by using this function. You can assign
            audio queue settings that are in effect carried by an audio queue buffer as you enqueue
            it. Hence, these changes only take effect when an audio queue buffer begins playing.
            
            This function queues a buffer for playback only, not for recording. Audio queues for
            recording have no parameters, do not support variable-bit-rate (VBR) formats (which
            might require trimming), and have a different way to handle timing. When queued for
            playback, the buffer must contain the audio data to be played back. See
            AudioQueueEnqueueBuffer for details on queuing a buffer for recording.
    
            If the buffer was allocated with AudioQueueAllocateBufferWithPacketDescriptions,
            the client should provide packet descriptions in the buffer's mPacketDescriptions
            and mPacketDescriptionCount fields rather than in inPacketDescs and
            inNumPacketDescs, which should be NULL and 0, respectively, in this case.
        @param      inAQ
            The audio queue associated with the buffer.
        @param      inBuffer
            The buffer to be played from.
        @param      inNumPacketDescs
            The number of packet descriptions pointed to by the inPacketDescs parameter. Required
            only for variable-bit-rate (VBR) audio formats. Pass 0 if no packet descriptions are
            required.
        @param      inPacketDescs
            A pointer to an array of audio stream packet descriptions. Required only for VBR audio
            formats. Pass NULL if no packet descriptions are required.
        @param      inTrimFramesAtStart
            The number of priming frames to skip at the start of the buffer.
        @param      inTrimFramesAtEnd
            The number of frames to skip at the end of the buffer.
        @param      inNumParamValues
            The number of parameter values pointed to by the inParamValues parameter.
        @param      inParamValues
            An array of parameter values. (In Mac OS X v10.5, there is only one parameter,
            kAudioQueueParam_Volume.) These values are set before buffer playback and cannot be
            changed while the buffer is playing. How accurately changes in parameters can be
            scheduled depends on the size of the buffer. If there are no parameters to set
            (inNumParamValues = 0), pass NULL.
        @param      inStartTime
            A pointer to a structure containing the desired start time for playing the buffer. If
            you specify the time using the mSampleTime field of the AudioTimeStamp structure, the
            sample time is relative to the time the queue started. If you pass NULL for the start
            time, the buffer starts immediately after the previously queued buffer, or as soon as
            possible if no buffers are queued ahead of it. Buffers are played in the order they are
            queued. If multiple buffers are queued, their times must be in ascending order or NULL;
            otherwise, an error occurs. The start time indicates when the actual audio data in the
            buffer is to be played (that is, the trim frames are not counted).
            
            Note: When specifying a start time for a buffer, if the buffer is not the first enqueued
            since AudioQueueStop or AudioQueueReset, it is normally necessary to call AudioQueueFlush
            before AudioQueueEnqueueBufferWithParameters.
        @param      outActualStartTime
            On return, points to an AudioTimeStamp structure indicating when the buffer will
            actually play.
        @result     An OSStatus result code.
    */
    上面的方法基本满足要求,这个方法对插入的buffer进行额外的更多的操作
    extern OSStatus
    AudioQueueEnqueueBufferWithParameters(
                                        AudioQueueRef                                inAQ,
                                        AudioQueueBufferRef                          inBuffer,
                                        UInt32                                       inNumPacketDescs,
                                        const AudioStreamPacketDescription * __nullable inPacketDescs,
                                        UInt32                                       inTrimFramesAtStart,
                                        UInt32                                       inTrimFramesAtEnd,
                                        UInt32                                       inNumParamValues,
                                        const AudioQueueParameterEvent * __nullable  inParamValues,
                                        const AudioTimeStamp * __nullable            inStartTime,
                                        AudioTimeStamp * __nullable                  outActualStartTime)     __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    5. 开始播放

    /*!
        @function   AudioQueueStart
        @abstract   Begins playing or recording audio.
        @discussion
            If the audio hardware is not already running, this function starts it.
        @param      inAQ
            The audio queue to start.
        @param      inStartTime
            A pointer to the time at which the audio queue should start. If you specify the time
            using the mSampleTime field of the AudioTimeStamp structure, the sample time is
            referenced to the sample frame timeline of the associated audio device. May be NULL.
        @result     An OSStatus result code.
    */
    第一个参数AudioQueue实例
    第二个参数播放时间,如果直接开始播放 传NULL
    
    extern OSStatus
    AudioQueueStart(                    AudioQueueRef                     inAQ,
                                        const AudioTimeStamp * __nullable inStartTime)
    

    6. 解码数据,不常用,调用开始播放会自动解码

    /*!
        @function   AudioQueuePrime
        @abstract   Begins decoding buffers in preparation for playback.
        @discussion
            This function begins decoding buffers in preparation for playback. It returns when at
            least the number of audio sample frames are decoded and ready to play or when all
            enqueued buffers have been completely decoded. To ensure that a buffer has been decoded
            and is completely ready for playback, before playback:
                1.  Call AudioQueueEnqueueBuffer.
                2.  Call AudioQueuePrime, which waits if you pass 0 to have a default number of
                    frames decoded.
                3.  Call AudioQueueStart.
    
            Calls to AudioQueuePrime following AudioQueueStart/AudioQueuePrime, and before
            AudioQueueReset/AudioQueueStop, will have no useful effect. In this situation,
            outNumberOfFramesPrepared will not have a useful return value.
        @param      inAQ
            The audio queue to be primed.
        @param      inNumberOfFramesToPrepare
            The number of frames to decode before returning. Pass 0 to decode all enqueued buffers.
        @param      outNumberOfFramesPrepared
            If not NULL, on return, a pointer to the number of frames actually decoded and prepared
            for playback.
        @result     An OSStatus result code.
    */
    extern OSStatus
    AudioQueuePrime(                    AudioQueueRef           inAQ,
                                        UInt32                  inNumberOfFramesToPrepare,
                                        UInt32 * __nullable     outNumberOfFramesPrepared)
    

    7. 停止播放

    /*!
        @function   AudioQueueStop
        @abstract   Stops playing or recording audio.
        @discussion
            This function resets the audio queue and stops the audio hardware associated with the
            queue if it is not in use by other audio services. Synchronous stops occur immediately,
            regardless of previously buffered audio data. Asynchronous stops occur after all queued
            buffers have been played or recorded.
        @param      inAQ
            The audio queue to stop.
        @param      inImmediate
            If you pass true, the stop request occurs immediately (that is, synchronously), and the
            function returns when the audio queue has stopped. Buffer callbacks are invoked during
            the stopping. If you pass false, the function returns immediately, but the queue does
            not stop until all its queued buffers are played or filled (that is, the stop occurs
            asynchronously). Buffer callbacks are invoked as necessary until the queue actually
            stops. Also, a playback audio queue callback calls this function when there is no more
            audio to play.
    
            Note that when stopping immediately, all pending buffer callbacks are normally invoked
            during the process of stopping. But if the calling thread is responding to a buffer
            callback, then it is possible for additional buffer callbacks to occur after
            AudioQueueStop returns.
        @result     An OSStatus result code.
    */
    第二个参数Bool值,控制是否立即停止,如果传false,会把Enqueue的所有buffer播放完成再停止
    
    extern OSStatus
    AudioQueueStop(                     AudioQueueRef           inAQ,
                                        Boolean                 inImmediate)            __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    8. 暂停播放

    /*!
        @function   AudioQueuePause
        @abstract   Pauses audio playback or recording.
        @discussion
            Pausing the queue does not affect buffers or reset the audio queue. To resume playback
            or recording using the audio queue, call AudioQueueStart.
        @param      inAQ
            The queue to be paused.
        @result     An OSStatus result code.
    */
    extern OSStatus
    AudioQueuePause(                    AudioQueueRef           inAQ)       __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    9. 重置解码器

    /*!
        @function   AudioQueueFlush
        @abstract   Resets the audio queue's decoder state.
        @discussion
            After all queued buffers have been played, the function cleans up all decoder state
            information. You must call this function following a sequence of buffers of encoded
            audio; otherwise, some of the audio might not play in the next set of queued buffers.
            The only time it is not necessary to call AudioQueueFlush is following AudioQueueStop
            with inImmediate=false. (This action internally calls AudioQueueFlush.)
            
            Also, you might wish to call this function before calling AudioQueueStop depending on
            whether you want to stop immediately regardless of what has played or whether you want
            to ensure that all buffered data and all data that is in the middle of processing gets
            recorded or played before stopping.
            
        @param      inAQ
            The audio queue to be flushed.
            
        @result     An OSStatus result code.
    */
    这个方法会播放完队列中的buffer后重置解码器,防止当前的解码器影响下一段音频,比如切换歌曲的时候,如果和AudioQueueStop(AQ,false)
    一起使用并不会起效,因为Stop方法的false参数也会做同样的事情。
    
    extern OSStatus
    AudioQueueFlush(                    AudioQueueRef           inAQ)            __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    10. 重置AudioQueue

    /*!
        @function   AudioQueueReset
        @abstract   Resets an audio queue.
        @discussion
            This function immediately resets an audio queue, flushes any queued buffer, removes all
            buffers from previously scheduled use, and resets any decoder and digital signal
            processing (DSP) state information. It also invokes callbacks for any flushed buffers.
            If you queue any buffers after calling this function, processing does not occur until
            the decoder and DSP state information is reset. Hence, a discontinuity (that is, a
            "glitch") might occur.
    
            Note that when resetting, all pending buffer callbacks are normally invoked
            during the process of resetting. But if the calling thread is responding to a buffer
            callback, then it is possible for additional buffer callbacks to occur after
            AudioQueueReset returns.
        @param      inAQ
            The audio queue to reset.
    
        @result     An OSStatus result code.
    */
    重置AudioQueue会清除所有已经Enqueue的buffer,并触发AudioQueueOutputCallback,调用AudioQueueStop方法时同样会触发该方法。这个方法的直接调用一般在seek时使用,用来清除残留的buffer(seek时还有一种做法是先AudioQueueStop
    ,等seek完成后重新start)。
    
    extern OSStatus
    AudioQueueReset(                    AudioQueueRef           inAQ)            __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    11. 获取播放时间

    /*!
        @function   AudioQueueGetCurrentTime
        @abstract   Obtains the current audio queue time.
        @discussion
            You must specify a timeline object if you want to be notified about any timeline
            discontinuities in the outTimelineDiscontinuity parameter. If you don't care about
            discontinuities, pass NULL in the inTimeLine and outTimelineDiscontinuity parameters.
        @param      inAQ
            The audio queue whose current time you want to obtain.
        @param      inTimeline
            The audio queue timeline object to which any timeline discontinuities are reported. May
            be NULL.
        @param      outTimeStamp
            On return, points to an audio timestamp structure containing the current audio queue
            time. The mSampleTime field is in terms of the audio queue's sample rate, and relative
            to the time at which the queue has started or will start.
        @param      outTimelineDiscontinuity
            Can be NULL. On return, only set to true or false if the inTimeLine parameter is not
            NULL. Set to true if a discontinuity has occurred in the sample timeline of the audio
            queue. For instance, the device's sample rate changed and a gap occurred in playback or
            recording, or the audio queue was unable to prepare and playback in time because it was
            late.
        @result
            An OSStatus result code.
    */
    调用时传入AudioTimeStamp,从这个结构体当中获取播放时间
    
    extern OSStatus
    AudioQueueGetCurrentTime(           AudioQueueRef                    inAQ,
                                        AudioQueueTimelineRef __nullable inTimeline,
                                        AudioTimeStamp * __nullable      outTimeStamp,
                                        Boolean * __nullable             outTimelineDiscontinuity)       __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    12. 销毁AudioQueue

    /*!
        @function   AudioQueueDispose
        @abstract   Disposes an existing audio queue.
        @discussion
            Disposing of the audio queue also disposes of all its resources, including its buffers.
        @param      inAQ
            The audio queue you want to dispose of
        @param      inImmediate
            If you pass true, the audio queue is disposed of immediately (that is, synchronously).
            If you pass false, disposal does not take place until all enqueued buffers are
            processed. Whether you call AudioQueueDispose synchronously or asynchronously, you can
            no longer interact with the queue, and the queue no longer invokes any callbacks to your
            application after the function returns.
            
            Note that if AudioQueueDispose is called from a buffer completion callback or property
            listener, you may receive further callbacks afterwards.
        @result     An OSStatus result code.
    */
    参数的意义基本和AudioQueueStop一样
    
    extern OSStatus
    AudioQueueDispose(                  AudioQueueRef           inAQ, 
                                        Boolean                 inImmediate)            __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    
    

    13. AudioQueue参数

    AudioQueueGetParameter
    /*!
        @function   AudioQueueGetParameter
        @abstract   Obtains an audio queue parameter value.
        @discussion
            You can access the current parameter values for an audio queue at any time with this
            function.
        @param      inAQ
            The audio queue whose parameter value you want to obtain.
        @param      inParamID
            The ID of the parameter you want to obtain. In Mac OS X v10.5, audio queues have one
            parameter available: kAudioQueueParam_Volume, which controls the queue's playback
            volume.
        @param      outValue
            On return, points to the current value of the specified parameter.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueGetParameter(             AudioQueueRef               inAQ,
                                        AudioQueueParameterID       inParamID,
                                        AudioQueueParameterValue *  outValue)       __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    
    AudioQueueSetParameter
    /*!
        @function   AudioQueueSetParameter
        @abstract   Sets an audio queue parameter value.
        @discussion
        @param      inAQ
            The audio queue whose parameter value you want to set.
        @param      inParamID
            The ID of the parameter you want to set.
        @param      inValue
            The parameter value to set.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueSetParameter(             AudioQueueRef               inAQ,
                                        AudioQueueParameterID       inParamID,
                                        AudioQueueParameterValue    inValue)        __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    
    参数列表
    CF_ENUM(AudioQueueParameterID)
    {
        kAudioQueueParam_Volume         = 1,
        kAudioQueueParam_PlayRate       = 2,
        kAudioQueueParam_Pitch          = 3,
        kAudioQueueParam_VolumeRampTime = 4,
        kAudioQueueParam_Pan            = 13
    };
    

    14. AudioQueue属性

    AudioQueueGetPropertySize
    /*!
        @function   AudioQueueGetPropertySize
        @abstract   Obtains the size of an audio queue property.
        @discussion 
        @param      inAQ
            The audio queue containing the property value whose size you want to obtain.
        @param      inID
            The ID of the property value whose size you want to obtain. See "Audio Queue Property
            IDs" for possible values.
        @param      outDataSize
            On return, points to the size of the specified property value.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueGetPropertySize(          AudioQueueRef           inAQ,
                                        AudioQueuePropertyID    inID,
                                        UInt32 *                outDataSize)            __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    
    AudioQueueGetProperty
    /*!
        @function   AudioQueueGetProperty
        @abstract   Obtains an audio queue property value.
        @discussion 
        @param      inAQ
            The audio queue whose property value you want to obtain.
        @param      inID
            The ID of the property you want to obtain. See "Audio Queue Property IDs."
        @param      outData
            On return, points to the desired property value.
        @param      ioDataSize
            A pointer to the size of the property data. On input, points to the maximum bytes of
            space the caller expects to receive. On return, points to the actual data size.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueGetProperty(              AudioQueueRef           inAQ,
                                        AudioQueuePropertyID    inID,
                                        void *                  outData,
                                        UInt32 *                ioDataSize)             __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    
    AudioQueueSetProperty
    /*!
        @function   AudioQueueSetProperty
        @abstract   Sets an audio queue property value.
        @discussion 
        @param      inAQ
            The audio queue whose property value you want to set.
        @param      inID
            The ID of the property you want to set. See "Audio Queue Property IDs" for the various
            audio queue properties.
        @param      inData
            A pointer to the property value to set.
        @param      inDataSize
            The size of the property data.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueSetProperty(              AudioQueueRef           inAQ,
                                        AudioQueuePropertyID    inID,
                                        const void *            inData,
                                        UInt32                  inDataSize)             __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    
    属性列表
    CF_ENUM(AudioQueuePropertyID) {
        kAudioQueueProperty_IsRunning               = 'aqrn',       // value is UInt32
    
        kAudioQueueDeviceProperty_SampleRate        = 'aqsr',       // value is Float64
        kAudioQueueDeviceProperty_NumberChannels    = 'aqdc',       // value is UInt32
        kAudioQueueProperty_CurrentDevice           = 'aqcd',       // value is CFStringRef
        
        kAudioQueueProperty_MagicCookie             = 'aqmc',       // value is void*
        kAudioQueueProperty_MaximumOutputPacketSize = 'xops',       // value is UInt32
        kAudioQueueProperty_StreamDescription       = 'aqft',       // value is AudioStreamBasicDescription
           
        kAudioQueueProperty_ChannelLayout           = 'aqcl',       // value is AudioChannelLayout
        kAudioQueueProperty_EnableLevelMetering     = 'aqme',       // value is UInt32
        kAudioQueueProperty_CurrentLevelMeter       = 'aqmv',       // value is array of AudioQueueLevelMeterState, 1 per channel
        kAudioQueueProperty_CurrentLevelMeterDB     = 'aqmd',       // value is array of AudioQueueLevelMeterState, 1 per channel
    
        kAudioQueueProperty_DecodeBufferSizeFrames  = 'dcbf',       // value is UInt32
        kAudioQueueProperty_ConverterError          = 'qcve',       // value is UInt32
    
        kAudioQueueProperty_EnableTimePitch         = 'q_tp',       // value is UInt32, 0/1
        kAudioQueueProperty_TimePitchAlgorithm      = 'qtpa',       // value is UInt32. See values below.
        kAudioQueueProperty_TimePitchBypass         = 'qtpb',       // value is UInt32, 1=bypassed
    };
    

    15. 添加监听属性

    AudioQueueAddPropertyListener
    /*!
        @function   AudioQueueAddPropertyListener
        @abstract   Adds a listener callback for a property.
        @discussion 
            This callback is used to act upon a change in an audio queue property such as
            kAudioQueueProperty_IsRunning. For instance, if your application has a user interface
            with a Play/Stop button, and kAudioQueueProperty_IsRunning changes, you need to update
            your button.
        @param      inAQ
            The audio queue that owns the property you want to assign the listener callback to.
        @param      inID
            The ID of the property to which you want to assign a listener callback. See "Audio Queue Property IDs".
        @param      inProc
            The listener callback to be called when the property value changes.
        @param      inUserData
            A value to be passed to the listener callback when it is called.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueAddPropertyListener(      AudioQueueRef                   inAQ,
                                        AudioQueuePropertyID            inID,
                                        AudioQueuePropertyListenerProc  inProc,
                                        void * __nullable               inUserData)     __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    16. 移除监听属性

    AudioQueueRemovePropertyListener
    /*!
        @function   AudioQueueRemovePropertyListener
        @abstract   Removes a listener callback for a property.
        @discussion 
        @param      inAQ
            The audio queue that owns the property from which you want to remove a listener.
        @param      inID
            The ID of the property from which you want to remove a listener.
        @param      inProc
            The listener being removed.
        @param      inUserData
            The same inUserData value that was previously passed to AudioQueueAddPropertyListener.
        @result
            An OSStatus result code.
    */
    extern OSStatus
    AudioQueueRemovePropertyListener(   AudioQueueRef                   inAQ,
                                        AudioQueuePropertyID            inID,
                                        AudioQueuePropertyListenerProc  inProc,
                                        void * __nullable               inUserData)     __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
    

    大家如果对AudioQueue感兴趣,有大牛给大家推荐两个github地址,一个是AudioStreamer,一个是FreeStreamer,这里的两个播放都是使用AudioQueue实现的。更多请详见技术文档

    参考文章

    1. iOS中声音播放的各种方法总结

    后记

    未完,待续~~~

    相关文章

      网友评论

        本文标题:几种播放音频文件的方式(四) —— 音频队列服务(Audio Q

        本文链接:https://www.haomeiwen.com/subject/txrygxtx.html