AudioUnit是什么? 它是ios端进行音视频采集的框架,最全,最屌的!但是缺点就是学习成本大,但是大没关系,既然您已经看到这里,想必就是想搞音视频,这点小的困难应该能克服的。
我这边就先看怎么用,用完在讲讲具体的是什么东西比较好,这也是我一向学习新东西的习惯和方法,这个世界上的理论很多,真理也很多,我们可以选择接收和不接受,如果你看看下面的实现结果如果不满意就可以直接关闭,如果有兴趣可以欢迎一直看下去咯!
废话不多说了,我也没时间了,直接介绍:
操作流程:
no1: 描述音频元件: kAudioUnitType_Output。kAudioUnitSubType_RemoteIO/kAudioUnitManufacturerApple 这个知道就行,不需要了解
no2: 使用AudioComponentFindNext : 这个就当作是生产AudioUnit 的工厂
no3 : AudioComponentInstanceNew: 顾名思义,就是Audio Unit 的实例
no4: AudioUnitSetProperty函数为录制和回放开启IO
no5: 使用 AudioStreamBasicDescription 结构体描述音频格式,并使用AudioUnitSetProperty进行设置
no6: 使用 AudioUnitSetProperty 设置音频录制与放播的回调函数
no7: 分配缓冲区
no8: 初始化Audio Unit
no9: 启动Audio Unit
理论:
Core Audio
数字音频处理的基础设施,它是应用程序用来处理音频的一组软件框架,所有关于iOS音频开发的接口都是由Core Audio来提供或者经过它提供的接口来进行封装的。Apple官方对Core Audio的框架分层图示如下:
OutputOnlyWithRenderCallback_2x.png
较复杂的构建
输入端有两路音频流,都是通过rendercallback方式抓取数据,其中一路音频流直接给入到Mixer Unit中,另一路先经过EQ Unit处理后给入到Mixer Unit中,
OutputOnlyWithRenderCallbackExtended_2x.png
Tips
1. 多线程及内存管理
尽可能的避免render callback方法内做加锁及处理耗时较高的操作,这样可以最大限度的提升实时性能,如果播放数据或者采集数据存在不同线程读写的情况,必需要加锁保护,推荐pthread相关lock方法性能比其它锁要高
音频的输入输出一般都是一个持续的过程,在采集与播放的callback中,应尽量复用buffer及避免多次buffer拷贝,而不是每次回调都重新申请和释放,在适当的位置加上@autoreleasepool避免长时间运行内存不断上涨
2. 格式
Core Audio Type中定义了AudioStreamBasicDescription结构,Audio Unit及其它很多音频API对格式的配置都需要用到它,根据需要将该结构的信息填充正确,下面是44.1K,stereo,16bit的填充例子
audioDescription.mSampleRate = 44100;
audioDescription.mChannelsPerFrame = 2;
audioDescription.mBitsPerChannel = 16;
audioDescription.mFramesPerPacket = 1;
audioDescription.mFormatID = kAudioFormatLinearPCM;
audioDescription.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioDescription.mBytesPerFrame = (audioDescription.mBitsPerChannel/8) * audioDescription.mChannelsPerFrame;
audioDescription.mBytesPerPacket = audioDescription.mBytesPerFrame ;
苹果官方建议在整个Audio Processing Graph或者Unit之间尽量以相同的音频格式流通,尽管Audio Unit的输入输出可以不同。另外在Unit之间输入输出连接点要保持一致。
3. 音质
在使用过程中,Audio Unit的format是可以动态改变的,但存在一种情况,Unit在销毁前最好恢复到默认创建时的format,否则在销毁后再重建Unit后,可能出现播放音质变差(音量变小,声音粗糙)的情况。
在使用VoiceProcessing I/O Unit过程,遇到在有些iphone上开启扬声器后,Unit从Mic采集过来的数据为空或者噪音的情况,从APP STORE中下载了其它的VOIP类型的APP也同样存在该问题,后来将AudioUnitSubType改成RemoteIO类型后,问题消失,怀疑苹果在VoiceProcessing Unit上对回声消除功能的处理上有bug
4. AudioSession
既然使用了音频特性,就会用到AudioSession,随着功能需求跟进,与它相关的问题也瞒多的,比如路由管理(听筒扬声器、线控耳机、蓝牙耳机),打断处理(interruption、iphone call)等,这里以Audio Unit为主,就不对它进行详细描述了,需要注意的是
音频的路由变更(用户挺拔耳机,或者代码调用强制切换)涉及到iOS硬件上输入和输出设备的改变,I/O类型Unit的采集和播放线程在切换过程中会阻塞一定时间(200ms左右),如果是语音对讲类对实时性要求较高的应用场景要考虑丢包策略。
在APP前台工作时,iPhone来电或者用户主动切换到其它音频类APP后,要及时处理音频的打断机制,在恰当的时机停止及恢复Unit的工作,由于iOS平台对资源的独占方式,iPhone在通话等操作时,APP中的Unit是无法初始化或者继续工作的。
作者:MasonFu
链接:http://www.jianshu.com/p/5d18180c69b8
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。