音视频倍速 是内容类APP非常重要的功能,其内部包含了 视频流 和 音频流 的倍速,其中视频倍速原理相对简单,即在解码视频帧时提升帧率即可。

音频倍速 相对复杂,众所周知,声音的本质其实是 物体振动时产生的声波,因此音频的倍速是 将语音信号在时域上拉长或缩短,考虑到用户的体验,在保证声音变速的同时,语音的采样率、基频以及共振峰都不能发生变化,以此达到 变速不变调 的目的。

对于 Android 平台的应用而言,音频倍速通常有3种实现方式:

对于原生的 AudioTrack 而言,其本身提供了处理PCM音频流的功能,但由于其默认被系统的 MediaPlayer 绑定,而后者本身在不同平台上的兼容性就不佳,因此很少被使用。

Sonic 库则被 Google 大名鼎鼎的开源播放器 ExoPlayer 所使用,其内部基于 时域压扩算法 (Time-scale modificatio,下简称TSM算法), 通过定位 基音周期 的方式,对输入的语音信号进行不断的分帧与合帧的处理,最终合成新的信号以达到倍速的效果。

SoundTouch 则被 Bilibili 开源的 ijkPlayer 所内置,内部仍然基于TSM算法,和Sonic不同的是使用了 寻找相关峰 进行语音信号的合成。

不可否认,信号的合成必然会造成原始音频的失真,区别在于Sonic是基于 基音周期 的,因此变速后的语音信号对人声音影响较小;而 SoundTouch 倍速效果更适用于综合性的场景。

但在实际应用中,问题却不断涌现:

  1. 从上述结论来看,既然对人声音影响较小,那么针对歌曲的倍速播放,Sonic效果应该更好,但实际中,Sonic在高倍速下听感失真明显,和SoundTouch的效果有显著差距,导致该现象的原因是什么?

  2. 如何解决该问题,两种倍速方案各自适用的场景又是什么?

要搞明白这些疑惑,就需要从原理和具体的算法实现进行分析。

音频倍速原理

1、TSM基本原理

音频倍速的实现思路分为针对 时域 信号或者 频域 信号分析,但由于频域的复杂度过高,因此实践中通常从时域信号着手。

时域压扩(TSM) 也正是基于时域信号的处理中的典型算法,其提供了 变速不变调 的音频处理实现。

音频信号的处理过程中,不可避免的要进行 分帧 (analysis fames)操作,帧的长度大多选取是 20ms 到 50ms 之间,并进行加窗操作,而由于加窗操作本身会对一帧信号的两端进行抑制,因此分帧不能按长度分段截取,而是相互重叠一部分(overlap),之后再进行 合帧 (synthesis frames)。如果分帧以 50% 的 overlap,而合帧(synthesis frames)时以 75%,那么就实现了慢放,反过来则是快放。

一言蔽之,对每个帧进行一系列处理比如拉伸或者压缩,最后在将这些帧重新叠加成合成信号实现倍速:

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

2、暴力的OLA

OLA(Overlap-and-Add, OLA) 重叠相加算法是音频变速算法中最简单的时域算法,它是后续时域算法(SOLA, SOLA-FS, TD-PSOLA, WSOLA)的基础。

首先,音频信号分帧处理后,暴力的将处理后的信号首位拼接起来,思路非常简单,但劣势显而易见,它会造成拼接后信号的不连续,相邻帧重叠区域产生基频失真:

为了减轻这种波形不连续的影响,我们对信号进行了分帧加窗处理,OLA中通常使用汉宁窗对帧进行加窗叠加(如下图 b ):

加窗的处理保证了信号两端被抑制,保证后续的傅里叶变换,减轻频谱泄漏;这之后,通过固定间隔 Ha 取到下一个帧(如上图 c ),加窗后与前一帧叠加(如上图 d ),以缓解波形不连续(基音断裂)问题。 即便如此,在帧裁剪的过程中,仍然无法保证每一个帧都能覆盖完整周期并保证其相位对齐,这种失真也叫相位跳跃失真(phase jump artifacts),对于音频的听感仍然不佳:

如图,两个周期信号帧通过 OLA 合成后变得 “不周期” 了。

3.波形相似叠加(WSOLA)

如何解决这样的问题,WSOLA (Waveform similarity Overlap-Add, 波形相似叠加) 算法提出这样一种思路,通过寻找当前帧下一个最相似的信号帧,并对两帧进行叠加,这样合成后的语音便会非常自然:

上图很清晰表述了该算法的核心思想:

1.在原音频中截取一个帧,加窗;
2.在一个范围内(蓝色虚线框)选取第二个帧,这个帧的相位参数应该和第一个帧相位对齐;
3.在另一个范围内(蓝色实线框)中查找第三个帧,这个帧和第二个帧应该最相似;
4.最后把它们叠加在一块。

问题很自然转换成为了 “ 如何找到最相似的帧 ”,在Android中,对于音频 变速不变调 处理的问题,SoundTouch使用 寻找相关峰 的算法来实现,而Sonic则使用的是另外一种 AMDF 的基音提取算法。

对于 寻找相关峰 ,顾名思义,当第一帧数据到达时,会将数据依次传入Buffer,并在固定长度之后的位置开始,寻找与第一帧信号相关性最大的位置,并对两帧信号进行合成;

对于 Sonic 中使用的是 AMDF (平均幅度差函数法)方法,该方法极其简单,在一定范围内,分别计算每个帧与起始帧的 AMDF 值,幅度差最小的帧与第一帧的距离便是基音周期,寻找到基因周期后,根据基音周期进行变速变调。

阶段性小结

文章最初有提到,使用 ExoPlayer 播放音乐时, Sonic的倍速效果失真明显,和 ijkPlayer 对应的 SoundTouch 倍速效果有 明显差距。这似乎有违常理,既然 Sonic 是基于定位基音周期的算法实现,那么对于人声这种周期性强的音频信号而言,倍速效果应该更好才对。

经过对比与思考,我们做出以下推测,诚然,对于纯粹的人声,Sonic 的倍速效果较佳,但对于绝大多数音乐,听众对于声音节奏的听感更多是由背景乐所提供的,而背景乐通常是由多种乐器组合演奏,Sonic对这种包含较多谐波冲击和瞬态分量的音频信号处理起来则更棘手。

因此,在具体的音频倍速实现中,不妨对具体的业务场景进行不同的决断,对于常规音乐——尤其是背景乐、打击感比较强的音乐,我们可以选择SoundTouch, 而对于人声更纯粹的音频类型(比如相声、评书、歌手清唱)而言,Sonic也是不错的选择。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

Android 音频倍速的原理与算法分析相关推荐

  1. Android 分场景集成不同音频倍速算法的实现

    概述 上文 <Android 音频倍速的原理与算法分析> 中, 我们针对音频倍速的基本原理进行了梳理,并逐步引申出了 Android 平台上常用的2种算法实现:Sonic 和 SoundT ...

  2. Android MediaPlayer 音频倍速播放,调整播放速度

    本文链接: Android MediaPlayer 倍速播放,调整播放速度 现在市面上的很多音视频App都有倍速播放的功能,例如把播放速度调整为0.5.1.5.2倍等等. 从Android API 2 ...

  3. 音频倍速(变速不变调)的实现

    背景: 项目需要,开发一款自己的安卓端播放器SDK,其中需要有一个视频倍速播放的功能.需要实现的效果是变速不变调.项目基于FFMpeg和WebRtc,通过FFMpeg从网络读取视频流,经过解封装.解复 ...

  4. java 音频倍速播放,libsonic - 倍速播放开源库

    概述 libsonic是一个支持音频倍速播放的开源库.支持大于2倍速的播放.有ANSI C的版本,也有纯Java的版本.能够方便的集成进你的应用中. 项目主页:https://android.goog ...

  5. 音视频之使用sonic.cpp实现音频倍速播放功能

    sonic.cpp 是一个音频处理库,可以实现倍速播放. 如果单纯通过修改pcm的采样率来实现音频倍速播放的话,就会出现声音变调的情况. 以下是通过采集windows 虚拟声卡获取到的音频数据, 我的 ...

  6. java 音频倍速播放_Android MediaPlayer 音频倍速播放,调整播放速度

    现在市面上的很多音视频App都有倍速播放的功能,例如把播放速度调整为0.5.1.5.2倍等等. 从Android API 23 (Android M)开始,MediaPlayer支持调整播放速度. 使 ...

  7. python播放视频 命令_【趣味案例】一行Python命令实现视频、音频倍速

    最近看了一部悬疑爱情电视剧 <想见你>,看过的朋友估计都已经被伍佰的一首<last dance>洗了脑,相当上头. 由于我是二倍速观看的视频,里面播放的歌曲也是二倍速.脱离开视 ...

  8. iOS 设置音频倍速播放

    ViewController.h // // ViewController.h // iOSAudio // // Created by 杜甲 on 13-11-18. // Copyright (c ...

  9. 大华、海康和华为等NVR录像机gb28181平台倍速播放原理

    最近做NVR倍速播放的web功能,大致了解了一下这些平台有关倍速播放的时候是如何发送视频数据的. 基本原理如下: 因为这些平台都不会牵扯到编解码,所以只能在编码后的数据进行处理,原始的编码数据来源于相 ...

最新文章

  1. PMP-【第3章 项目管理过程】-2021-1-11(61页-87页)
  2. usg2130 虚拟服务器,usg2130防火墙怎么样设置
  3. Spring点滴二:Spring Bean
  4. matlab 线性拟合polyfit_从零开始的matlab学习笔记——(24)曲线拟合
  5. APIO/CTSC2017游记
  6. 公司招聘asp.net 工程师
  7. corosynclib+drbd+mysql组合应用
  8. android 数据存储之 Shared Preferences
  9. mciSendCommand对本地音乐的播放
  10. 直播组装服务器,快速搭建直播服务器
  11. 1. 神禹(shenyu)网关启动踩坑
  12. 开源分布式数据库中间件 DBLE
  13. 创建OMF(Oracle Managed Files,Oracle管理的文件)
  14. Ubuntu18.04 RTL8169驱动更换RTL8168驱动
  15. 师徒结对活动记录表计算机,师徒结对活动记录表一.doc
  16. 这图怎么画 | 相关分析棒棒糖图
  17. gallary 实现类似viewpage 的效果 左右可见
  18. SET NAMES utf8mb4
  19. Android高级控件----AdapterView与Adapter详解
  20. 快速复制蜜芽商城多个商品主图及细节图保存

热门文章

  1. Tiled结合Unity做地图——Tiled2Unity
  2. 强烈推荐33个 GitHub 前端学习资源
  3. 专科的计算机跨专业考研,专科生考研心路:跨学历都不怕,怕什么三跨?
  4. nginx+keepalived+tomcat
  5. docker logs 查看日志
  6. MATLAB动画绘制
  7. 系统集成项目管理工程师高频考点(第六章)
  8. c语言入门经典+第5版+习题答案,C语言入门经典(第5版)
  9. MATLAB-7-程序流程控制
  10. 终端I/O之终端标识