基本上,现在常用的声音采样办法是pcm,而对于压缩音频的解码,得到的也pcm数据。这个pcm数据,只是一堆数值,有正有负,看这个值看不出什么花样。

声音采集,采的是什么呢?

采的是声音的强度变化,也是声音这种能量的强弱变化,这种强弱用分贝来表示,即dB。所以,pcm数据跟这个dB就一定有关系,这个关系是这样的:

dB=20∗log10(pcm)

pcm=pow(10,(dB/20.0))

模数转换ADC时常用的位深是16bit,也就是用16位来表示一个sample,这里不考虑偷懒而使用不足16位的情况。16位能表示65536个值,也就意味着有65536个dB可以表示出来,哪又怎么样?很厉害了吗?

的确是比较厉害的了。

16位的pcm数值,分正负,那正数的范围是0至32767,负数的范围是-1至-32768,随便挑几个来看看,对应的dB是多少,如下图:

由上面的运算可知,16位的pcm值,如果不分正负,最大可以表示96dB,如果分正负,也能表示到90dB。90dB是什么概念?有数据表明(我也不清楚什么数据),85dB就会伤害了你,90dB相当于摩托车启动的声音--你有开过吗?

所以,你的pcm数据需要去到90dB以上吗?想祸害谁?一般情况下,能表示到90dB就很够用了。

既然知道了pcm数值与dB的关系,就可以搞点事情了,比如把pcm转成dB后再放大一点,再保存成新的文件,是不是播放就可以大声一点了呢?

来做个实验。

import math
import math
import wave
import audioread
import contextlib
import sys
import math
import struct def gainpcm(filepath):
try:
with audioread.audio_open(filepath) as f:
with contextlib.closing(wave.open(filepath+'.wav', 'w')) as of:
of.setnchannels(f.channels)
of.setframerate(f.samplerate)
of.setsampwidth(2)
for buf in f:
for i in range(0, len(buf)-2, 2):
s = buf[i] + buf[i+1]
pcm = struct.unpack('<h', s)[0]
apcm = abs(pcm)
if apcm==0:
apcm=1
db = 20*math.log10(apcm)
db = db * 1.2
apcm=int(math.pow(10, float(db)/20.0))
if apcm>32767:
apcm=32767
if pcm < 0:
pcm=-apcm
else:
pcm = apcm
tbuf = struct.pack('<h', pcm)
of.writeframes(tbuf) except audioread.DecodeError:
print("File could not be decoded.")
sys.exit(1) if __name__ == '__main__':
gainpcm('test.mp3')

这里是对代码的简单解释:

把一个mp3放过去试验,出来一个wav,发现wav文件的声音真的大了好多(好多是因为这里设置了db*1.2)。但是,另一个问题也暴露出来了,就是听起来声音失真很严重了,这是因为放大到这个程度,很多apcm都超过了32767,也就是人们说的截顶失真了,看一下原文件与放大后的文件波形图就更清楚了:

由于不能上传音频,这里就不提供直接的音频对比了。

由此可见,要想不失真,那db就不要乘那么大的数啊--另一个办法:给它限幅(压幅),或者直接使用更合适的整体技术(灵活变音量跟限幅都考虑进去了)比如agc或drc等,明显这个不是这里的内容。

好了,总结一下,本文演示了改变音量的一种最原始的办法,就是直接改pcm的值(转dB再改变,其实也可以直接改变pcm值),但这不是最好的办法,因为它会引入失真的副作用。而从pcm数据中提取出能量(dB),这个也更像是音频特征的技能。有缘再见,see you。

多媒体开发(5)&音频特征:声音可以调大一点吗?的更多相关文章

  1. 多媒体开发之音频编码---ffmpeg 编码aac

    http://blog.csdn.net/ctroll/article/details/8169396

  2. graphical Layout调大一点

    布局最右边的放大器按钮好难找啊

  3. 多媒体开发库 之 SDL 详解

    SDL 简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的 ...

  4. moviepy音视频开发:音频剪辑基类AudioClip

    ☞ ░ 前往老猿Python博文目录 ░ 一.背景知识介绍 1.1.声音三要素: 音调:人耳对声音高低的感觉称为音调(也叫音频).音调主要与声波的频率有关.声波的频率高,则音调也高. 音量:也就是响度 ...

  5. IOS开发之音频--录音

    前言:本篇介绍录音. 关于录音,这里提供更为详细的讲解网址:http://www.cnblogs.com/kenshincui/p/4186022.html#audioRecord  ,并且该博客有更 ...

  6. Kubuntu麦克风音频无声音

    前段时间买了新本,装了双系统,win8和kubuntu 14.04,使用的过程感觉都不错,因为平时玩游戏看视频是用win8,但最近打算在kubuntu上听音乐时,发现音频没有声音,麦克风也没有声音,这 ...

  7. LiveVideoStack Meet|深圳 多媒体开发新趋势

    2018年初始,音视频技术生态并不平静,Codec争夺愈加激烈,新一代标准的挑战一浪高过一浪:WebRTC的定版也为打通浏览器.移动端乃至IoT带来了机会:此外AI.区块链技术的兴起,催化着与多媒体领 ...

  8. 音频标签化1:audioset与训练模型 | 音频特征样本

    随着机器学习的发展,很多"历史遗留"问题有了新的解决方案.这些遗留问题中,有一个是音频标签化,即如何智能地给一段音频打上标签的问题,标签包括"吉他"." ...

  9. iOS AVAudioPlayer播放音频时声音太小

    iOS AVAudioPlayer播放音频时声音太小 //引入AVFoundation类库,设置播放模式就可以了 do { try AVAudioSession.sharedInstance().ov ...

随机推荐

  1. 交叉熵损失函数,以及pytorch CrossEntropyLoss的理解

    实际运用例子: https://zhuanlan.zhihu.com/p/35709485 pytorch CrossEntropyLoss,参考博客如下: https://mathpretty.co ...

  2. JavaScript异步编程的四种方法

    1.回调函数 f1(f2); 回调函数是异步编程的基本方法.其优点是易编写.易理解和易部署:缺点是不利于代码的阅读和维护,各个部分之间高度耦合 (Coupling),流程比较混乱,而且每个任务只能指定 ...

  3. 【题解】HDU4625 JZPTREE

    题目链接 题意 给定一棵 n 点的树,定义 \(dis(u,v)\) 为树上路径长度.对于每个点,定义 \(E_u=\sum_{v=1}^n dis(u,v)^k\) ,其中 k 为给定数. 求每个 ...

  4. AcWing 339 .圆形数字

    大型补档计划 题目链接 设 \(f[i][j]\) 表示二进制下,数字有 \(i\) 位, \(0\) 的个数 - \(1\) 的个数 \(=\) \(j\) 的方案数 \(f[0][0] = 1;\ ...

  5. NPM相关知识点

    1.Windows环境变量的配置 npm config set prefix "D:\Program Files\nodejs\node_global" npm config se ...

  6. centos安装scrapy

    安装scrapy centos 7 安装scrapy报错说找不到scrapy需要的Twisted13.0以上版本? Collecting Twisted>=13.1.0 (from Scrapy ...

  7. 自顶向下redis4.0(3)命令与dict

    redis4.0的命令 简介 目录 redis4.0的命令 简介 正文 redisCommand与redisCommandTable 初始化命令 执行命令 set指令与字典 参考文献 正文 redis ...

  8. pycharm的快捷键的使用

    作为未来的程序猿,快捷键对我们来说很重要,因为它方便且快捷,今天就给大家介绍pycharm中常用的快捷键 1.编辑: Ctrl + Space------------------基本的代码完成(类.方 ...

  9. .NET+SqlServer 实现数据读写分离

    如今,我们操作数据库一般用ORM框架 现在用.NET Core + EFCore + SqlServer 实现数据读写分离 介绍 为什么要读写分离? 降低数据库服务器的压力 如何实现读写分离? 1.一 ...

  10. C# 队列Queue,ConcurrentQueue,BlockingCollection 并发控制lock,Monitor,信号量Semaphore

    什么是队列? 队列Queues,是一种遵循先进先出的原则的集合,在.netCore中微软给我们提供了很多个类,就目前本人所知的有三种,分别是标题提到的:Queue.ConcurrentQueue.Bl ...