陈斌彬的技术博客

Stay foolish,stay hungry

iOS-系统声音服务(System Sound Services)

系统声音服务(System Sound Services)提供了一个接口,用于播放不超过30秒的声音。它支持的文件格式有限,具体地说只有CAF、AIF和使用PCM或IMA/ADPCM数据的WAV文件。由于这些函数没有提供操纵声音和控制音量的功能,所以当你为多媒体或者游戏创建专门的配乐时,不要使用系统声音服务。

iOS使用系统声音服务来支持三种不同的通知:

  1. 声音:立刻播放一个简单的声音文件。如果手机被设置为静音,用户什么也听不到
  2. 提醒:播放一个声音文件,如果手机被设置为静音或震动,将通过震动提醒用户
  3. 震动:震动手机,而不考虑其他设置

要在项目中使用系统声音服务,首先要导入AudioToolbox.h

#import <AudioToolbox/AudioToolbox.h>

系统声音服务并非是通过类实现的,而是使用传统的C语言函数调用来触发播放操作。要播放音频,需要使用的两个函数是AudioServicesCreateSystemSoundID 和 AudioServicesPlaySystemSound。还需要声明一个类型为SystemSoundID的变量,它表示要使用的声音文件。下面演示了如何加载并播放声音:

- (IBAction)testSystemSound:(id)sender 
{
    SystemSoundID soundID;
    NSString *strSoundFile = [[NSBundle mainBundle] pathForResource:@"alertsound" ofType:@"wav"];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:strSoundFile],&soundID);
    AudioServicesPlaySystemSound(soundID);
}

其实这段代码应该这样来理解:

在写这个功能时最主要是两句代码:

SystemSoundID soundID;
AudioServicesPlaySystemSound(soundID);

然后考虑如何在中间加代码使得soundID被赋值:

AudioServicesCreateSystemSoundID((CFURLRef)fileURL,&myID);

第二个参数就是我们建立的SystemSoundID对象,但是这里要传地址(加&符号)。 第一个参数需要一个CFURLRef类型的url参数,要新建一个NSString来做桥接转换(bridge),而这个NSString的值,是通过NSBundle来返回音频文件路径:

NSString *strSoundFile = [[NSBundle mainBundle] pathForResource:@"alertsound" ofType:@"wav"];

mainBundle – 总地来说,mainBundle对应于应用程序文件归档或者应用程序的封包:一个以“.app”为扩展名并以应用程序名称为基本名的目录。

pathForResource方法 – 通过文件名和后缀名获取路径。

这句话调用pathForResource方法,来获取mainBundle下名为alertsound.wav的音频文件,然后将路径值返回。

对于提醒音来说,与系统声音之间的差别在于,如果手机处于静音状态,提醒音将自动触发震动。提醒音的设置和用法与系统声音相同,区别在于系统声音调用AudioServicesPlaySystemSound,而提醒音调用AudioServicesPlayAlertSound。

震动更容易实现,只需要调用AudioServicesPlaySystemSound,并将常量kSystemSoundID_Vibrate传递给它:

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

如果视图震动不支持震动的设备(如iPad2),将静默失败。因此将震动代码留在应用程序中不会有任何害处,而不管目标设备是什么。

Resource Reference