AudioQueue

本文详细探讨了iOS平台上的AudioQueue服务,包括其工作原理、使用场景和核心API,帮助开发者深入了解音频处理技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//========================= 播放 ==============================

// 所属类 AudioPlayer
AudioQueueRef mQueue;
AudioStreamBasicDescription mDataFormat;

//创建AudioQueue
AudioQueueNewOutput(&mDataFormat, AQBufferCallback, (__bridge void *)self,  NULL, NULL, 0, &mQueue);

//生成若干 mBuffers (AudioQueueBufferRef)
for (int i = 0; i < 3; ++i) 
{
    AudioQueueAllocateBufferWithPacketDescriptions(mQueue, bufferByteSize, 0, &mBuffers[i]);
}


//回调
AudioQueueNewOutput(&mDataFormat, AQBufferCallback, (__bridge void *)self,  NULL, NULL, 0, &mQueue);

void AQBufferCallback(void *                    inUserData,
                                AudioQueueRef            inAQ,
                                AudioQueueBufferRef        inBuffer)
{
    //d 是要播放的数据(磁盘读出来的,或者其他地方来的,反正是要播放数据来源)
    memcpy(inBuffer->mAudioData,[d bytes], inBuffer->mAudioDataByteSize);//取缓存器中的音频数据
    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);//缓冲器重新放入缓存队列中
}



//========================= 录制 ==============================

// 所属类 AQRecorder
AudioQueueRef mQueue;
AudioStreamBasicDescription	mRecordFormat;

//创建AudioQueue
AudioQueueNewInput(&mRecordFormat, MyInputBufferHandler, (__bridge void *)self,NULL, NULL, 0 , &mQueue);

//回调
static void MyInputBufferHandler(	void *inUserData,//录音回调函数
										AudioQueueRef inAQ,
										AudioQueueBufferRef	inBuffer,// newly filled by the recording audio queue, containing the new audio data
										const AudioTimeStamp *inStartTime,
										UInt32 inNumPackets,
										const AudioStreamPacketDescription* inPacketDesc)

{
	AQRecorder *aqr = (__bridge AQRecorder *)inUserData;

    //将缓冲器中的数据写入磁盘
    [aqr.delegate captureData:(const char *)inBuffer->mAudioData size:inBuffer->mAudioDataByteSize];
    
    //重复利用缓冲器,将缓冲器加入缓存队列
    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}


 

 

参考:https://blog.youkuaiyun.com/midfar/article/details/7233454

### 使用 AudioQueue 进行音频录制 Audio Queue Services 提供了一种简单而灵活的方法来处理音频输入和输出。对于录音功能而言,开发者可以利用 `AudioQueue` 来捕获来自麦克风或其他声源的数据并保存到文件中。 为了实现这一目标,在应用程序启动时需创建一个或多个队列对象,并配置其属性如采样率、声道数等参数[^1]。下面是一个简单的例子展示如何设置以及管理这些资源: #### 初始化录音环境 ```objc #import <AVFoundation/AVFoundation.h> // 定义回调函数原型声明 void MyInputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, const AudioStreamPacketDescription *inPacketDescs); @interface Recorder : NSObject { AudioQueueRef audioQueue; } @end @implementation Recorder - (BOOL)setupAudioFormat:(AudioStreamBasicDescription *)format{ memset(format, 0, sizeof(*format)); format->mSampleRate = kSampleRate; // 设置样本速率 format->mFormatID = kAudioFormatLinearPCM; // PCM 编码方式 format->mFramesPerPacket = 1; format->mChannelsPerFrame = 1; // 单声道 if (format->mFormatID == kAudioFormatLinearPCM){ format->mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); format->mBytesPerPacket = sizeof(AudioUnitSampleType); format->mBytesPerFrame = sizeof(AudioUnitSampleType); format->mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; } return YES; } - (BOOL)startRecordingToFileAtPath:(NSString*)path error:(NSError**)outError { OSStatus status; AudioStreamBasicDescription recordFormat; BOOL success = [self setupAudioFormat:&recordFormat]; if (!success || outError != nil && *outError != nil) {return NO;} status = AudioQueueNewInput(&recordFormat, MyInputCallback, (__bridge void *)(self), NULL, NULL, 0, &audioQueue); if(status != noErr){ /* 错误处理 */ } // 准备缓冲区... for(int i=0;i<3;++i){ AudioQueueBufferRef buffer; status = AudioQueueAllocateBuffer(audioQueue, 4096,&buffer); if(status==noErr){ MyEnqueueBuffer(buffer); }else{/* 处理错误 */} } // 启动队列 status = AudioQueueStart(audioQueue,NULL); if(status!=noErr){/* 错误处理 */} return true; } @end ``` 此段代码展示了初始化过程的一部分,包括定义必要的变量、设定音频格式、分配内存给缓冲区并将它们加入到播放列表里去等待被填充数据。当一切准备就绪之后调用 `AudioQueueStart()` 方法正式开启录音流程。 需要注意的是实际开发过程中还需要考虑更多细节比如权限申请、UI交互逻辑设计等方面的内容。上述仅作为基础框架提供参考价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值