介绍
- 声音是什么呢?
- 声音的原理是什么?
- 我们应该如何去分析声音数据?
声音是振动产生的声波,通过介质(气体、固体、液体)传播并能被人或动物听觉器官所感知的波动现象。
声音是一种波动,当演奏乐器、拍打一扇门或者敲击桌面时,声音的振动会引起介质——空气分子有节奏的振动,使周围的空气产生疏密变化,形成疏密相间的纵波,这就产生了声波,这种现象会一直延续到振动消失为止。声音总可以被分解为不同频率不同强度正弦波的叠加。这种变换(或分解)的过程,称为傅里叶变换。
上个问题中,提到的傅里叶变换,就是对声音(声波)的处理,通过转换,使之变为数学中的周期函数形式。音波常简化为正弦平面波的合成,各平面波可以用以下的性质来描述:
- 频率
频率越大,音调越高;频率越小,音调越低。(介质相同时,fλ成反比) - 波长
波长越短,音调越高;波长越长,音调越低。(介质相同时,fλ成反比) - 波数
- 振幅
振幅越大,音量(响度)越大;振幅越小,音量越小。 - 声压
- 音强
- 音速
- 方向
- 音色
波形
一、数据集
下载天池数据集并解压
wget http://tianchi-competition.oss-cn-hangzhou.aliyuncs.com/531887/train_sample.zip
unzip -qq train_sample.zip
rm train_sample.zip
wget http://tianchi-competition.oss-cn-hangzhou.aliyuncs.com/531887/test_a.zip
unzip -qq test_a.zip
rm test_a.zip
二、数据处理与分析
1.导入音频处理库
安装库
pip install librosa
导入库
import librosa
import librosa.display
2.查看数据基本情况
在数据分析前,对数据进行统计,了解数据的基本情况。
import os
voice_path = './train_sample'
def look_data():
# 音频类别文件夹个数
print(f'音频文件夹的个数: {len(os.listdir(voice_path))}')
voice_total = 0
single_label = {}
for ind, label_name in enumerate(os.listdir(voice_path)):
file_path = voice_path + '/' + label_name
single_num = len(os.listdir(file_path))
single_label[label_name] = single_num
voice_total += single_num
print(f'音频文件总量: {voice_total}')
print(f'{"序号":<5}{"类别":<15}{"数量":<10}{"占比"}')
for ind, (key, value) in enumerate(single_label.items()):
print(f'{ind:<5}{key:<20}{value:<10}{value / voice_total:.2%}')
look_data()
输出
3、查看音频特征
使用IPython.display中的Audio()来对加载需要播放的音频文件,所以其中需要的参数为音频文件的路径
import IPython.display as ipd
# 播放芦荟的声音
ipd.Audio('./train_sample/aloe/24EJ22XBZ5.wav')
使用librosa模块加载音频文件,librosa.load()加载的音频文件,默认采样率(sr)为22050HZ mono。我们可以通过librosa.load(path,sr=44100)来更改采样频率
data1, sampling_rate1 = librosa.load('./train_sample/aloe/24EJ22XBZ5.wav')
画出波形幅度包络图
# 芦荟的波形幅度包络
plt.figure(figsize=(14, 5))
librosa.display.waveplot(data1,sr=sampling_rate1)
声谱图(spectrogram)是声音或其他信号的频率随时间变化时的频谱(spectrum)的一种直观表示。声谱图有时也称sonographs,voiceprints,或者voicegrams。当数据以三维图形表示时,可称其为瀑布图(waterfalls)。在二维数组中,第一个轴是频率,第二个轴是时间。我们使用librosa.display.specshow来显示声谱图。
# 芦荟的声谱图
plt.figure(figsize=(20, 10))
D = librosa.amplitude_to_db(np.abs(librosa.stft(data1)), ref=np.max)
plt.subplot(4, 2, 1)
librosa.display.specshow(D, y_axis='linear')
plt.colorbar(format='%+2.0f dB')
plt.title('Linear-frequency power spectrogram of aloe')