0

我是 Python 新手,所以如果我需要澄清任何事情,请告诉我。我正在尝试获取过滤后的 wav 文件的 rms 值。我可以在 pyaudio 流中使用 USB 麦克风录制 wav 文件,并将数据存储在块中,获取该块的 rms 值并将其存储在一个数组中,然后在遍历所有样本后,它只需要该数组的最大 rms 值(全部在函数 mic0() 下完成)。我以可以应用于过滤信号的不同格式重复此过程(因为我正在读取 wav 文件而不是流)并获得相同的结果。

我想获取记录的 wav 文件,对其进行过滤,然后再次获取 rms 值。但是在我使用了 butter_bandpass_filter 函数之后,每当我尝试计算 rms 值时,我总是得到 18000 左右。在将数据存储到函数中之前,我对其进行了标准化,使其与原始信号匹配(我大胆地检查了它)但这并不影响最终结果,因为我尝试删除它(y / max_int16),它仍然给我 18000。我也尝试弄乱数据类型,但我尝试的几乎所有东西都不起作用或导致过滤后的信号显示为 0。

这是代码:

import pyaudio
import wave
import audioop
import numpy as np
import datetime
import threading
import time
import os
from scipy.signal import butter, lfilter
from scipy.io.wavfile import write, read


os.chdir('/home/pi/Desktop/test') #mounting process
form_1 = pyaudio.paInt16 # 16-bit resolution
chans = 1 # 1 channel
samp_rate = 48000 # 48 kHz sampling rate
lowcut = 200
highcut = 20000
chunk = 1024 # samples for buffer
record_secs = 5 # seconds to record
dev_index0 = 2 # device index found by p.get_device_info_by_index(ii)
dev_index1 = 3

audio = pyaudio.PyAudio() # create pyaudio instantiation
print("Start")

# create pyaudio stream
stream0 = audio.open(format = form_1,rate = samp_rate,channels = chans, \
                    input_device_index = dev_index0,input = True, \
                    frames_per_buffer=chunk)
print("recording mic 1")

stream1 = audio.open(format = form_1,rate = samp_rate,channels = chans, \
                    input_device_index = dev_index1,input = True, \
                    frames_per_buffer=chunk)
print("recording mic 2")


def butter_bandpass(lowcut, highcut, samp_rate, order=5):
    nyq = 0.5 * samp_rate
    low = lowcut / nyq
    high = highcut / nyq
    b, a = butter(order, [low, high], btype='band', analog=False)
    return b, a

def butter_bandpass_filter(data, lowcut, highcut, samp_rate, order=5):
    b, a = butter_bandpass(lowcut, highcut, samp_rate, order=order)
    y = lfilter(b, a, data)
    return y

def mic0():
    global frames0, rms0, max0
    rms0 = []
    frames0 = []
    # loop through stream and append audio chunks to frame array
    for ii in range(0,int((samp_rate/chunk)*record_secs)):
        data0 = stream0.read(chunk, exception_on_overflow=False)
        frames0.append(data0)
        rms0.append(audioop.rms(data0, 2))
        max0 = np.max(rms0)
    print(max0)
      
def mic1():
    global frames1
    frames1 = []
    # loop through stream and append audio chunks to frame array
    for ii in range(0,int((samp_rate/chunk)*record_secs)):
        data1 = stream1.read(chunk, exception_on_overflow=False)
        frames1.append(data1)
       


# start threading
t1 = threading.Thread(target=mic0)
t2 = threading.Thread(target=mic1)
t1.start()
t2.start()
t1.join()
t2.join()

     
dt = str(datetime.datetime.now())
wav_output_filename = 'mic1.wav' # name of .wav file
wavefile = wave.open(wav_output_filename,'wb')
wavefile.setnchannels(chans)
wavefile.setsampwidth(audio.get_sample_size(form_1))
wavefile.setframerate(samp_rate)
wavefile.writeframes(b''.join(frames0))
wavefile.close()

    
dt = str(datetime.datetime.now())
wav_output_filename = 'mic2.wav' # name of .wav file
wavefile = wave.open(wav_output_filename,'wb')
wavefile.setnchannels(chans)
wavefile.setsampwidth(audio.get_sample_size(form_1))
wavefile.setframerate(samp_rate)
wavefile.writeframes(b''.join(frames1))
wavefile.close()


# stop the stream, close it, and terminate the pyaudio instantiation
stream0.stop_stream()
stream0.close()
stream1.stop_stream()
stream1.close
audio.terminate()
print("end")

# check method, compare to max0
samplerate, data = read('mic1.wav')
rms = []
for i in range(0, 240000, 1024):
    j = i + 1024
    sub = data[i:j]
    rms.append(audioop.rms(sub, 2))
    max_rms = np.max(rms)
## max rms of unfiltered signal
print(max_rms)

##filtering
max_int16 = 2**15
y = butter_bandpass_filter(data, lowcut, highcut, samplerate, order=5)
write('mic1_filtered.wav', samplerate, y / max_int16)
      
samplerate, data_filtered = read('mic1_filtered.wav')
data_filtered = data_filtered * max_int16
rms_filtered = []
for i in range(0, 240000, 1024):
    j = i + 1024
    sub = data_filtered[i:j]
    rms_filtered.append(audioop.rms(sub, 2))
    max_filtered = np.max(rms_filtered)
## max rms of filtered signal
print(max_filtered)
4

0 回答 0