Advertisement

python实时采集与处理声音信号_Python之音频信号处理(一)音频基础知识

阅读量:

音频基础知识包括声音的三要素(音调、音量和音色)及其特性。声音通过模拟信号采集后进行量化(采样-量化-编码),并可采用有损或无损压缩技术处理。常用压缩方法包括哈夫曼编码等无损压缩和基于频域掩蔽的技术。 audio signal processing involves key concepts like sampling, quantization, and encoding.
Python可以用于读取和写入WAV音频文件,支持设置声道数、采样频率和量化位数,并通过wave模块完成相关操作。

一、音频基础知识

1、声音的三要素

(1)音调

人类感知声音高低的变化现象被称为音调(亦称音频)。决定音调的关键因素是声波的振动频率。当声波振动频率增加时,相应的音调也会提高。通常情况下,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征时,在相同环境下比较同一器官的声音特征。

人的听觉系统对声音的感知频谱范围为20\text{Hz}-20,000\text{Hz}。当进行音频压缩任务时,在该频谱范围内采集的声音信息具有重要价值,并且超出该频谱范围的数据可以被去除以减少数据量。

(2)音量

我们称其为响度。将声音强弱的感觉称为响度。其振幅大小相关的是响度的变化规律。通常情况下,在其他条件相同的情况下,声波振幅越大则对应的响度也会越大。

人类对声音的感知不仅受到声波频率的影响,在具有相同强度的不同频率声波中,人耳感知到的声音亮度也会随之变化。

(3)音色

也就是音品

音色是人们区别具有同样响度、同样音调的两个声音之所以不同的特性

或者说是人耳对各种频率、各种强度的声波的综合反应

音色与声波的振动波形有关

2、音频的量化与编码

(1)音频的量化过程

在现实中,人们所听到的声音总是随着时间连续变化着,我们将这种变化规律称为模拟信号(即连续时间信号)。为了能在计算机系统中处理这些信息,我们需要将模拟信号转换为数字形式,这一过程通常包括五个关键步骤:采样、量化、编码以及解码等环节。具体来说,量化过程通常包括五个关键步骤:采样、量化、编码以及解码等环节。

模拟信号

现实生活中的声音可以被看作是连续且平滑的波形形态。其中,在时间轴上描绘出声信号随时间的变化情况;而该波形在纵轴上则代表了声音强度的变化范围。

采样

按照一定的时间间隔在连续的波上进行采样取值,如下图所示取了10个样。

量化

通过量化处理采样得到的值等同于对纵坐标设定一个量程,并获取每个采样的纵坐标的数值。

编码

将每个量化后的样本值转换成二进制编码。

数字信号

将所有样本二进制编码连起来存储在计算机上就形成了数字信号。

(2)量化的基本概念

1)采样大小

在采样过程中,在每个采样点通常采用多少bit来表示数据?其中最常见的是16位(这表明在量化过程中),其对应的纵坐标范围定为0至65535,并且声音信号本身不会出现负值)。

2)采样率

即为音频信号中各个时间点上的离散样本值集合。通常我们所使用的音频采集设备会以固定的时间间隔对声波进行采样。常见的数字音频系统中所采用的标准采样速率包括8kHz、16kHz、32kHz、44.1kHz和48kHz等多种选择。需要注意的是,在实际应用中选择合适的采样率不仅关系到最终音频质量的呈现效果更为重要的是要平衡好信号信息的完整保留与数据存储传输的成本效率之间的关系。

在模拟信号中描述人类听觉频段通常涵盖从二十到二万赫兹之间。以 forty-four 点一千赫兹作为基准频率来进行取样操作时发现:对于 twenty 赫兹频率的音频信号而言,在其周期内总共被取样的次数约为二千二百零零次;而对于 twenty thousand 赫兹频段的信号,则在其周期内平均被取样约两分两次。

3)声道数

为了在播放声音时实现对真实声场的还原,在录音过程中同时采集前后左右等多个方位的声音信号,并将每个方位对应一个独立的声道。其中道数指的是录音过程中的音源数量与放回过程中相应扬声器数量的一致性。具体包括单声道、双声道以及多声道等多种配置类型。

4)码率

也被称作比特率,在信息论中被定义为每秒传输的信息量(以bit为单位)。通常用bps(Bit Per Second)来表示这一指标。值得注意的是,在实际应用中这一数值直接决定了系统的传输能力——传输速率越快,则每秒钟能传递的数据量越大,并且质量也会相应提升。

码率计算公式:

码率 = 采样率 * 采样大小 * 声道数

比如采样率44.1kHz,采样大小为16bit,双声道PCM编码的WAV文件:

码率=44.1hHz16bit2=1411.2kbit/s。

那么录制1分钟的音乐的大小为(1411.2 * 1000 * 60) / 8 / 1024 / 1024 = 10.09M。

3、音频压缩技术

音频压缩主要包括2种方法:

(1)消除冗余数据

该压缩方案的核心策略是剔除采集到的可冗余数据。这些被删减的部分无法重建原始内容。因此称作有损压缩。

多余信息不仅包括超出人类听觉范围的音频信号,在某些情况下也会有部分音频信号无法被感知到。那么,什么是被抑制的信号呢?这种情况下,信号的抑制分为频域抑制和时域抑制。

1)频域掩蔽效应

人的听觉频率范围为20至20,000赫兹。然而,并非在这个频率范围内所有声音都能被察觉到。能否察觉到声音则与其分贝数值密切相关。存在一个特定的分贝阈值,在此阈值之上的声音能够被人耳感知,在此之下则无法听见。值得注意的是,在不同频率声波中这一临界点具有显著差异性。

另外一种情况是:比如说两个人同时说话时(或者一起说话),一个人的声音较强而另一个人的声音较弱(或者很安静),那么较弱的声音就会受到较强的声音的影响(或者结果是听不到较弱的声音)。

2)时域掩蔽效应

除了同时发出声音之间存在相互抑制的现象之外,在时间上相邻的时间段内发出的声音也会产生相互抑制的现象这一效应被称为时域抑制效应。该效应具体表现为超前抑制和滞后抑制两种类型。根据研究发现其主要原因在于人类大脑处理信息的过程具有一定的延迟性。一般情况下超前抑制的时间范围仅限于5到20毫秒而滞后抑制则可能持续50到200毫秒。

(2)哈夫曼无损编码

对于人类难以识别的声音信号进行删除处理后接着会对余下的声音信号实施压缩编码过程在解压过程中能够恢复回与原始数据完全一致的信息(值得注意的是)这种技术便得名于无损压缩技术

二、音频信号的读写

标准的Python已内置WAV格式的处理功能,并可通过pyAudio库(附有详细官方文档)实现实时声音输入输出功能。

音频信号属于模拟信号,在数字化处理前必须将其转换为数字形式以便进行进一步的分析和处理。WAV格式是由微软公司开发的一种无压缩声音文件格式,在存储原始声音数据方面具有显著优势。

语音信号有三个重要的参数:声道数、取样频率和量化位数。

声道数:可以是单声道或者是双声道。

该系统中的采样频率是指,在一秒钟的时间内对声音信号进行采集的次数。具体来说,在这种情况下(即使用了...),每秒钟的声音信号会被分割为...个独立的数据点。进一步说明的是,在这种情况下,在每隔大约...秒的时间间隔内就会记录一次数据。需要注意的是,在实际应用中(如在现代数字音频系统中),当采用较高的采样率时(如高于或等于特定阈值),播放回的声音会更加逼真且连续。

量化位数是指每次采样所得的数据所采用的二进制位数数量,在实际应用中通常取值包括8 bit、16 bit、24 bit和32 bit四种类型。

1、python读取.wav音频

下面是python读取音频代码

import wave

import struct

wave_file=wave.open("./sound111.wav", 'r')

channels=wave_file.getnchannels()#声道数

samp_width=wave_file.getsampwidth()#采样大小

frame_rate=wave_file.getframerate()#帧率

numframes=wave_file.getnframes()#总帧数

print("channel",channels)#声道数

print('samp_width',samp_width)#采样大小2B 16bit

print('frame_rate',frame_rate)#8000 帧率8000fps

print('numframes',numframes)#总帧数=帧率时间=8000fps10s=80000f

#输出

#channel 1

#samp_width 2

#frame_rate 8000

#numframes 80000

for i in range(500):

frame=wave_file.readframes(1)#读取1帧音频数据,可能包含多个声道信息

该代码段打印结果时会调用函数struct.unpack来解析二进制数据。具体来说,struct.unpack("h", frame[0:2])[0]的作用是从前两个字节读取一个带有符号的短整数(即16位整数)。通过这种方式,在处理嵌入式设备中的音频或视频数据时,可以高效地获取所需的数值信息。

#输出

#b'\xd4\xfc' -812

#...

#b'\x07\xff' -249

#b'\x05\xff' -251

#b'X\xff' -168

#b'\xf2\xff' -14

#b'0\x00' 48

#b'#\x00' 35

wave_file.close()

2、python写.wav音频文件

段落1

段落2

Wave_write = wave.open(file,mode="wb")

Wave_write是写文件流,

Wave_write.setnchannels(n) 配置通道数为n。
Wave_write.setsampwidth(n) 将采样宽度配置为n个字节,并包含量化位数信息。

Wave_write.configure sampling rate for n。Wave_write.set frame count to n

该对象采用元组格式设定各项参数(包括nchannels、sampwidth、framerate等)。

Wave_write.writeframes(data) 写入data个长度的音频,以采样点为单位

Wave_write.tell() 返回文件中的当前位置

写wav文件:

-- coding: utf-8 --

import wave

import numpy as np

import scipy.signal as signal

framerate = 44100 # 采样频率

time = 10 # 持续时间

t = np.arange(0, time, 1.0/framerate)

产生长度为10秒、取样频率为44.1kHz、100Hz到1kHz的频率扫描波

wave_data = signal.chirp(t, 100, time, 1000, method='linear')

该函数返回的是一个浮点数类型的数组,并且其数据类型已经被明确标注为float64类型

需要调用数组的astype方法将其转换为short型。

wave_data = wave_data.astype(np.short)

打开WAV音频用来写操作

f = wave.open(r"sweep.wav", "wb")

f.setnchannels(1) # 配置声道数

f.setsampwidth(2) # 配置量化位数

f.setframerate(framerate) # 配置取样频率

comptype = "NONE"

compname = "not compressed"

也可以用setparams一次性配置所有参数

outwave.setparams((1, 2, framerate, nframes,comptype, compname))

将wav_data转换为二进制数据写入文件

f.writeframes(wave_data.tostring())

f.close()

参考文献:

音频基础知识

音频信号的读写、播放及录音

Python标准库 wav模块

Python音频处理

全部评论 (0)

还没有任何评论哟~