From

一.声音的相关概念

声音是介质振动在听觉系统中产生的反应。声音总可以被分解为不同频率不同强度正弦波的叠加(傅里叶变换)。

声音有两个基本的物理属性:频率振幅。声音的振幅就是音量,频率的高低就是指音调,频率用赫兹(Hz)作单位。人耳只能听到20Hz到20khz范围的声音。

模拟音频(Analogous Audio),用连续的电流或电压表示的音频信号,在时间和振幅上是连续。在过去记录声音记录的都是模拟音频,比如机械录音(以留声机、机械唱片为代表)、光学录音(以电影胶片为代表)、磁性录音(以磁带录音为代表)等模拟录音方式。

数字音频(Digital Audio),通过采样和量化技术获得的离散性(数字化)音频数据。计算机内部处理的是二进制数据,处理的都是数字音频,所以需要将模拟音频通过采样、量化转换成有限个数字表示的离散序列(即实现音频数字化)。

采样频率(Sampling Rate),单位时间内采集的样本数,是采样周期的倒数,指两个采样之间的时间间隔。采样频率必须至少是信号中最大频率分量频率的两倍,否则就不能从信号采样中恢复原始信号,这其实就是著名的香农采样定理。CD音质采样率为 44.1 kHz,其他常用采样率:22.05KHz,11.025KHz,一般网络和移动通信的音频采样率:8KHz。

量化深度,表示一个样本的二进制的位数,即样本的比特数。量化是将经过采样得到的离散数据转换成二进制数的过程,量化深度表示每个采样点用多少比特表示,在计算机中音频的量化深度一般为4、8、16、32位(bit)等。例如:量化深度为8bit时,每个采样点可以表示256个不同的量化值,而量化深度为16bit时,每个采样点可以表示65536个不同的量化值。量化深度的大小影响到声音的质量,显然,位数越多,量化后的波形越接近原始波形,声音的质量越高,而需要的存储空间也越多;位数越少,声音的质量越低,需要的存储空间越少。CD音质采用的是16 bits,移动通信 8bits。

声道数,记录声音时,如果每次生成一个声波数据,称为单声道;每次生成两个声波数据,称为双声道。使用双声道记录声音,能够在一定程度上再现声音的方位,反映人耳的听觉特性。

数字音频存储大小。采样频率、量化深度数越高,声音质量也越高,保存这段声音所用的空间也就越大。立体声(双声道)存储大小是单声道文件的两倍。即:文件大小(B)=采样频率(Hz)×录音时间(S)×(量化深度/8)×声道数(单声道为1,立体声为2)
如:录制1分钟采样频率为44.1KHz,量化深度为16位,立体声的声音(CD音质),文件大小为:
44.1×1000×60×(16/8)×2=10584000B≈10.09M

二.PCM

音频编码,指将模拟音频转换成数字音频并以某种格式存储的技术或过程。

PCM(Pulse Code Modulation)编码,即通过脉冲编码调制方法生成数字音频数据的技术或格式,是一种无损编码格式,是音频模拟信号数字化的一种方法,需要经过采样、量化和编码过程,以实现音频模拟信号数字化。

首先从6个方面描述PCM:
1)采样率;
2)符号:表示样本数据是否是有符号位,比如用一字节表示的样本数据,有符号的话表示范围为-128~127,无符号就是0~255,;
3)字节序:字节序分为大端与小端;
4)样本大小:决定了每个样本由多少位组成,即前面说到的量化深度,一般16位是最常见的;
5)声道数:分为单声道与双声道。
6)整形或浮点型:大多数格式的PCM样本数据使用整形表示,然而在一些对精度要求高的应用方面,使用浮点类型表示PCM样本数据。

打开ffmpeg,敲:ffmpeg -formats命令,获取ffmpeg支持的音视频格式,在这当中我们可以找到支持的PCM格式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

DE f32be           PCM 32-bit floating-point big-endian

DE f32le           PCM 32-bit floating-point little-endian

DE f64be           PCM 64-bit floating-point big-endian

DE f64le           PCM 64-bit floating-point little-endian

DE mulaw           PCM mu-law

DE s16be           PCM signed 16-bit big-endian

DE s16le           PCM signed 16-bit little-endian

DE s24be           PCM signed 24-bit big-endian

DE s24le           PCM signed 24-bit little-endian

DE s32be           PCM signed 32-bit big-endian

DE s32le           PCM signed 32-bit little-endian

DE s8              PCM signed 8-bit

DE u16be           PCM unsigned 16-bit big-endian

DE u16le           PCM unsigned 16-bit little-endian

DE u24be           PCM unsigned 24-bit big-endian

DE u24le           PCM unsigned 24-bit little-endian

DE u32be           PCM unsigned 32-bit big-endian

DE u32le           PCM unsigned 32-bit little-endian

DE u8              PCM unsigned 8-bit

比如DE s16be,就表示一个样本用16bits有符号的整形数据表示,字节序为大端。

假设我们有一个PCM signed 16-bit little-endian,双声道的PCM文件。如下是文件中前9个样本:

1

2

3

+------+------+------+------+------+------+------+------+------+

|  500 |  300 | -100 | -20  | -300 |  900 | -200 |  -50 |  250 |

+------+------+------+------+------+------+------+------+------+

每个样本2字节,总共18字节,每个样本取值范围:-32768 ~ 32767。

三.PCM音量控制

通过前面描述我们对PCM有了个了解,知道了在PCM流中数据如何存储。下面我们先看一个真正的音频样本波形:

如果我们放大5倍波形,也就是振幅乘以5,此时我们听到了更大的声音,此时样本波形如下:

假如我们有2048bytesPCM数据,样本大小两个字节,共有1024个样本,我们要放大两倍声音,代码可以按如下写:

1

2

3

4

int16_t pcm[1024] = read in some pcm data;

for (ctr = 0; ctr < 1024; ctr++) {

pcm[ctr] *= 2;

}

这是不是很简单,但是接下来我们还需要考虑两个方面的问题。

数据溢出

因为每个样本取值范围是有限制的,调节音量时不可能随便增大,比如一个signed 16 bits的样本,值为5000,我们放大10倍,由于有符号位16bits数据取值范围为-32768~32767,5000乘以10得到的50000超过了32767,数据溢出了,最后值可能变为-15536,不是我们期望的。此时我们就需要裁剪了,确保数值在正确范围内。如下代码对前面说到的放大两倍声音做了裁剪处理:

1

2

3

4

5

6

7

8

9

10

11

12

int16_t pcm[1024] = read in some pcm data;

int32_t pcmval;

for (ctr = 0; ctr < 1024; ctr++) {

pcmval = pcm[ctr] * 2;

if (pcmval < 32767 && pcmval > -32768) {

pcm[ctr] = pcmval

} else if (pcmval > 32767) {

pcm[ctr] = 32767;

} else if (pcmval < -32768) {

pcm[ctr] = -32768;

}

}

对数描述

平时表示声音强度我们都是用分贝(db)作单位的,声学领域中,分贝的定义是声源功率与基准声功率比值的对数乘以10的数值。根据人耳的心理声学模型,人耳对声音感知程度是对数关系,而不是线性关系。人类的听觉反应是基于声音的相对变化而非绝对的变化。对数标度正好能模仿人类耳朵对声音的反应。所以用分贝作单位描述声音强度更符合人类对声音强度的感知。前面我们直接将声音乘以某个值,也就是线性调节,调节音量时会感觉到刚开始音量变化很快,后面调的话好像都没啥变化,使用对数关系调节音量的话声音听起来就会均匀增大。

如下图,横轴表示音量调节滑块,纵坐标表示人耳感知到的音量,图中取了两块横轴变化相同的区域,音量滑块滑动变化一样,
但是人耳感觉到的音量变化是不一样的,在左侧也就是较安静的地方,感觉到音量变化大,在右侧声音较大区域人耳感觉到的音量变化较小。

下面我们讲下音量值乘数取值,这里我只简单的用tan函数模拟,效果也不错,至于使用对数如何调整请参考文末链接:

1

2

int some_level;

float multiplier = tan (some_level / 100.0 );

上面代码中音量乘数取值为tan (some_level / 100.0 ),最后实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

int16_t pcm[1024] = read in some pcm data;

int32_t pcmval;

uint8_t level = certain value;

float multiplier = tan(level/100.0);

for (ctr = 0; ctr < 1024; ctr++) {

pcmval = pcm[ctr] * multiplier;

if (pcmval < 32767 && pcmval > -32768) {

pcm[ctr] = pcmval

} else if (pcmval > 32767) {

pcm[ctr] = 32767;

} else if (pcmval < -32768) {

pcm[ctr] = -32768;

}

}

其中level取值需要具体测试实现,一般使用时level取值为某个范围的几个数,比如取10个数,这样音量就有10个阶跃可以调节。
如下图,最后声音音量近似按对数关系增长了:

如果想了解利用对数关系调节音量的具体实现,请参考:
PCM音量控制(高级篇)

改变PCM采样点计算来控制音量相关推荐

  1. 计算音频数据音量_【翻译】线性的音量推子……简直像一个个秤砣!

    --副标题:给音频软件硬件工程师的提示 原文:Programming Volume Controls - dr-lex.be 因为很多程序员缺乏对人类听觉系统的常识,或者只是因为太懒了,很多音频软件都 ...

  2. 使用Python基于OpenCV+MediaPipe追踪手势并控制音量

    利用Python基于OpenCV+MediaPipe追踪手势并实现控制音量 写在前面 说明 简介 1.OpenCV简介 2.MediaPipe简介 3.配置环境 开发环境 所需的库 最终效果演示 手部 ...

  3. KerberosSDR代码笔记(5) 信号处理(采样时间延迟计算、相位差计算的2种方法、MUSIC算法)

    https://github.com/rtlsdrblog/kerberossdr/blob/master/_signalProcessing/hydra_signal_processor.py 这部 ...

  4. Win11使用键盘控制音量大小的方法分享

    Win11使用键盘控制音量大小的方法分享.今天来教大家怎么设置自己的键盘来进行音量的控制.因为有的时候,我们在游戏或者其他操作的时候,需要快捷的去进行音量的大小改变,通过键盘切换的方法非常方便,可以随 ...

  5. EE架构|国内主流OEM的中央计算+区域控制架构信息梳理

    智能座舱.智能驾驶和智能网联的发展将会促使新功能的不断增加.同时,对高算力和大带宽数据传输的需求也会越来越迫切,再加上"软件定义汽车"的理念驱动,共同推动着整车EE架构的升级和变革 ...

  6. kodi鼠标控制音量界面_如何使用Amazon Echo控制您的Kodi Media Center

    kodi鼠标控制音量界面 Remote controls are so 1950. If you have a Kodi media center and an Amazon Echo, you ca ...

  7. 手势控制音量--详细注释解析恩培作品1

    感谢恩培大佬对项目进行了完整的实现,并将代码进行开源,供大家交流学习. 一.项目简介 本项目最终达到的效果为手势控制电脑音量.如图所示 项目用python实现,调用opencv,mediapipe,c ...

  8. 计算机视觉项目:手势拖拽方块和手势控制音量

    项目简介: 电子科技大学中山学院2019级计算机视觉的课程设计 语言:Python 开发工具:Pycharm.Python3.9 库:PyQt.OpenCv.mediapipe 功能: 手势拖拽方块: ...

  9. 鼠标滚轮控制音量软件

    简介: 当我们想要调整电脑的音量时,有时无法将其设置为我们需要的精确音量,只能调个大概,使用这款 tb-vol-scroll 软件可以帮助我们轻松控制电脑音量,通过用鼠标滚轮滑动的方式就能增大或减小音 ...

最新文章

  1. 网络推广外包中如何让网络推广外包专员充分运用网站的市场价值?
  2. 【一起学OpenFOAM】04 OpenFOAM的学习资源
  3. Python机器学习:决策树003使用信息熵寻找最优划分
  4. opencv AKAZE 局部特征匹配算法
  5. SQL 引擎如何把语句转换为一个抽象语法树?
  6. 百度Map与HT for Web结合的GIS网络拓扑应用
  7. 深入分析同步工具类之AbstractQueuedSynchronizer
  8. php5.2、5.3和5.4,Apache多虚拟主机多版本PHP(5.2+5.3+5.4)共存运行配置
  9. 四分位数(Quartiles)、十分位数(Deciles)和百分位数(Percentiles
  10. 人,人,还是人-对需求、沟通、辅导、会议、改变、学习的狂想
  11. C# 获得当前应用程序路径
  12. ThinkPHP 提示验证码输入错误
  13. “致广大而尽精微,极高明而道中庸。”
  14. 与商业经济有关的英语电影推荐:商学院学生必看的20部电影(图文)
  15. Minio Utils
  16. 狂飙高启兰好飒,你看狂飙了吗?
  17. 1、网络七层的具体作用
  18. Windows环境下PyTorch_geometric安装踩坑
  19. RxJava之背压策略
  20. activiti学习01

热门文章

  1. OSC源创会【放码过来】环节精彩回顾
  2. 用SDWebImage渐变加载图片
  3. 适用于连续资源块的数组空闲链表的算法
  4. 如何写出兼容大部分浏览器的CSS 代码
  5. Ubuntu解压文件的方法
  6. 艾伟_转载:单元测试之道(使用NUnit)
  7. 上传分片切片大文件 XLSX/CSV/TXT
  8. javascript 数组过滤重复对象
  9. JavaScript 插件的书页翻转效果
  10. java怎么看内存值_【java】内存分析