使用Python对音频进行频谱分析

原文链接:http://blog.sina.com.cn/s/blog_40793e970102w3m2.html


本篇尝试使用Python对音频文件进行频谱分析。在语音识别领域对音频文件进行频谱分析是一项基本的数据处理过程,同时也为后续的特征分析准备数据。

直接上Python代码:

import wave
import pyaudio
import numpy
import pylab

#打开WAV文档,文件路径根据需要做修改
wf = wave.open("D:\\Python\\wavs\\Do-piano-2.20s.wav", "rb")
#创建PyAudio对象
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
nframes = wf.getnframes()
framerate = wf.getframerate()
#读取完整的帧数据到str_data中,这是一个string类型的数据
str_data = wf.readframes(nframes)
wf.close()
#将波形数据转换为数组
# A new 1-D array initialized from raw binary or text data in a string.
wave_data = numpy.fromstring(str_data, dtype=numpy.short)
#将wave_data数组改为2列,行数自动匹配。在修改shape的属性时,需使得数组的总长度不变。
wave_data.shape = -1,2
#将数组转置
wave_data = wave_data.T
#time 也是一个数组,与wave_data[0]或wave_data[1]配对形成系列点坐标
#time = numpy.arange(0,nframes)*(1.0/framerate)
#绘制波形图
#pylab.plot(time, wave_data[0])
#pylab.subplot(212)
#pylab.plot(time, wave_data[1], c="g")
#pylab.xlabel("time (seconds)")
#pylab.show()
#
# 采样点数,修改采样点数和起始位置进行不同位置和长度的音频波形分析
N=44100
start=0 #开始采样位置
df = framerate/(N-1) # 分辨率
freq = [df*n for n in range(0,N)] #N个元素
wave_data2=wave_data[0][start:start+N]
c=numpy.fft.fft(wave_data2)*2/N
#常规显示采样频率一半的频谱
d=int(len(c)/2)
#仅显示频率在4000以下的频谱
while freq[d]>4000:
d-=10
pylab.plot(freq[:d-1],abs(c[:d-1]),'r')
pylab.show()

实验结果
 
图1:本文博主发“啊”音的频谱分析图:
使用Python对音频进行频谱分析
图2:博主女儿(4岁半)发“啊”音的频谱分析图:
使用Python对音频进行频谱分析
图3:IPhone上音乐软件发“Do”音(C4)的频谱分析图:
使用Python对音频进行频谱分析
图4:博主发“Do”音的频谱分析图:
使用Python对音频进行频谱分析



  • 11
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
频谱分析是对音频进行信号处理的一种方法,它可以将音频信号转换为频谱图,从而可以更直观地了解音频的频率分布和能量分布情况。在Python中,可以使用一些库来进行音频频谱分析,其中比较常用的是librosa和pyaudio库。 下面是一个利用librosa库对音频进行频谱分析的示例代码: ```python import librosa import librosa.display import matplotlib.pyplot as plt # 读取音频文件 audio_file = "test.wav" y, sr = librosa.load(audio_file) # 计算短时傅里叶变换(STFT) stft = librosa.stft(y) # 计算功率谱密度(PSD) psd = librosa.power_to_db(abs(stft)**2) # 显示频谱图 librosa.display.specshow(psd, y_axis='linear', x_axis='time') plt.title('Power Spectrogram') plt.colorbar(format='%+2.0f dB') plt.tight_layout() plt.show() ``` 在上述代码中,首先使用librosa库中的load函数读取音频文件,并计算其短时傅里叶变换(STFT),再根据STFT计算功率谱密度(PSD)并绘制频谱图。其中,y和sr分别为音频数据和采样率,stft为STFT结果,psd为PSD结果。可以根据需要对频谱图进行调整和美化,例如修改颜色、坐标轴刻度、标题等。 下面是一个利用pyaudio库进行实时音频频谱分析的示例代码: ```python import pyaudio import numpy as np import matplotlib.pyplot as plt # 设置参数 CHUNK = 1024 # 每个缓冲区的大小 FORMAT = pyaudio.paInt16 # 采样格式 CHANNELS = 1 # 声道数 RATE = 44100 # 采样率 # 初始化pyaudio对象 p = pyaudio.PyAudio() # 打开音频流 stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) # 绘制频谱图 fig, ax = plt.subplots() x = np.arange(0, 2 * CHUNK, 2) line, = ax.plot(x, np.random.rand(CHUNK), '-', lw=2) ax.set_ylim(0, 255) ax.set_xlim(0, CHUNK) plt.xlabel('Frequency') plt.ylabel('Amplitude') # 实时更新频谱图 while True: data = stream.read(CHUNK) data = np.frombuffer(data, dtype=np.int16) fft = np.fft.fft(data) fft_abs = np.abs(fft)[:CHUNK] line.set_ydata(fft_abs) fig.canvas.draw() fig.canvas.flush_events() # 关闭音频流和pyaudio对象 stream.stop_stream() stream.close() p.terminate() ``` 在上述代码中,首先设置了一些参数,例如缓冲区大小、采样格式、声道数、采样率等。然后初始化了一个pyaudio对象,并打开了一个音频流,用于实时读取音频数据。接着绘制了一个空的频谱图,其中x轴表示频率,y轴表示振幅。最后使用一个while循环,不断读取音频数据并进行FFT变换,得到音频的频谱信息,然后实时更新频谱图。可以根据需要对频谱图进行调整和美化,例如修改颜色、坐标轴刻度、标题等。最后在合适的时候关闭音频流和pyaudio对象。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值