Python音频信号分析

一、录制音频

1、定义

(1)定义数据流

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100

(2)设置录音时间

RECORD_SECONDS = 10

(3)打开数据流

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

2、录音

frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)
print("* done recording")

二、处理音频

1、批量读取.wav文件名

import os
 
filepath = "./data/" #添加路径
filename= os.listdir(filepath) #得到文件夹下的所有文件名称 
for file in filename:
    print(filepath+file)

这里用到字符串路径:

  1. 通常意义字符串(str)
  2. 原始字符串,以大写R 或 小写r开始,r’’,不对特殊字符进行转义
  3. Unicode字符串,u’’ basestring子类

2、读取文件

wave.open(file,mode)

mode可以是:
‘rb’,读取文件;
‘wb’,写入文件;
不支持同时读/写操作。
Wave_read.getparams用法:

f = wave.open(file,'rb')
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]

其中最后一行为常用的音频参数:
nchannels:声道数
sampwidth:量化位数(byte)
framerate:采样频率
nframes:采样点数

  • 单通道
import wave
import matplotlib.pyplot as plt
import numpy as np
import os
 
filepath = "./data/" #添加路径
filename= os.listdir(filepath) #得到文件夹下的所有文件名称 
f = wave.open(filepath+filename[1],'rb')
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
strData = f.readframes(nframes)#读取音频,字符串格式
waveData = np.fromstring(strData,dtype=np.int16)#将字符串转化为int
waveData = waveData*1.0/(max(abs(waveData)))#wave幅值归一化
# plot the wave
time = np.arange(0,nframes)*(1.0 / framerate)
plt.plot(time,waveData)
plt.xlabel("Time(s)")
plt.ylabel("Amplitude")
plt.title("Single channel wavedata")
plt.grid('on')#标尺,on:有,off:无。

结果图:
在这里插入图片描述

  • 多通道:
    这里通道数为3,主要借助np.reshape一下,其他同单通道处理完全一致;
# -*- coding: utf-8 -*-
"""
Created on Wed May  3 12:15:34 2017
 
@author: Nobleding
"""
 
import wave
import matplotlib.pyplot as plt
import numpy as np
import os
 
filepath = "./data/" #添加路径
filename= os.listdir(filepath) #得到文件夹下的所有文件名称 
f = wave.open(filepath+filename[0],'rb')
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
strData = f.readframes(nframes)#读取音频,字符串格式
waveData = np.fromstring(strData,dtype=np.int16)#将字符串转化为int
waveData = waveData*1.0/(max(abs(waveData)))#wave幅值归一化
waveData = np.reshape(waveData,[nframes,nchannels])
f.close()
# plot the wave
time = np.arange(0,nframes)*(1.0 / framerate)
plt.figure()
plt.subplot(5,1,1)
plt.plot(time,waveData[:,0])
plt.xlabel("Time(s)")
plt.ylabel("Amplitude")
plt.title("Ch-1 wavedata")
plt.grid('on')#标尺,on:有,off:无。
plt.subplot(5,1,3)
plt.plot(time,waveData[:,1])
plt.xlabel("Time(s)")
plt.ylabel("Amplitude")
plt.title("Ch-2 wavedata")
plt.grid('on')#标尺,on:有,off:无。
plt.subplot(5,1,5)
plt.plot(time,waveData[:,2])
plt.xlabel("Time(s)")
plt.ylabel("Amplitude")
plt.title("Ch-3 wavedata")
plt.grid('on')#标尺,on:有,off:无。
plt.show()

结果图:
在这里插入图片描述

3、写入文件

涉及到的主要指令有三个:

  • 参数设置:
nchannels = 1 #单通道为例
sampwidth = 2
fs = 8000
data_size = len(outData)
framerate = int(fs)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
outwave.setparams((nchannels, sampwidth, framerate, nframes, comptype, compname))

单通道数据写入:

import wave
#import matplotlib.pyplot as plt
import numpy as np
import os
import struct
 
#wav文件读取
filepath = "./data/" #添加路径
filename= os.listdir(filepath) #得到文件夹下的所有文件名称 
f = wave.open(filepath+filename[1],'rb')
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
strData = f.readframes(nframes)#读取音频,字符串格式
waveData = np.fromstring(strData,dtype=np.int16)#将字符串转化为int
waveData = waveData*1.0/(max(abs(waveData)))#wave幅值归一化
f.close()
#wav文件写入
outData = waveData#待写入wav的数据,这里仍然取waveData数据
outfile = filepath+'out1.wav'
outwave = wave.open(outfile, 'wb')#定义存储路径以及文件名
nchannels = 1
sampwidth = 2
fs = 8000
data_size = len(outData)
framerate = int(fs)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
outwave.setparams((nchannels, sampwidth, framerate, nframes,
    comptype, compname))
 
for v in outData:
        outwave.writeframes(struct.pack('h', int(v * 64000 / 2)))#outData:16位,-32767~32767,注意不要溢出
outwave.close()

多通道数据写入:

import wave
#import matplotlib.pyplot as plt
import numpy as np
import os
import struct
 
#wav文件读取
filepath = "./data/" #添加路径
filename= os.listdir(filepath) #得到文件夹下的所有文件名称 
f = wave.open(filepath+filename[0],'rb')
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
strData = f.readframes(nframes)#读取音频,字符串格式
waveData = np.fromstring(strData,dtype=np.int16)#将字符串转化为int
waveData = waveData*1.0/(max(abs(waveData)))#wave幅值归一化
waveData = np.reshape(waveData,[nframes,nchannels])
f.close()
#wav文件写入
outData = waveData#待写入wav的数据,这里仍然取waveData数据
outData = np.reshape(outData,[nframes*nchannels,1])
outfile = filepath+'out2.wav'
outwave = wave.open(outfile, 'wb')#定义存储路径以及文件名
nchannels = 3
sampwidth = 2
fs = 8000
data_size = len(outData)
framerate = int(fs)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
outwave.setparams((nchannels, sampwidth, framerate, nframes,
    comptype, compname))
 
for v in outData:
        outwave.writeframes(struct.pack('h', int(v * 64000 / 2)))#outData:16位,-32767~32767,注意不要溢出
outwave.close()

4、播放音频

import wave
import pyaudio 
import os
 
#wav文件读取
filepath = "./data/" #添加路径
filename= os.listdir(filepath) #得到文件夹下的所有文件名称 
f = wave.open(filepath+filename[0],'rb')
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
#instantiate PyAudio 
p = pyaudio.PyAudio() 
#define stream chunk  
chunk = 1024 
#打开声音输出流
stream = p.open(format = p.get_format_from_width(sampwidth),
                channels = nchannels,
                rate = framerate, 
                output = True) 
 
#写声音输出流到声卡进行播放
data = f.readframes(chunk) 
i=1
while True:
    data = f.readframes(chunk)
    if data == b'': break
    stream.write(data)   
f.close()
#stop stream 
stream.stop_stream() 
stream.close() 
#close PyAudio 
p.terminate() 
发布了6 篇原创文章 · 获赞 1 · 访问量 291

猜你喜欢

转载自blog.csdn.net/weixin_43899333/article/details/104922569