ChannelRemappingAudioSource

整个AudioSource类系的本质是产生新的音频流,所产生的音频流数据保存到getNextAudioBlock()的引用型参数中。这些类所产生的音频流有两个来源:一是从无到有,凭空产生。比如ToneGeneratorAudioSource,不依赖任何外部数据,自己创建出全新的正弦波音频流。二是基于另一个或另一些AudioSource所产生的音频流,进一步加工处理,而后产生新的音频流。比如MixerAudioSource,另一些AudioSource添加给该类后,该类进行混合,而后产生混合后的全新音频流。

第二种情况(即基于另外的AudioSource产生音频流)又可分为两个子情况:一是本类产生新的音频流时,不改变来源所产生的音频流。比如MixerAudioSource,它只负责混合,不修改也无法修改每个来源所产生的原始数据。AudioSource绝大多数派生类均属于这种情况。二是本类产生新的音频流时,可以修改来源所产生的原始数据。比如ResamplingAudioSource(改变采样率)和ChannelRemappingAudioSource(通道重映射)。这个情况,又可以分为两个子子情况:1、修改来源数据后直接输出;2、不仅可以修改来源数据,还可以进一步处理,基于修改后的来源数据产生新的输出数据。归纳一下,其实共4种情况:

  1. 从无到有,凭空产生新的音频流,不依赖于其他AudioSource
  2. 基于另外的AudioSource产生新的音频流,无法修改来源数据,内部处理后输出
  3. 基于另外的AudioSource产生新的音频流,可以修改来源数据,修改后直接输出
  4. 基于另外的AudioSource产生新的音频流,可以修改来源数据,也可作内部处理

ChannelRemappingAudioSource通道重映射就属于第4种情况,这种情况其实很特殊:不仅可以改变来源数据(来源数据的通道重映射、重排序、合并和通道数量的增减),还可以基于改变后的来源数据进一步处理(输出通道的重映射),而后输出处理后的全新数据。说白了,就是两次重映射式修改,一次针对音频来源的原始数据,改变音频来源;第二次针对修改后的原始数据,产生全新的音频流。

所谓通道重映射是指:比如音频来源中包含两个通道的采样,即双通道音频流,经过通道重映射类处理后,左通道的数据保持不变,同时将右通道设置为左通道的数据(反之亦然),此即为通道重映射。或者,左通道和右通道的数据互换,原来的左通道成了现在的右通道,而原来的右通道成了现在左通道,此即为通道重排序。或者,左通道和右通道的数据全部合并到左通道或右通道,此即为通道合并。通道合并后,多余的右通道可删掉,此即为通道减少。或者,新增4个通道,将左通道的数据复制给左后通道,将右通道的数据复制给右后通道,将左右两个通道的数据合并后复制给中置通道和低音通道,此即为合并后的通道增加。

改变音频来源的数据后,正常情况下,将改变后的音频数据直接赋值给getNextAudioBlock()的参数即可完成任务,但ChannelRemappingAudioSource的特殊性就在于它在getNextAudioBlock()中进行了再次处理,即进行两次重映射:第一次改变音频来源的通道状态,第二次基于第一次改变后的数据,再次改变之,再次改变后的数据即为自身所生成和输出的音频流。也就是:经过该类处理后,产生两种不同的数据,一是音频来源改变后的数据,二是该类生成的数据。这一点与ResamplingAudioSource有本质的区别:ResamplingAudioSource改变来源的数据后,直接输出这些数据。而ChannelRemappingAudioSource不仅改变了来源的数据,还产生了全新的数据。

针对这两种数据,ChannelRemappingAudioSource提供了不同的处理函数。理清思路后,就容易理解这些函数的作用了,否则可能会感到一片茫然。

ChannelRemappingAudioSource的构造函数和成员函数(网站发布,略)。