音频变速播放原理分析及实现方案

[时间:2019-05] [状态:Open]
[关键词:音频,audio,倍速,变速,变调,soundtouch,sonic]

音频变调变速原理分析

先来一段语音处理的理论:

变速变调可分为:变速不变调和变调不变速。

语音变速不变调是指保持音调和语义保持不变,语速变快或变慢。该过程表现为语谱图在时间轴上如手风琴般压缩或者扩展。那也就是说,基频值几乎不变,对应于音调不变;整个时间过程被压缩或者扩展,声门周期的数目减小或者增加,即声道运动速率发生改变,语速也随之变化。对应于语音产生模型,激励和系统经历与原始发音情况几乎相同的状态,但持续时间相比原来或长或短。

严格地讲,基频和音调是两个不同的概念,基频是指声带振动的频率,音调是指人类对基频的主观感知,但是两者变化基本一致,即基频越高,音调越高,基频越低,音调越低,音调是由基频决定的。因此,语音变调不变速就是指改变说话人基频的大小,同时保持语速和语义不变,即保持短时频谱包络(共振峰的位置和带宽)和时间过程基本不变。对应于语音产生模型,变调改变了激励源;声道模型的共振峰参数几乎不变,保证了语义和语速不变。

综上所述,变速改变声道运动速率,力求保持激励源不变;变调改变激励源,力求保持声道的共振峰信息不变。但是声源和声道不是相互独立的,在改变声源时,必然也会非线性的影响声道,同样地,改变声道时也会或多或少的影响声源,两者之间相互影响,相互作用。

语音变调在变声软件中较常用。而语音变速在播放器中常用,比如倍速播放(快播、慢播)。本文重点关注变速。
相对于视频基于帧的变速原理,跳帧或者插帧。音频的变速原理并不是如此简单,因为简单的抽采样点会引起声音的不连续、噪声或爆破音,主观体验较差。
所以一下简单的音频处理策略通常是行不通的:(以x2倍速为例)

1.播放设备实现,设置播放设备播放采样率加倍,这样单位时间播放的采样点数加倍,可以实现变二倍速不变调,但声音不连续。
2.播放前PCM重采样为原采样率的一半,可以实现二倍速,但是会变调。
3.丢帧,每隔一帧丢一帧,可以实现两倍速,但是也会有刺啦刺啦的噪音,而且声音会产生断续,体验十分差。

可用方案

所以为了实现较好的主观体验,只能采用相对复杂的语音处理策略。目前较为常用的音频变速解决方案有两个:soundtouch和Sonic。

ijkplayer使用的是soundtouch,EXOPlayer使用的是Sonic。

在Android上还有一种实现方式,基于AudioTrack的变速播放,代码如下:

	PlaybackParams params = audioTrack.getPlaybackParams();
    //params.setSpeed(1.0f);  // available
    //params.setSpeed(0.5f);  // available
    params.setSpeed(1.5f);  // not available
    audioTrack.setPlaybackParams(params);

详细用法建议参考PlaybackParams

Sonic和Soundtouch用法类似,都是提供封装好的库,将原音频的PCM数据通过接口函数处理为目标格式,比如二倍速,可能PCM采样点就减半。
这里以Soundtouch提供的接口为例,说明下如下使用:

参数设置类接口:

  • setChannels(int) 设置声道,1 = mono单声道, 2 = stereo立体声
  • setSampleRate(uint) 设置采样率
  • setRate(double) 指定播放速率,原始值为1.0,大快小慢
  • setTempo(double) 指定节拍,原始值为1.0,大快小慢
  • setRateChange(double)、setTempoChange(double) 在原速1.0基础上,按百分比做增量,取值(-50 .. +100 %)
  • setPitch(double) 指定音调值,原始值为1.0
  • setPitchOctaves(double) 在原音调基础上以八度音为单位进行调整,取值为[-1.00,+1.00]
  • setPitchSemiTones(int) 在原音调基础上以半音为单位进行调整,取值为[-12,+12]

PCM处理类接口:

  • putSamples(const SAMPLETYPE *samples, uint nSamples) 输入采样数据
  • receiveSamples(SAMPLETYPE *output, uint maxSamples) 输出处理后的数据,需要循环执行
  • flush() 冲出处理管道中的最后一组“残留”的数据,应在最后执行

从上述接口来看,类似于常规的解码器或者解复用器的调用逻辑。

小结

本文简述了音频变速变调的原理,并对目前Android平台上可用的音频变速方案做了总结,包括Soundtouch、Sonic及AudioTrack三种方案,仅供后续参考。

参考资料

  1. 音频倍速(变速不变调)的实现
  2. 变速变调原理与方法总结
  3. SoundTouch官网
  4. ijkplayer倍速变调问题解决方案
  5. SoundTouch实现音频变速变调
posted @ 2019-07-31 21:50  Tocy  阅读(8272)  评论(0编辑  收藏  举报