Python学习笔记--语音处理初步

时间:2021-09-19 00:19:57

语音处理最基础的部分就是如何对音频文件进行处理。

声音的物理意义:声音是一种纵波,纵波是质点的振动方向与传播方向同轴的波。如敲锣时,锣的振动方向与波的传播方向就是一致的,所以声波是纵波。纵波是波动的一种(波动分为横波和纵波)

通常情况下对声音进行采样量化之后得到了声音的“时间—振幅”信息。

Python学习笔记--语音处理初步

 

Python 打开wav文件的操作

wav文件

利用python打开一个wav音频文件,然后分析wav文件的数据存储格式,有了格式之后就能很方便的进行一些信号处理的操作。Wikipedia给出的wav文件的资料如下

 Waveform Audio File Format (WAVE, or more commonly known as WAV due to its filename extension - both pronounced "wave"‘)(rarely, Audio for Windows) is a Microsoft and IBM audio file format standard for storing an audio bitstream on PCs. It is an application of the Resource Interchange File Format (RIFF) bitstream format method for storing data in "chunks", and thus is also close to the 8SVX and the AIFF format used on Amiga and Macintosh computers, respectively. It is the main format used on Windows systems for raw and typically uncompressed audio. The usual bitstream encoding is the linear pulse-code modulation (LPCM) format.

 音频格式资料在网上也有一些标准格式的说明,比如WAVE PCM soundfile format http://soundfile.sapp.org/doc/WaveFormat/

 关于Python中对wave文件的处理,可以参考官方给出的文档 https://docs.python.org/3/library/wave.html

 当然大多数情况下,很需要对信息进行筛选的能力,在使用python来处理wav文件的时候仅仅需要其中的几个操作,并不一定要每个都掌握,在需要的时候查询文档。

注意

大段的文字来叙述wav音频文件是什么并不是作为编程练习的目的,人的精力是有限的不可能同时掌握所有的知识点。一开始,就学习声音的原理,然后再验证,这些工作应该是由搞信息编码的研究者来完成,而作为一个工程师应该集中精力研究代码上的复现。不如反其道行之,读取音频文件,根据系统提供的API获得各种参数,再去查询参数的信息。编程练习要思考怎么用一般在处理音频文件的时候。有个流程就是将音频文件导入,分析波形,进行傅里叶变换之类的操作,作为数据的预处理,才可以进行下一步数值数据的处理,其实音频处理最想要的过程无非如上所述。所以正常情况下,还要知道音频文件中的数据的含义,用计算机科学的思想分析就是需要知道它的数据结构。

 音频文件信息

 

 用到了python 处理wav文件的包 wave,读取wave 信息,遍历参数

import wave as we

filename = 'child1.wav'

WAVE = we.open(filename)
for item in enumerate(WAVE.getparams()):
    print(item)

查询官方文档中对于wave.getparams()的描述

Wave_read.getparams()

Returns a namedtuple() (nchannels, sampwidth, framerate, nframes, comptype, compname), equivalent to output of the get*() methods.

输出信息(声道,采样宽度,帧速率,帧数,唯一标识,无损)

 Python学习笔记--语音处理初步

采样点的个数为 2510762,采样的频率为44100HZ,通过这两个参数可以得到声音信号的时长

每个采样点是16 bit = 2 bytes ,那么将采样点的个数 2510762*2/(1024*1024)=4.78889MB,那么这个信息就是文件大小信息。

检验一下声音波形的时间

 child1.wav 4.78MB,时长56s

time = 56.93337868480726

根据上面WAVE PCM soundfile format 的资料信息查询。有一个印象:WAV文件中由以下三个部分组成:

1."RIFF" chunk descriptor  2.The "fmt" sub-chunk 3.The "data" sub-chunk 存这些信息的时候都要要有 “ID”、“大小”、“格式”,这些信息标注了数据的位置,“WAV”格式由“fmt”和“data”,两个部分组成,其中“fmt”的存储块用来存音频文件的格式,“data”的存储块用来存实际听到的声音的信息,物理上描述的振幅和时间:长度(时间)和振幅,当然人的耳朵听听见的是长度和音调。也就是说可以读取这个数组,在配合频率的信息直接画出波形图。

 注意一下几点

1.一个采样点的值代表了给定时间内的音频信号,一个采样帧由适当数量的采样点组成并能构成音频信号的多个通道。

2.对于立体声信号一个采样帧有两个采样点,一个采样点对应一个声道。一个采样帧作为单一的单元传送到数/模转换器(DAC),以确保正确的信号能同时发送到各自的通道中。

3.单声道振幅数据为n*1矩阵点,立体声为n*2矩阵点,那么将来文件的信息处理通过一个矩阵来实现

WAV文件波形

为了绘制波形图,需要的参数有时间和振幅的信息,完整的步骤如下:

1.将WAV文件导入到Python的工作环境中。

2.设置参数,声音信号(时间、振幅、频率)。

3.将这些信息通过 matplotlib.pyplot提供的接口绘画出来。

 Python学习笔记--语音处理初步

可以得到一个振幅随着时间变化的函数。

 1 import wave as we
 2 import matplotlib.pyplot as plt
 3 import numpy as np
 4 from scipy.io import wavfile
 5 
 6 filename = 'child1.wav'
 7 WAVE = we.open(filename)
 8 print('---------声音信息------------')
 9 for item in enumerate(WAVE.getparams()):
10     print(item)
11 a = WAVE.getparams().nframes    # 帧总数
12 f = WAVE.getparams().framerate  # 采样频率
13 sample_time = 1/f               # 采样点的时间间隔
14 time = a/f                      #声音信号的长度
15 sample_frequency, audio_sequence = wavfile.read(filename)
16 print(audio_sequence)           #声音信号每一帧的“大小”
17 x_seq = np.arange(0,time,sample_time)
18 
19 plt.plot(x_seq,audio_sequence,'blue')
20 plt.xlabel("time (s)")
21 plt.show()

 WAV文件的存储格式

通过上述操作流程,了解了几个信息:

1.通过python现有包wave 可以获取wav文件几个基础信息,比如文件的声道,声音的采样宽度,帧速率,帧数,是否唯一标识,是否无损,关于WAV文件处理的入门信息,可先用几行代码获得WAV文件基本处理信息,然后将这些信息通过画图的形式绘画出来。

2.WAV文件中的时间,可以按照采样点数目,以及频率的大小获得,将来可以加窗口,进行数字信号处理上的一些操作,对声音信号作进一步的分析。

3.WAV文件中将声音信号存为n*1矩阵点或者n*2矩阵点,区分条件为是单声道还是双声道,对声音信号的研究可以转化为这个数组的研究。