Ray Wenderlich:分享iPhone开发者需掌握的音频内容

在面向iPhone开发游戏之前我对音频格式真的非常陌生。我只知道.WAVs和.MP3之间的区别,但是我却怎么都说不出.AAC或.CAF到底是什么,或者在Mac上转换音频文件的最佳方法是什么。

后来我发现如果想要在iPhone上开发游戏,我们就必须真正理解文件,数据格式,文件间的转换,录音以及API等基本元素。

sweet_sound(from dryicons.com)

sweet_sound(from dryicons.com)

文件格式和数据格式

我们必须清楚每个音频文件都是由两部分内容所构成:它的文件格式(或者音频容器)以及它的数据格式(或者音频编码)。

文件格式(或音频容器)是用于形容文件本身的格式。我们可以通过多种不同的方法为真正的音频数据编码。例如CAF文件便是一种文件格式,它能够包含MP3格式,线性PCM以及其它数据格式的音频。

数据格式(或音频编码)

我们将从音频编码开始阐述(而不是文件格式),因为编码是最重要的环节。

以下是iPhone所支持的数据格式及其相关描述:

AAC:AAC是指“高级音频编码”,可以说它MP3格式的延续。你可能会想这种格式将压缩最初的声音而保存在磁盘中,所以会降低原先声音的质量。但是通常情况下我们很难注意到质量的降低,并且这主要是取决于我们所设置的比特率。实际上AAC的压缩做得比MP3好多了,特别是在比特率低于每秒128千比特的情况下。

HE-AAC:HE-AAC是AAC的超集,HE表示“高效率”。HE-AAC是对于低比特率音频(如流式音频)的优化。

AMR:AMR代表“自适应多速率”,是语音优化的另一种编码优化格式,能够突出极低比特率音频。

ALAC:同样也被称为“Apple Lossless”,它是一种可以不破坏质量而压缩音频的编码。实际上它大概会压缩原始数据的40-60%。再加上算法是经过精心设计的,所以我们可以以较快的速度解压数据,这非常适合像iPod或iPhone等设备。

iLBC:这是另一种优化语音的编码,有益于IP语音和流媒体格式。

IMA4:这是一种压缩格式,将对16位体的音频文件进行4:1的压缩。这是面向iPhone设备的一种重要编码。

线性PCM:这是表示线性脉冲编码调制,主要是描写用于将模拟声音数据转换成数字格式的技术。简单地说也就是未压缩的数据。因为数据是未压缩的,所以我们便可以最快速地播放出音频,而如果空间不是问题的话这便是iPhone音频的优先代码选择。

μ-law和a-law:这是两种交替式编码,能够将模拟数据转换成数字格式,但是比起线性PCM拥有更强的语音优化效果。

MP3:这是我们最熟悉也是最喜欢的一种格式。这么多年以来MP3仍是最受欢迎的一种格式,而iPhone也支持这种格式。

所以我们该使用哪种格式?

在这一大串列表中我们必须选出几个优选编码格式。为了做出选择我们首先需要清楚:

我们可以无需压缩或简单压缩而同时播放线性PCM,IMA4等格式并且不会出现任何问题。

而对于更加高级的压缩方法如AAC,MP3以及ALAC,iPhone也拥有相关硬件能够帮助我们快速压缩这些数据——但是问题在于它一次只能处理一种文件。所以如果你一次希望播放2种以上的编码,你就不得不对其进行压缩,而这将耗费更多时间。

为了选择合适的数据格式,你需要遵循以下规则:

如果空间不是问题的话,我们便可以使用线性PCM对任何内容进行编码。这不仅是播放音频最快速的方法,并且你也可以同时播放多种声音且不会遭遇任何CPU资源问题。

如果空间是问题所在的话,你便可以使用AAC编码去播放背景音乐而使用IMA4编码去制造音效。

线性PCM的各种变体

关于线性PCM最需要注意的一点便是它应该算是iPhone首选的未压缩数据格式。基于数据的储存方式线性PCM具有多种变体。我们可以根据大端字节序或小端字节序,浮点数或整数以及不同位体去保存数据。

在此我们需要清楚的是在iPhone中线性PCM的优选变体是小端字节序整数16位体,或简称为LEI16。同时这也不同于Mac OSX中的优选变体。因为我们总是在Mac上创造音频文件,所以我们最好能够仔细检查文件并将其转换成iPhone中的优选格式。

文件格式(或音频容器)

iPhone支持许多文件格式,包括MPEG-1(.mp3),MPEG-2 ADTS(.aac),AIFF,CAF以及WAVE。但是通常情况下我们都会选择CAF,因为它能够同时包含所有iPhone所支持的编码,并且它也是iPhone中的优先文件格式选择。

比特率

在此我们必须强调音频编码中一个非常重要的术语:比特率。

比特率是指一个音频文件所占有的每秒字节数。像AAC或MP3等编码便能够指定字节数而压缩音频文件。当你降低每秒钟的字节数时,你同时也在降低音频的质量。

你可以根据特定的音频文件选择比特率——尝试不同的比特率并判断哪一种最能够匹配文件规格和音频质量。如果你的文件主要与语音有关,你便可以选择较低的比特率。

以下是一些较常见的比特率:

每秒32千比特率:调频广播质量

每秒48千比特率:较长的语音博客中常见的频率

每秒64千比特率:标准长度的语音博客中常见的频率

每秒96千比特率:调频收音机的质量

每秒128千比特率:MP3音乐最常见的比特率

每秒160千比特率:音乐家和敏感听众的优先选择

每秒192千比特率:数字无线电广播的质量

每秒320千比特率:和CD的质量没两样了

每秒500千至1411千比特率:无失真的音频编码,如线性PCM

采样频率

我们最后需要提到的一个术语便是:采样频率。

当我们将模拟信号转换成数字格式时,采样频率是指我们多长时间抽取一次声波去创造数字信号。

通常情况下44100赫兹便是最常用的采样频率,因为这与CD音频的频率相同。

转换和记录

这是iPhone开发者需要掌握的制作音频要素的第二部分。

在上文中我提到了文件格式与数据格式间的区别,以及iPhone所支持的各种格式。而接下来我将说说如何在这两种格式间进行转换。

Afplay,AFConvert以及AFInfo

在Mac上转换音频文件非常简单,因为Mac中有三个内置命令行工具:afplay,afconvert以及afinfo。

最容易使用的便是afplay——你只要通过终端输入音频文件名它便能够将其播放出来。当你想要将文件压缩成各种比特率以对比效果时这种工具便非常方便。

接下来便是afinfo——当你输入音频文件名时它将呈现出文件格式,数据格式,比特率以及其它有用的信息,如下:

afinfo pew-pew-lei.caf
File:           pew-pew-lei.caf
File type ID:   caff
Data format:     1 ch,  44100 Hz, ‘lpcm’ (0x0000000C)
16-bit little-endian signed integer no channel layout.
estimated duration: 0.560 sec
audio bytes: 49408
audio packets: 24704
audio 24704 valid frames + 0 priming + 0 remainder = 24704
bit rate: 705600 bits per second
packet size upper bound: 2
audio data file offset: 4096
optimized
sound check:
approximate duration in seconds          0.56
—-

从以上代码中我们可以看出这个文件拥有一个CAF文件类型,一个16位体小端字节序带符号整数数据格式(LEI16),一个44100赫兹的样本频率以及每秒705600的比特率。

最后我们来说说最实用的工具:afconvert。afconvert也是最容易使用的一种,我们只需要发出如下命令行便可:

afconvert -d [out data format] -f [out file format] [in file] [out file]

为了将文件转换成iPhone首选的未压缩音频编码(提示:小端字节序整数16位线性PCM变体,也就是LEI16)以及首选的文件格式(提示:核心音频文件格式,也就是CAFF),你就需要发出如下命令行:

afconvert -d LEI16 -f ‘caff’ input_file.xxx output_file.caf

需要注意的是我并未在此指出输入文件的扩展名,因为afconvert已经能够帮助我们判别任何音频文件类型并进行适当的转换,所以它也算是带有音频文件格式的音频数据格式。

另外一点需要注意的便是:你可以在输入/输出文件前添加-b选项以设置比特率。举个例子来说吧,在此我将文件保存为每秒32千比特率,随后又改为每秒128千比特率:

afconvert -d aac -f ‘caff’ -b 131072 background-music-lei.caf test_128.caf
afconvert -d aac -f ‘caff’ -b 32768 background-music-lei.caf test_32.caf

在Mac上记录音频

以下我将列出在Mac上制作应用音乐和声音的一些好方法。

首先是GarageBand。GarageBand能够帮助我们更容易组合一些预制的乐器声,如鼓声,吉他声等,并如此创作出一首简单的音乐。而如果你自己懂音乐的话你便可以将自己的演奏录下来并创造出一些更酷的作品。

Garage Band Full(from raywenderlich)

Garage Band Full(from raywenderlich)

我发现“使用内置软件工具”是最有效的一种方法。

而当我们记录下满意的歌曲后我们需要将其传送到iTunes上,然后“记录在Finder(游戏邦注:Mac OS和Mac OS X中默认的应用程式,能让使用者管理档案,文件,磁盘,网络,以及启动其他的应用程式)”中以抓取文件方便今后的使用。

我发现GarageBand并不能记录下最简单的音效。所以我便转向了免费的音频程序Audacity(游戏邦注:一款跨平台、免费开源的录音、编辑声音编辑器)。你可以将其插在麦克风上然后记录下你的声音,并轻松地将其保存下来。

Audacity(from raywenderlich)

Audacity(from raywenderlich)

不要忘记当你录下自己的声音时它们将被保存为16位体大端字节序带符号整数(BEI16),所以在整合到应用前一定要将其转换为LEI16。

如果你不懂音乐的话也可以在The Freesound Project网站的创作共用许可版块中找到一些合适的声音授权,或者也可以聘请专业的音乐人士帮忙!

使用编程方式播放音频

这是iPhone开发者需要掌握的制作音频要素的第三部分。

之前我们已经谈到了文件和数据格式间的区别以及如何在Mac上转换并记录音频。现在我们将尝试着在手机上播放音频。

在Mac上播放音频的方法有很多,包括System Sound Services,AVAudioPlayer,Audio Queue Service以及OpenAL。如果没有外部支持库的话,最简单的方法应该是System Sound Services和AVAudioPlayer——所以让我们开始讨论你何时想要(或不想要)使用哪种方法以及如何使用它们。

System Sound Services

System Sound Services为我们提供了一种非常简单的方法以播放音频文件。而我们只需要如下进行操作:

NSString *pewPewPath = [[NSBundle mainBundle]
pathForResource:@”pew-pew-lei” ofType:@”caf”];
NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath];
AudioServicesCreateSystemSoundID((CFURLRef)pewPewURL, &_pewPewSound);
AudioServicesPlaySystemSound(_pewPewSound);

没有什么比这个还简单了。但是这一方法也存在许多缺陷:

它只支持音频数据格式的线性PCM或IMA4.

它只支持音频文件格式CAF,AIF或WAV。

声音的长度只能压缩在30秒以内。

AVAudioPlayer

如果你想要以一个AAC或MP3格式的音频文件作为背景音乐的话你又该怎么做?另外一种简单的方法便是使用AVAudioPlayer类播放音乐。很大程度上看来这也是一种非常简单的方法:

NSError *error;
_backgroundMusicPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:backgroundMusicURL error:&error];
[_backgroundMusicPlayer prepareToPlay];
[_backgroundMusicPlayer play];

而AVAudioPlayer的缺陷则是速度非常慢。如果你按压一个按钮并尝试着使用AVAudioPlayer去触发一个声音,此时便会出现一个非常明显的延迟。而如果你不在乎这种延迟的话(就像启动背景音乐),AVAudioPlayer便是一种非常合适的选择。

同时我们还需牢记:

1.如果你正在播放背景音乐,请一定要检查看看是否已经播放了其它音频,从而确保不会同时运行两个层面的音乐!

2.如果一个电话接入而用户选择了“拒绝”后,你需要默认设置你的AVAudioPlayer为停止。你可以通过再次登录AVAudioPlayerDelegate而重新开启AVAudioPlayer并在audioPlayerEndInterruption方法中再次播放音乐。

示例代码

我组合了一些示例代码以呈现System Sound Services和AVAudioPlayer的使用。这些代码不仅能够演示出应用程序界面,同时也拥有一些特别的节拍和超酷的太空氛围。

OpenAL

如果你正在编写一款游戏或应用并希望在较低延迟性的前提下通过低细粒度去控制音频,那么你便不会使用上述的方法。相反地,你可能会选择使用OpenAL这个iPhone支持的跨平台音频库。

OpenAL其实并不好理解。但是幸运的是Alex Restrepo已经在gehacktes.net网站上为我们呈现出一个非常棒的例子,并使用OpenAL创造了一个出色的声音引擎库,所以我们便能够在自己的项目中使用这一引擎库,或以它作为参考。

还有一个选择便是Cocos2D游戏库,其中包含了一个非常容易使用的声音引擎能够创造出噼啪声的音效。

总结

以上这些便是我对于iPhone音频程序设计的相关内容,但是需要注意的是我只触及一些基础元素而未进行深入研究。我希望本文能够为那些刚刚接触音频理念的开发者提供一些帮助。

游戏邦注:原文发表于2010年2月5日,所涉事件和数据均以当时为准。

via:游戏邦/gamerboom

评论已关闭

感谢支持199IT
我们致力为中国互联网研究和咨询及IT行业数据专业人员和决策者提供一个数据共享平台。

要继续访问我们的网站,只需关闭您的广告拦截器并刷新页面。
滚动到顶部