PCM音量控制(高级篇)
http://blog.jianchihu.net/pcm-volume-control.html
去年写过一篇文章,有关PCM的音量控制:http://blog.jianchihu.net/pcm-volume-control.html。那时阐述了一些概念,对一些细节没有详细描述。因为有人问到使用对数关系调节音量时,增益系数如何确定,故开此篇文章。
声学中的分贝
因为人耳的特性,我们对声音的大小感知呈对数关系。所以我们通常用分贝描述声音大小,分贝(decibel)是量度两个相同单位之数量比例的单位,主要用于度量声音强度,常用dB表示。声学中,声音的强度定义为声压。计算分贝值时采用20微帕斯卡为参考值(通常被认为是人类的最少听觉响应值,大约是3米以外飞行的蚊子声音)。这一参考值是人类对声音能够感知的阈值下限。声压是场量,因此使用声压计算分贝时使用下述版本的公式:
其中的pref是标准参考声压值20微帕。
分贝声音变化范围
在编程中,我们可以用以下公式计算两个声音之间的动态范围,单位为分贝:
1
|
dB = 20 * log(A1 / A2)
|
其中 A1 和 A2 是两个声音的振幅,在程序中表示每个声音样本的大小。声音采样大小(也就是量化深度)为1bit时,动态范围为0,因为只可能有一个振幅。采样大小为8bit也就是一个字节时,最大振幅是最小振幅的 256 倍。因此,动态范围是 48 分贝,计算公式如下:
dB = 20 * log(256)
48 分贝的动态范围大约是一个安静房间和一台运行着电动割草机之间的区别。如果将声音采样大小增加一倍到16bit,产生的动态范围则为 96 分贝,计算公式如下:
dB = 20 * log(65536)
这非常接近听力最低阈值和产生痛感之间的区别,这个范围被认为非常适合还原音乐。
了解了分贝的相关概念我们通过图表说下为什么要用对数关系描述声音大小。
1)音量滑块与声音增幅大小线性变化。
上述左图中,音量滑块位置与声音振幅为线性增长关系,右图是我们人耳感受的音量大小与滑块位置关系。可知,在左侧移动相同距离的滑块,感知到的声音变化范围很大,在右侧接近声音最大值移动相同距离滑块,感知到的声音大小变化就很小了。
2)音量滑块与声音振幅大小对数关系变化。
左图中,音量滑块位置与声音振幅对数关系增长。右图中无论哪个位置,移动相同距离滑块,感知到的声音变化都是相同的。
需要说明的是滑块最小位置只是接近0,不能为0,因为对数函数y=logx中x>0。
windows系统中音量滑块控制的声音变化范围
在最新版的windows系统中,音量滑块控制的声音变化范围也是96分贝。如下表所示,是不同版本windows的音量范围以及默认音量值。
从表中我们可以看到默认值都是0分贝,根据分贝公式:dB = 20 * log(A1 / A2),当A1,A2相等时,db为0。
程序实现
了解了分贝以及windows中音量滑块是在哪个范围变化,我们的程序实现起来也很简单。
这里我们规定音量大小变化范围也是96分贝,每个声音采样大小为16位。对于分贝公式:dB = 20 * log(A1 / A2),我们取参考声音振幅A2为原始声音振幅,A1为调节后的声音振幅大小。可知调节后的声音:
1
|
A1 = A2 * pow(10 , db/20)
|
看过一篇文章说理想的声音调节步长最好是2db,对于96db范围,我们按2db步长进行分割,可以分成48份,这样我们得到的声音变化为[-96db,-94db,-92db,…-4db.-2db,0db],假设我们要调节一半音量大小,也就是-48db,由上述公式可知:调节后音量A1大小:
1
|
A1 = A2 * pow(10 , -48/20)
|
程序伪代码如下,具体db大小与滑块位置对应关系的实现这里就不写出:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int16_t pcm[1024] = read in some pcm data;
int32_t pcmval;
float multiplier = pow(10,db/20);
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;
}
}
|
PCM音量控制(高级篇)的更多相关文章
- PCM音量控制
http://blog.jianchihu.net/pcm-volume-control.html 一.声音的相关概念 声音是介质振动在听觉系统中产生的反应.声音总可以被分解为不同频率不同强度正弦波的 ...
- 【.net深呼吸】动态类型(高级篇)
前面老周给大家介绍了动态类型使用的娱乐级别用法,其实,在很多情景下,娱乐级别的用法已经满足需求了. 如果,你想自己来控制动态类型的行为和数据的存取,那么,就可以考虑用今天所说的高大上技术了.比如,你希 ...
- ORM查询语言(OQL)简介--高级篇:脱胎换骨
相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎换骨 ORM查询语言(OQL)简介--高级篇(续):庐山 ...
- 25个增强iOS应用程序性能的提示和技巧(高级篇)(2)
25个增强iOS应用程序性能的提示和技巧(高级篇)(2) 2013-04-16 14:56 破船之家 beyondvincent 字号:T | T 在开发iOS应用程序时,让程序具有良好的性能是非常关 ...
- PHP笔记(PHP高级篇)
高级篇中将涉及数据库的使用以及Cookie和Session会话,提高PHP的开发效率和运行效率 PHP程序员需要掌握的MySQL操作 为项目设计表 使用SQL语句 MySQL的目录结构 data目录中 ...
- WPF 媒体播放器(MediaElement)实例,实现进度和音量控制
WPF 视频音频播放控件MediaElement实现进度控制,音量控制实例 说明: 1.Volume控制音量的大小,double类型,并且实现了属性依赖,可以用来双向绑定:在 0 和 1. 之间的线性 ...
- Android应用--简、美音乐播放器增加音量控制
Android应用--简.美音乐播放器增加音量控制 2013年6月26日简.美音乐播放器继续完善中.. 题外话:上一篇博客是在6月11号发的,那篇博客似乎有点问题,可能是因为代码结构有点乱的原因,很难 ...
- ORM查询语言(OQL)简介高级篇
ORM查询语言(OQL)简介--高级篇:脱胎换骨 在写本文之前,一直在想文章的标题应怎么取.在写了<ORM查询语言(OQL)简介--概念篇>.<ORM查询语言(OQL)简介--实例篇 ...
- 从零开始学Axure原型设计(高级篇)
如果你熟悉了Axure的部件库,那么你可以得心应手地画出心目中产品的线框图:如果你会用Axure的母版.动态面板功能,那么你应该能够画出一些简单网站的原型图:但只有你精通了Axure的条件逻辑.变量. ...
随机推荐
- 提高开发效率 -> 图片
相比于文字, 我们从图片中获取的信息是更快和更多的. 所以, 应当大量使用图片, 大量地截图和看图, 不管是针对资料还是代码都应如此. 这里给大家推荐两个好用的小工具, 一个是截图(DuckLink ...
- PPA(Personal Package Archives)简介、兴起、使用
1.简介 PPA是Personal Package Archives,个人软件包文档,是默认情况下并未被包含在Ubuntu中的软件的一个集合.通常这些存储库的侧重点是单个的程序,不过他们也可以包含更多 ...
- React routerV4 笔记
React routerV4 笔记 一.基础路由示例 import React from 'react' import { BrowserRouter as Router, Route, Li ...
- 关于Class.getResourceAsStream
Properties properties = new Properties(); properties.load(new InputStreamReader(CharactorTest.cl ...
- 交叉编译Mesa,X11lib,Qt opengl
记录Mesa配置文件如下: Mesa版本:Mesa-10.2.3 CC=/usr/local/arm-4.8.1/bin/arm-none-linux-gnueabi-gcc CXX=/usr/loc ...
- Java中的HashMap
今天到中关村软件园面试被问到Java中HashMap的存值原理,瞬间无言已对,回答用了一个数组,然后沉默,面试官说,一次的面试失败不算什么,之后...... 1.关于hashCode hashCode ...
- 20145231《Java程序设计》第三次实验报告
实验三 敏捷开发与XP实现 实验内容 XP基础 XP核心实践 相关工具 实验要求 了解敏捷开发的基本方法以及XP软件开发的相关准则:了解代码编写的标准和原则:体会结对编程的好处: 实践体会版本控制的方 ...
- 写makefile时候的cc和gcc
Linux 下 的 cc 和 gcc Linux 下 的 cc 和 gcc 周银辉 在Linux下一会看到cc,另一会又看到gcc,感觉又点混乱的样子.它们是同一个东西么,有啥区别呢 一分为二 ...
- SQLite3时间函数小结
import sqlite3 conn = sqlite3.connect('/tmp/sqlite.db') cur = conn.cursor() 接下来干嘛呢?建一张表吧.这里需要注意的是,SQ ...
- Spark-运行时架构
Spark运行时架构 在分布式环境下,Spark集群采用的时主/从结构.在一个Spark集群中,有一个节点负责中央协调,调度各个分布式工作节点.这个中央协调节点被称为驱动器(Driver),与之对应的 ...