[iOS]关于Audio Queue Audio Unit Audio Converter以及一个Music Visualizer Demo

事先声明:

  1. 能用傻瓜式的API还是去用傻瓜式吧,MediaPlayerFramework基本都能满足正常的音频播放需求。本文所涉及的内容用这些是实现不了的。

  2. 如果你指望本文是一个关于标题中提到的东西的教程,那我建议你还是关掉这个标签去翻文档吧,我看过的几个市面上容量仅有一篇博文那么多的关于这些方面的教程都没有什么实际意义,真的想学就踏踏实实去看文档,没有比文档对这方面讲的更清楚的了。除了文档建议补一下WWDC 2010 2011的相关Session,此外就是几个官方Sample。遇到问题了尤其是设计底层的API时,基本只有一个地方回答的比较靠谱,就是Apple Mailing List,另外StackOverflow也不错。本文仅仅回提供一些思路和链接,给后来的人指一个大概的方向。

以下进入正文:

记得小时候mp3刚开始流行那阵,那时候WINAMP称霸一时,虽然当时对音乐还没有什么感觉,但对WINAMP自带的众多可视化效果甚是着迷,直到今天终于有能力自己实现一个了,做了个Demo录了个视频发出来,效果较挫,嫌弃不好的就当听歌了,原曲来自niconico,sm18028378。youku视频如下:(也有u2b新浪

想实现视频中的效果有一种简单的方法和一种困难的方法

先说简单的:首先你要有音频的源文件(这不是废话么),压缩非压缩均可,格式要在iOS设备支持的范围内,另外就是对AudioQueue工作方式比较熟悉,如果你能成功用AudioQueue播放音频的话基本就成功一半了,其实从一定程度上来说AudioQueue也算是半傻瓜式的API,接下来就是获取level meter,这里提示点关键东西,自己看下就明白了:

  • AudioQueueGetProperty, kAudioQueueProperty_CurrentLevelMeterDB
  • Sample Code, Speak Here,MeterTable.h

这样就可以在每次OpenGL刷新的时候获取level meter值,
关于最后的OpenGL展示集中在后面讲

比较困难的方法就是用Audio Unit了,说困难其实不是API多么难用,而是越到底层我们做的工作就越多,真的要实现一个播放器的话我们就要人工处理音乐播放器的各种逻辑,时间控制,播放列表控制等等,实现功能以后还有一段很长的路要走。

进入正题,要求音频文件最好是liner PCM,也就是无损无压缩的,因为Audio Unit只能接受liner PCM的数据,如果是压缩格式还需要转换,转换格式可能就需要用到ExtAudioFile,或者AudioFile+AudioConverter,前者比较方便,后者相当复杂,尤其是要考虑对各种格式的兼容问题,需要很多判断,很多分支,对音频格式的知识要求也相当高,参考Sample Code,ConvertFile,这是一个控制台应用,代码很多,耐心看。如果格式的问题回避或解决了,就可以进入AudioUnit部分了,这部分其实也不难,基本就是设置一大堆属性,然后在回调函数里面提供数据就可以了,看官方文档会对你有很大帮助。至于获取level meter,可以让音频数据通过一次MultiChannleMixer Unit(这个AudioUnit的使用可以参考下Sample Code,Mixer Host),不过我们只用一个输入口,不真正mix,只是为了借用其kMultiChannelMixerParam_PostAveragePower,获取和kAudioQueueProperty_CurrentLevelMeterDB相同的东西,然后沿用MeterTable.h,转换成更直观的数据,最后显示出来。

如果做更复杂显示效果,可能就需要fft了,也就是将时域转换成频域,根据频率数据来实现比如做那种频谱图(Spectrometer),可参考的资料:

FFT部分:

  • 理论基础,随便找个教程看吧,这方面有很多
  • 实际一点的看下Create a FFT Analyzer这个系列的前半部分,这个系列从头到尾讲了下Mac上一个显示频谱的AudioUnit的实现,但是iOS目前(5.x.x)并不支持自制的Audio Unit,所以即使你照着这个教程做出来东西也不能用到iOS平台上,不过对实现过程还是能有一个比较清晰的认识的。另外该教程也对学习路线有一明确指引。

AudioUnit部分:

  • Sample Code, AurioTouch2, Aurio Touch;前者用了AccelerateFramework,这个Framework里面有个硬件加速版的FFT,以及一些iOS 5才出现的API,但仅仅FFT部分还是能支持到iOS 4的,至于后者是纯用CPU算FFT,可以兼容iOS 4之前的系统。

接下来是显示部分:

这部分实在没什么可说的,对OpenGL ES我还是个小白,现在只是用了一个现成的Particle System,在每次draw view之前根据level meter改变了下各点的尺寸,然后就没有然手了。我也跪求高手指导如何才能做出漂亮的效果。

最后说下我的学习路线:

  1. WWDC 2010 2011关于Audio的所有Session,对Audio部分有一个直观的认识,
  2. 官方文档,从Multimedia Programming Guide开始,所有关于Audio的分支文档,从表层到底层都有个了解,明确实现某种功能需要从哪一层入手,这部分内容很多,拖拖拉拉看至少4天吧。
  3. 期间参杂之前提到的所有Sample Code,文章,以及StackOverflow,Mailing list中的各种问题。

其实有一些关于CoreAudio的书也不错,但是太大部头了,短期纯为了实现功能看书太慢了。

本文Demo的代码我就不放出来了,没有太大价值,只能起到急功近利的效果,对学习没有什么帮助,另外就是代码都是拼凑了,结构混乱,还是不要拿出来让人喷了。

PS.题外话,关于Mac向Youku,新浪传视频,Mac下的转码软件基本都是个悲剧,前面用的视频是用Video Converter-Clone2Go这个转换的,这个软件虽然UI非常悲剧,但至少能设置下音频,视频的bit率,这对于要保证音频质量来说是必不可少的(youku没爆音真是很幸运)。另外就是对比新浪和youku,新浪的审核转码都比youku快不少,音质也明显比youku高,至于u2b各方面都非常好,也就是对于我们这些国内的人上传超费劲。

祝各位玩得愉快。

–以上–