870920 Menu

AudioDeviceManager详解

AudioDeviceManager可称为JUCE音频系统中最重要的功能类。该类用来管理音频驱动和MIDI接口(二者通称为音频设备),实现播放、录音、MIDI进出等重要功能。

通常,应创建本类的全局实例,并通过手工代码或AudioDeviceSelectorComponent设置当前所用的音频驱动、音频进出端口、采样率、缓冲大小和MIDI进出端口。当所选择的设备发生变化时,本类的实例可自动关联所选的新设备,并且不会中断有关回调函数的持续执行。当前所有设置可保存为XmlElement对象,并基于所保存的XML数据重新加载先前的设置,这一点非常实用。

本类继承自ChangeBroadcaster可变生成类,因此,本类的对象可调用addChangeListener()函数绑定一到多个ChangeListener对象,当设置有变化时,所绑定的ChangeListener对象可对本类产生的消息进行处理。

AudioDeviceManager的使用流程
创建对象,调用initialise()初始化之,调用addAudioCallback()添加AudioIODeviceCallback音频回调类的派生类对象,使用该对象处理进出的音频数据,实现音频播放或音频录音等功能。如需处理MIDI输入端口的数据,则调用addMidiInputCallback()添加MidiInputCallback对象,利用该对象处理MidiInput类所收到的MIDI消息。

AudioDeviceManager类的构造函数无参,其主要成员函数有:
 initialise () 初始化,使用本类对象之前必须调用此函数
 createStateXml () 将当前所有设置保存为XmlElement
 getAudioDeviceSetup () 返回当前所使用的设备属性
 setAudioDeviceSetup () 改变设备或改变当前设备的设置
 getCurrentAudioDevice () 返回当前处于激活状态的AudioIODevice
 getCurrentAudioDeviceType () 返回当前所使用的音频驱动的类型
 getCurrentDeviceTypeObject () 返回当前处于激活状态的AudioIODeviceType
 setCurrentAudioDeviceType () 设置当前所用的音频设备的类型
 closeAudioDevice () 关闭当前打开的设备
 restartLastAudioDevice () 重新打开最后一次所用的音频设备
 addAudioCallback () 添加AudioIODeviceCallback
 removeAudioCallback () 移除先前添加的AudioIODeviceCallback
 getCpuUsage () 返回CPU占用率
 setMidiInputEnabled () 开启或禁用MIDI输入设备
 isMidiInputEnabled () 如果给定的MIDI输入设备已启用,则返回true
 addMidiInputCallback () 添加MidiInputCallback
 removeMidiInputCallback () 移除已添加的MidiInputCallback
 setDefaultMidiOutput () 设置默认的MIDI输出设备
 getDefaultMidiOutputName () 返回默认的MIDI输出设备的名称
 getDefaultMidiOutput () 返回当前默认的MIDI输出设备
 getAvailableDeviceTypes () 返回当前所有可用的AudioIODeviceType
 createAudioDeviceTypes () 给出AudioIODeviceType,创建可用的类型
 playTestSound () 播放一声测试音,专用于音频设备设置组件
 enableInputLevelMeasurement () 开启测量输入电平,专用于音频设备设置组件
 getCurrentInputLevel () 返回当前的输入电平

在此给出一个使用本类的小技巧。笔者(Running)曾开发的一款软件,某些用户在非常罕见、毫无规律的情况下,会出现音频播放假死的现象。多方查找原因未果,调试时甚至无法重现。哥的心都要碎了……折磨许久之后,一个偶然的机会,尝试使用本类,非常简单的几行代码,问题解决。感慨之余,心戚戚然。特发布于此:

示例第一行所声明的结构体对象为:

AudioDeviceManager::AudioDeviceSetup

AudioDeviceManager类的initialise()初始化(最后一个参数)、setAudioDeviceSetup()改变或设置当前所用的音频设备、getAudioDeviceSetup()获取当前所用设备的属性等3个函数,均与当前所用设备的属性有关,Jules使用了一个结构体来表示设备的各类属性,该结构体为AudioDeviceManager::AudioDeviceSetup,嵌套于AudioDeviceManager类中。

除构造函数与“==”比较运算符之外,AudioDeviceSetup无其他成员函数,其public数据成员有:
 outputDeviceName 音频设备的输出名称。空字符串代表默认设备。String类型
 inputDeviceName 音频设备的输入名称。空字符串代表默认设备。String类型
 sampleRate 当前设备的采样率。double类型
 bufferSize 缓冲大小(采样数)。 输入和输出使用相同大小。int类型
 inputChannels 当前激活的输入通道。 BigInteger类型
 useDefaultInputChannels true则忽略inputChannels数组,使用默认的输入通道
 outputChannels 当前激活的输出通道。BigInteger类型
 useDefaultOutputChannels true则忽略outputChannels数组,使用默认的输出通道