870920 Menu

JUCE音频核心— AudioSource类系

AudioSource是一个抽象基类,其派生类构成了JUCE音频系统“两大支柱”中的其一(另一支柱为AudioProcessor类群)。AudioSource类的派生层次为:

  • ChannelRemappingAudioSource 通道重映射
  • IIRFilterAudioSource IIR滤波处理
  • MixerAudioSource 音频混合
  • ResamplingAudioSource 重采样处理
  • ReverbAudioSource 混响处理
  • ToneGeneratorAudioSource 生成有音高的正弦波(音调)
  • PositionableAudioSource 可定位的音频来源
    • AudioFormatReaderSource 音频格式读取器
    • AudioTransportSource 音频传输(中转)
    • BufferingAudioSource 可缓冲的AudioSource
表 3 9 AudioSource类系层次图

AudioSource类系的最根本作用是生成各种各样、连续的音频流,所生成的数据供音频系统的下一个环节使用。该类系的数据来源只有两种途径,一是内部运算,从无到有的生成音频数据,二是通过AudioFormatReaderSource读取磁盘文件、音频CD或InputStream输入流中的音频数据。

一个AudioSource对象有3种状态:“准备生成”、“开始生成”和“结束生成”。在开始产生音频流之前,需先进行准备,而后开始生成。工作完成后,及时“结束生成”。AudioSource类仅有的3个纯虚函数恰好代表了该类的完整工作流程和3种不同的状态:

  1. prepareToPlay() 准备产生音频流,设置采样率。可在此函数中准备所需、分配内存
  2. getNextAudioBlock() 产生音频流,此函数被调用方反复调用,以产生连续不断的音频流
  3. releaseResources() 停止产生音频流。可在此函数中清理并释放不再需要的内存

AudioSource及其所有派生类,均遵循这一流程,即:调用方需要本类提供音频流时,首先让本类对象调用prepareToPlay()做好准备。而后让本类对象不间断的调用getNextAudioBlock()产生连续不断的音频流。不再需要音频流时,调用方让本类对象调用releaseResources()结束工作。

核心函数getNextAudioBlock()用于产生连续不断的音频流,其形参为音频来源通道信息结构体的引用型对象(AudioSourceChannelInfo)。该结构体用来保存AudioSource所产生的音频数据,事实上,正是通过该结构体将AudioSource所产生的音频数据保存到AudioSampleBuffer中(缓冲对象即是此结构体的构造1参)。

更直观的理解:getNextAudioBlock()函数其实应该命名为fillNextAudioBlock(),它的作用就是填充该函数的1参。因此,要在该函数中完成所需的功能,需针对该函数的1参做文章。一个混合音频采样(混合式输出)的典型示例为:

AudioSourceChannelInfo有3个构造函数和1个成员函数:(略)。

AudioSourceChannelInfo的public数据成员:(略)。

由上可知:AudioSource所生成的连续音频流,最终保存在AudioSampleBuffer对象中,而缓冲中的数据位于数组的数组中(二维数组),每个子数组保存某个音频通道的一批采样,每个采样均为float数值。保存过程中,使用了一个中间层的辅助类,即所有AudioSource类最核心的工作函数getNextAudioBlock()的参数:AudioSourceChannelInfo结构体对象。该结构体的构造参数即是AudioSampleBuffer,即保存AudioSource所产生的音频数据的最底层容器。

AudioSource各派生类功能详解及示例代码请参见后续文章。