iOS音频播放学习(4)

Audio Queue

Audio Queue功能:连接音频硬件;管理内存;调用编解码器;播放或者录音

控制Audio Queue:
AudioQueueStart
OSStatus AudioQueueStart ( AudioQueueRef inAQ, // 需要开启的Audio Queue
                           const AudioTimeStamp *inStartTime ); // 开启的时间。使用AudioTimeStamp的mSampleTime,使用NULL来马上开启。

AudioQueuePrime
OSStatus AudioQueuePrime ( AudioQueueRef inAQ, 
                           UInt32 inNumberOfFramesToPrepare,  // 在返回之前需要解码的帧数,0表示解码所有入列的buffer
                           UInt32 *outNumberOfFramesPrepared ); // 在作为输出时,表示实际上的解码和播放的帧数。在作为输入时可以传递0
这个函数为播放音频做准备,解码已经入列的buffer,返回inNumberOfFramesToPrepare中指定的最少的解码帧数。
步骤:调用AudioEnqueueBuffer;
AudioQueuePrime;
AudioQueueStart

AudioQueueFlush
重设音频队列解码状态
OSStatus AudioQueueFlush ( AudioQueueRef inAQ );
在确保所有缓冲的数据中的最后的数据已经入列时调用。如果不调用的话,可能会对下一个缓冲的数据播放造成干扰
在确保所有入列的数据已经到达目的地之前调用AudioQueueStop.

AudioQueueStop
OSStatus AudioQueueStop ( AudioQueueRef inAQ, 
                          Boolean inImmediate ); // true的话,马上停止(同步)。传递false该函数会马上返回,但是音频队列会在其队列被播放或者录音后才停止(异步)
该函数重设音频队列,停止与该队列相关的硬件,还有停止队列本身。在录音时,该函数通常由用户调用;在播放时,当没有音频可以播放时则由播放音频队列的回调调用

AudioQueuePause
OSStatus AudioQueuePause ( AudioQueueRef inAQ );
暂停队列,要开始时调用AudioQueueStart

AudioQueueReset
OSStatus AudioQueueReset ( AudioQueueRef inAQ );
重设音频队列,刷新所有队列缓存,移除已经使用的缓冲,重设解码器和数字信号进程状态


音频队列的创建和处理

AudioQueueNewOutput
创建新的播放音频队列对象
OSStatus AudioQueueNewOutput ( const AudioStreamBasicDescription *inFormat,  // 要播放的音频的数据格式
                               AudioQueueOutputCallback inCallbackProc,  // 播放音频队列的回调函数
                               void *inUserData,  // 回调函数使用的自定义数据结构
                               CFRunLoopRef inCallbackRunLoop,  // 使用NULL的话会在音频队列的内部进程中调用回调
                               CFStringRef inCallbackRunLoopMode,  // 
                               UInt32 inFlags,  // 必须为0
                               AudioQueueRef *outAQ ); // 作为输出时,为最新创建的播放音频队列对象

AudioQueueNewInput
OSStatus AudioQueueNewInput ( const AudioStreamBasicDescription *inFormat, 
                              AudioQueueInputCallback inCallbackProc, 
                              void *inUserData, 
                              CFRunLoopRef inCallbackRunLoop, 
                              CFStringRef inCallbackRunLoopMode, 
                              UInt32 inFlags, 
                              AudioQueueRef *outAQ );
创建新的录音音频队列对象

AudioQueueDispose
OSStatus AudioQueueDispose ( AudioQueueRef inAQ, 
                             Boolean inImmediate );
处理一个音频队列
处理音频队列及其数据源,包括缓存。在调用了函数以后,可以不再与音频队列进行交互。而音频队列也不能够再调用其他回调函数


处理音频队列缓冲

AudioQueueAllocateBuffer
OSStatus AudioQueueAllocateBuffer ( AudioQueueRef inAQ, 
                                    UInt32 inBufferByteSize,  // 大小取决于数据的进程以及音频数据格式
                                    AudioQueueBufferRef *outBuffer ); // 作为输出时,指向最新分配的音频队列缓存
要求音频队列对象分配音频队列缓存
一旦分配完成,指向缓存的指针和缓存的容量就不允许改变。缓存大小--mAudioDataByteSize, 表明了有效数据的数量会被初始化为0

AudioQueueAllocateBufferWithPacketDescriptions
要求音频队列对象为帧描述分配空间
OSStatus AudioQueueAllocateBufferWithPacketDescriptions ( AudioQueueRef inAQ, 
                                                          UInt32 inBufferByteSize, 
                                                          UInt32 inNumberPacketDescriptions, 
                                                          AudioQueueBufferRef *outBuffer );
一般用于VBR

AudioQueueFreeBuffer
处理音频队列缓冲
OSStatus AudioQueueFreeBuffer ( AudioQueueRef inAQ,
                                AudioQueueBufferRef inBuffer );

AudioQueueEnqueueBuffer
添加一个缓冲区
OSStatus AudioQueueEnqueueBuffer ( AudioQueueRef inAQ, 
                                   AudioQueueBufferRef inBuffer,  // 要添加到队列的缓冲
                                   UInt32 inNumPacketDescs,  // 在以下几种情况时使用0:播放CBR格式的音频/作为录音的音频队列/使用AudioQueueAllocateBufferWithPacketDescription函数来进行入列操作时
                                   const AudioStreamPacketDescription *inPacketDescs ); // 在以下几种情况使用NULL:同上

AudioQueueEnqueueBufferWithParameters
为播放音频队列对象的缓冲队列添加一个缓冲,指定开始时间和其他的设定
OSStatus AudioQueueEnqueueBufferWithParameters ( AudioQueueRef inAQ, 
                                                 AudioQueueBufferRef inBuffer, 
                                                 UInt32 inNumPacketDescs, 
                                                 const AudioStreamPacketDescription *inPacketDescs, 
                                                 UInt32 inTrimFramesAtStart,  // 该buffer的开始时间
                                                 UInt32 inTrimFramesAtEnd,  // 结束时间
                                                 UInt32 inNumParamValues,  // 音频队列参数数目
                                                 const AudioQueueParameterEvent *inParamValues, // 音频队列缓冲的参数数组
                                                 const AudioTimeStamp *inStartTime, // 播放缓冲的期望开始时间
                                                 AudioTimeStamp *outActualStartTime );


音频队列参数
AudioQueueGetParameter
获取音频队列参数
OSStatus AudioQueueGetParameter ( AudioQueueRef inAQ, 
                                  AudioQueueParameterID inParamID, // 参数的ID
                                  AudioQueueParameterValue *outValue ); // 指定参数当前值的指针

AudioQueueSetParameter
设置播放音频队列参数值
OSStatus AudioQueueSetParameter ( AudioQueueRef inAQ,
                                  AudioQueueParameterID inParamID,
                                  AudioQueueParameterValue inValue );


音频队列属性

AudioQueueGetProperty
获取音频队列属性值
OSStatus AudioQueueGetProperty ( AudioQueueRef inAQ, 
                                 AudioQueuePropertyID inID, 
                                 void *outData,  // 在输出时,为期望的属性值
                                 UInt32 *ioDataSize ); // 在输入时,为调用者所期望接收的最大字节的空间;输出时为属性值的真实数据大小
在调用以前,需要使用AudioQueueGetPropertySize函数来决定大小。

AudioQueueSetProperty
OSStatus AudioQueueSetProperty ( AudioQueueRef inAQ, 
                                 AudioQueuePropertyID inID,
                                 const void *inData, 
                                 UInt32 inDataSize );

AudioQueueGetPropertySize
获取属性的size
OSStatus AudioQueueGetPropertySize ( AudioQueueRef inAQ,
                                     AudioQueuePropertyID inID, 
                                     UInt32 *outDataSize );

AudioQueueAddPropertyListener
给音频队列添加属性监听回调
OSStatus AudioQueueAddPropertyListener ( AudioQueueRef inAQ, 
                                         AudioQueuePropertyID inID, 
                                         AudioQueuePropertyListenerProc inProc, // 属性值变化时执行的回调函数
                                         void *inUserData );
比如说可以用于播放暂停或者停止状态的监听

AudioQueueRemovePropertyListener
移除回调函数
OSStatus AudioQueueRemovePropertyListener ( AudioQueueRef inAQ, 
                                            AudioQueuePropertyID inID,
                                            AudioQueuePropertyListenerProc inProc, 
                                            void *inUserData );


时间的处理

AudioQueueCreateTimeLine
为音频队列创建时间线对象
OSStatus AudioQueueCreateTimeline ( AudioQueueRef inAQ,
                                    AudioQueueTimelineRef *outTimeline );

AudioQueueDisposeTimeLine
释放音频队列时间轴对象
OSStatus AudioQueueDisposeTimeline ( AudioQueueRef inAQ, 
                                     AudioQueueTimelineRef inTimeline );

AudioQueueDeviceGetCurrentTime
获取设备的当前时间
OSStatus AudioQueueDeviceGetCurrentTime ( AudioQueueRef inAQ, 
                                          AudioTimeStamp *outTimeStamp ); // 作为输出时,为当前的时间,如果设备并没有运行的话,只能填入mHostTime

AudioQueueDeviceGetNearestStartTime
获取开始时间
OSStatus AudioQueueDeviceGetNearestStartTime ( AudioQueueRef inAQ, 
                                               AudioTimeStamp *ioRequestedStartTime, 
                                               UInt32 inFlags ); // 传0

AudioQueueDeviceTranslateTime
转换时间
OSStatus AudioQueueDeviceTranslateTime ( AudioQueueRef inAQ, 
                                         const AudioTimeStamp *inTime,
                                         AudioTimeStamp *outTime );

AudioQueueGetCurrentTime
获取音频队列的当前时间
OSStatus AudioQueueGetCurrentTime ( AudioQueueRef inAQ, 
                                    AudioQueueTimelineRef inTimeline, // 如果没有相关的时间线对象的话使用NULL
                                    AudioTimeStamp *outTimeStamp,  // 输出时为当前音频队列的时间。
                                    Boolean *outTimelineDiscontinuity ); // 出现中断时为true


执行渲染

AudioQueueSetOfflineRenderFormat
设置渲染模式和音频格式
OSStatus AudioQueueSetOfflineRenderFormat ( AudioQueueRef inAQ, 
                                            const AudioStreamBasicDescription *inFormat,
                                            const AudioChannelLayout *inLayout );

AudioQueueOfflineRender
输出音频给缓冲
OSStatus AudioQueueOfflineRender ( AudioQueueRef inAQ, 
                                   const AudioTimeStamp *inTimestamp,
                                   AudioQueueBufferRef ioBuffer, 
                                   UInt32 inNumberFrames );


回调函数
处理音频队列缓冲

AudioQueueInputCallback
在记录用的音频队列结束时填充瑾队列缓冲时由系统调用
typedef void (*AudioQueueInputCallback) ( void *inUserData, 
                                          AudioQueueRef inAQ, 
                                          AudioQueueBufferRef inBuffer, 
                                          const AudioTimeStamp *inStartTime, 
                                          UInt32 inNumberPacketDescriptions,
                                          const AudioStreamPacketDescription *inPacketDescs );

AudioQueueOutputCallback
在音频队列缓冲可被重新使用的时候由系统调用
typedef void (*AudioQueueOutputCallback) ( void *inUserData, 
                                           AudioQueueRef inAQ, 
                                           AudioQueueBufferRef inBuffer );
通常回调:
1.从文件或者其他缓冲中获取下一个音频数据来填充新的buffer
2.重新入列。使用AudioQueueEnqueueBuffer或者AudioQueueEnqueueBufferWithParameters


定义属性监听者

AudioQueuePropertyListenerProc
指定音频队列属性的值改变时由系统调用
typedef void (*AudioQueuePropertyListenerProc) ( void *inUserData, 
                                                 AudioQueueRef inAQ, 
                                                 AudioQueuePropertyID inID );
通过AudioQueueAddPropertyListener函数来安装此回调。


数据类型

AudioQueueBuffer
typedef struct AudioQueueBuffer { const UInt32 mAudioDataBytesCapacity;  // 大小
                                  void *const mAudioData;  // 拥有音频队列缓冲的音频数据
                                  UInt32 mAudioDataByteSize;  // 有效音频数据中mAudioData的大小。初始化为0
                                  void *mUserData;  // 上下文
                                  const UInt32 mPacketDescriptionCapacity; // 帧描述的最大数目 
                                  AudioStreamPacketDescription *const mPacketDescriptions;  // 缓冲的AudioStreamPacketDescription的数组
                                  UInt32 mPacketDescriptionCount; // 有效的数目} AudioQueueBuffer; 
typedef AudioQueueBuffer *AudioQueueBufferRef;

AudioQueueBufferRef
指向音频队列缓冲的指针

AudioQueueRef
代表音频队列的数据类型(OS X使用)

AudioQueueTimelineRef

AudioQueueLevelMeterState

AudioQueueParameterEvent

AudioQueueParameterID

AudioQueueParameterValue



常量

Audio Queue Property Identifiers
enum {
   kAudioQueueProperty_IsRunning               = 'aqrn', // 只读。表明当前音频队列是否正在播放。0表示停止
   kAudioQueueDeviceProperty_SampleRate        = 'aqsr', // 只读。采样率
   kAudioQueueDeviceProperty_NumberChannels    = 'aqdc', // 信道数
   kAudioQueueProperty_CurrentDevice           = 'aqcd', // CFStringRef.当前设备的UID
   kAudioQueueProperty_MagicCookie             = 'aqmc', 
   kAudioQueueProperty_MaximumOutputPacketSize = 'xops',
   kAudioQueueProperty_StreamDescription       = 'aqft',
   kAudioQueueProperty_ChannelLayout           = 'aqcl',
   kAudioQueueProperty_EnableLevelMetering     = 'aqme',
   kAudioQueueProperty_CurrentLevelMeter       = 'aqmv',
   kAudioQueueProperty_CurrentLevelMeterDB     = 'aqmd',
   kAudioQueueProperty_DecodeBufferSizeFrames  = 'dcbf',
   kAudioQueueProperty_ConverterError          = 'qcve'
};
typedef UInt32 AudioQueuePropertyID;

Audio Queue Parameter
enum {
   kAudioQueueParam_Volume          = 1
   kAudioQueueParam_PlayRate        = 2,
   kAudioQueueParam_Pitch           = 3,
   kAudioQueueParam_VolumeRampTime  = 4,
   kAudioQueueParam_Pan             = 13
};
typedef UInt32 AudioQueueParameterID;



















你可能感兴趣的:(iOS,学习)