博客> 全民K歌iOS端AudioQueue实现耳返功能(项目详解)
全民K歌iOS端AudioQueue实现耳返功能(项目详解)
2018-05-24 15:44 评论:0 阅读:272 唐秦风
iOS开发 程序员 AudioQueue 音频技术

前言

最近一直在做iOS音频相关技术的项目,期间在官方及网上的资料文档也学习了很多,当然,iOS平台中音频相关技术还是有很多方面的,然后以AudioUnit对耳返功能实现为例子来总结一下自己最近的收获,同时分享给大家。

技术点使用场景:

唱吧、全民K歌类似音乐项目中的,原唱和伴唱切换功能。
•这个当初实现的时候,差点搞残自己了。弄出来了,也拿来给大家做一个分享。我们团队面试经常拿这个问开发者。大家有兴趣可以学一下。
•如果有更好的实现策略和我讨论或者想拿源码和思维导图资料的, 请联系我时,备注一下AudioUnit耳返功能实现 
•加我技术交流QQ群:686183764

AudioUnit耳返功能实现思路

这边使用AudioUnit录音,AudioQueue播放

1.创建AudioUnit对象,并初始化设置参数等

2.创建AudioQueue对象,初始化并设置参数

3.在AudioUnit回调方法中获取到采集到的数据,并将获取到的数据喂给AudioQueue的容器中,并给它播放

AudioUnit简介

AudioUnit这个名字取得还是比较形象的,它的主体就是一系列的unit,不同unit能够实现不同的功能,将一个或多个unit添加到AUGraph(Audio Processing Graph)中,并建立unit之间的连接,音频数据顺次通过各个节点即可完成我们最终需求。

 Enter your image description here:

代码开始

1.使用AVAudioSession获取音频录制播放权限,并激活

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil]; 

2.创建AudioUnit

AudioComponentInstanceNew(_audioComponment, &_audioUint);

3.设置AudioUint

AudioUnitSetProperty(_audioUint, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flagOne, sizeof(flagOne)); AudioUnitSetProperty(_audioUint, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &asbd, sizeof(asbd)); AudioUnitSetProperty(_audioUint, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global

4.初始化/Start

AudioUnitInitialize(_audioUint);
AudioOutputUnitStart(_audioUint);

5.创建AudioQueue实例

AudioQueueNewOutput(&_asbd, BufferCallback, (__bridge void * _Nullable)(self), nil, nil, 0, &_audioQueue);

6.初始化音频缓冲区,这3个音频缓冲区地址不会改变,往里面填数据的时候,只是里面的数据变化而已(官方文档表明地址不可改变)

//初始化音频缓冲区 for (int i = 0; i < 3 xss=removed xss=removed>mAudioData, 0, 2048); } 

7.AudioUnit回调中处理数据

AudioUnitRender(vc->_audioUint, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);

使用该函数来讲数据填充到我们创建的bufferList中 便于后续处理

void *data = malloc(bufferList.mBuffers[0].mDataByteSize); memcpy(data, bufferList.mBuffers[0].mData, bufferList.mBuffers[0].mDataByteSize); //play AudioQueueBufferRef audioBuffer = NULL; if (vc->_index == 2) { vc->_index = 0; } audioBuffer = vc->_audioQueueBuffers[vc->_index]; vc->_index ++; audioBuffer->mAudioDataByteSize = bufferList.mBuffers[0].mDataByteSize; memset(audioBuffer->mAudioData, 0, bufferList.mBuffers[0].mDataByteSize); memcpy(audioBuffer->mAudioData, data, bufferList.mBuffers[0].mDataByteSize); //将数据压入AudioQueue播放缓存中 AudioQueueEnqueueBuffer(vc->_audioQueue, audioBuffer, 0, NULL); free(data); 

8.AudioQueue的回调

项目代码获取

具体实现步骤,如下实现步骤 有步骤讲解视频以及资料.因为简书文章没有地方放.大家可以加一下我的群获取一下。在群里讨论一下音视频技术这一块。 QQ群号:686183764.

收藏
0
sina weixin mail 回到顶部