Py学习  »  Python

python实现Wav信号的录制与频谱分析

人間矢格 • 3 年前 • 521 次点击  

##matlab转python实现(四)
##后附完整代码及windows环境下的pyaudio库的安装。

Wav信号的录制与频谱分析

程序结构

录制Wav音频
读取音频信号
时域波形
频域波形

自定义函数

#定义sound recoding 函数

参数为录音时间t。

def


    
 sound_rec(t):
  • 1
  • 1
#定义wav文件读取函数

参数为wav文件的路径path,代码中因为保存的录音文件就在该代码路径下,可以不用输入绝对路径。返回值为:左右声道的波形数组wave_data,采样率framerate,采样率*时间nframes

def wave_read(path):
  • 1
  • 1
#定义画出时域上的波形图函数time plot

第一个参数为采样率,第二个参数为采样率*时间,第三个参数为左右声道的数据wave data list

def time_plt(frames,nframes,wave):
  • 1
  • 1
#定义画出信号频谱上的波形图函数frequence plot

第一个参数为采样率,第二个参数为左右声道的数据wave data list

def freq_plt(frames,wave):
  • 1
  • 1

主要进程

a.

录制音频,将音频保存在文件路径下的output.wav文件中。(本步骤可以忽略,在已经录制过音频的情况下。)

b.

读取音频信号,将双声道信号的信息存储在数组中,并得出采样率,以及信号长度。

c.

做出时域上的波形图,频域上,进行傅里叶变换,单边谱处理以及归一化处理,得出频域幅度谱,最后一起显示。

附完整代码

import wave
import pyaudio
import numpy
from pyaudio import PyAudio
import matplotlib.pyplot as plt

#定义sound recoding 函数,其参数为录音时间t
def sound_rec(t):
    # 定义数据流块
    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 2
    RATE = 44100
    # 录音时间
    RECORD_SECONDS = t
    # 要写入的文件名
    WAVE_OUTPUT_FILENAME = "output.wav"
    # 创建PyAudio对象
    p = pyaudio.PyAudio()
    # 打开数据流
    stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)
    print("start recording")
    # 开始录音
    frames = []
    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)
    print("done recording")
    # 停止数据流
    stream.stop_stream()
    stream.close()
    # 关闭PyAudio
    p.terminate()
    # 写入录音文件
    wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

#定义wav文件读取函数,其参数为wav文件的路径path
#返回值为:左右声道的波形数组wave_data,采样率framerate,采样率*时间nframes
def wave_read(path):
    wf = wave.


    
open(path, 'rb')
    # 创建PyAudio对象
    p = 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()
    # 将波形数据转换成数组
    wave_data = numpy.fromstring(str_data, dtype=numpy.short)
    # 将wave_data数组改为2列,行数自动匹配
    wave_data.shape = -1,2
    # 将数组转置
    wave_data = wave_data.T
    return wave_data,framerate,nframes

#定义画出时域上的波形图函数time plot
#第一个参数为采样率,第二个参数为采样率*时间,第三个参数为左右声道的数据wave data list
def time_plt(frames,nframes,wave):
    # time也是一个数组,与wave_data[0]或wave_data[1]配对形成系列点坐标
    time = numpy.arange(0, nframes)*(1.0/frames)
    # 绘制波形图
    plt.figure(num=1,figsize=(6,4))
    plt.subplot(211)
    plt.plot(time, wave[0], c='r')
    plt.subplot(212)
    plt.plot(time, wave[1], c='g')
    plt.xlabel('time (seconds)')
    plt.ylabel('ampliude')

#定义画出信号频域上的波形函数frequence plot
#第一个参数为采样率,第二个参数为左右声道的数据wave data list
def freq_plt(frames,wave):
    # 采样点数,修改采样点数和起始位置进行不同位置和长度的音频波形分析
    N = 44100
    start = 0  # 开始采样位置
    df = frames/(N-1)  # 分辨率
    freq = [df*n for n in range(0, N)]  # N个元素
    wave_data2 = wave[0][start:start+N]
    c = numpy.fft.fft(wave_data2)*2/N
    # 常规显示采样频率一半的频谱
    d = int(len(c)/2)
    # 仅显示频率在4000以下的频谱
    while freq[d] > 4000:
        d -= 10
    plt.figure(num=2,figsize=(6,4))
    plt.plot(freq[:d-1


    
], abs(c[:d-1]), 'r')

#sound_rec(5)
wave,frames,nframes=wave_read('output.wav')
time_plt(frames,nframes,wave)
freq_plt(frames,wave)
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

windows下安装pyaudio库

建议工具:一个python编辑器(用来查看你的python.exe存放的位置),windows powershell。

首先下载一个

直接使用pip install来安装会报错error:failed building wheel for pyaudio。

找适合自己的版本,本机环境为window+python3.7选择了PyAudio-0.2.11-cp37-cp37m-win_amd64.whl。自己看情况选择。

下载完后放在自己的python的Scripts文件夹下;这里找不到可以在自己的python编辑器里面找路径,会方便一点。

之后通过powershell进入scripts文件夹下:

~$: cd Scripts
~/Scripts$:  pip install  PyAudio-0.2.11-cp37-cp37m-win_amd64.whl
~/Scripts$:  pip install pyaudio
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

最后试用上述代码,没报错就为成功。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/73429
 
521 次点击  
文章 [ 1 ]  |  最新文章 3 年前