前提・実現したいこと
環境音から取得した音声からfe1とfe2をリアルタイムで決めており、一定時間でfe1とfe2の値が変化するのですが
この2つの値をグラフに表示させる方法ってあるのでしょうか
発生している問題
下記のプログラミングのfe1とfe2の値をグラフ上に表示させることってできるのでしょうか
該当のソースコード
python
1# グラフ更新し続ける 2 3import pyaudio 4import time 5import sys 6import numpy as np 7import matplotlib.pyplot as plt 8from collections import deque 9from scipy import signal 10global min_id 11global fe1 12global fe2 13 14input_device = 0 # 入力デバイス 15output_device = 1 # 出力デバイス 16sampling_rate = 44100 # サンプリングレート マイクの特性に合わせる 17CHUNK = 2 ** 10 # データ長になる 18record_seconds = 1.0 # サンプリングする必要最低限の時間 19freq_limit = 12000 # Hz 20 21 22class Plot(): # もうすこしマトモなclassにしたい 23 def __init__(self): 24 self.fig, self.ax = plt.subplots(1, 1) 25 self.lines, = self.ax.plot(0, 0, color='b') # 第一プロット 26 self.lines2, = self.ax.plot(0, 0, color='c') # 第二プロット 27 self.lines3, = self.ax.plot(0, 0) # 第三プロット 28 self.points, = self.ax.plot(0, 0, color='orange', marker='o', markersize=15, linestyle='None') # ポイント 29 self.target, = self.ax.plot(0, 0, color='red', marker='o', markersize=15, linestyle='None') 30 plt.yscale('symlog') 31 32 def set(self, x_data, y_data): 33 self.lines.set_data(x_data, y_data) 34 self.ax.set_xlim(0, x_data.max()) 35 self.ax.set_ylim(0, y_data.max()) 36 37 def set2(self, x_data, y_data): 38 self.lines2.set_data(x_data, y_data) 39 # self.ax.set_xlim(0, x_data.max()) 40 # self.ax.set_ylim(0, y_data.max()) 41 42 def set3(self, x_data, y_data): 43 self.lines3.set_data(x_data, y_data) 44 # self.ax.set_xlim(0, x_data.max()) 45 # self.ax.set_ylim(0, y_data.max()) 46 47 48 def set_points(self, x_data, y_data): 49 self.points.set_data(x_data, y_data) 50 51 def set_targets(self, x_data, y_data): 52 self.targets(x_data, y_data) 53 54 def pause(self): 55 plt.pause(.01) 56 57 def close(self): 58 plt.close() 59 60 61class AudioFilter(): 62 def __init__(self): 63 # オーディオに関する設定 64 self.p = pyaudio.PyAudio() 65 self.channels = 1 # モノラル 66 self.format = pyaudio.paFloat32 67 self.voice_data = deque([], maxlen=int(sampling_rate * record_seconds)) 68 self.filtered_data = deque([], maxlen=int(sampling_rate * record_seconds)) 69 self.noise_data = deque([], maxlen=int(sampling_rate * record_seconds)) 70 self.rate = sampling_rate 71 self.chunk = CHUNK 72 self.idt = '' 73 self.fe1 = 100/(sampling_rate/2) 74 self.fe2 = 10000/(sampling_rate/2) 75 self.min_id = [] 76 self.minimum = [] 77 #self.filter1 = signal.firwin(numtaps=255, cutoff=[self.fe1,self.fe2], pass_zero=False) 78 self.audio_data = '' 79 # self.time = {} 80 self.stock_sec = record_seconds 81 self.buf = np.array([]) 82 83 self.stream = self.p.open( 84 format=self.format, 85 channels=self.channels, 86 rate=self.rate, 87 output=True, 88 input=True, 89 frames_per_buffer=self.chunk, # バッファごとのフレーム長を指定 90 input_device_index=input_device, 91 output_device_index=output_device, 92 stream_callback=self.callback # コールバック関数の指定 93 ) 94 95 # コールバック関数(chunk貯まるたびに呼び出される。長い処理を書くと再帰が深くなる) 96 def callback(self, in_data, frame_count, time_info, status): 97 filter1 = signal.firwin(numtaps=255, cutoff=[self.fe1, self.fe2], pass_zero=False)#フィルタの定義 98 99 #min_idに値が入ったとき、それに合わせカットオフ周波数を変更 100 if len(self.minimum) >= 1: 101 j = 0 102 #サンプリングレートの1/2以上の値を除外 103 for i in self.minimum: 104 if i > 20000: 105 j += 1 106 else: 107 break 108 #カットオフ周波数の変更 109 self.fe1 = self.minimum[j]/ (sampling_rate / 2) 110 self.fe2 = (self.minimum[j] +1000)/ (sampling_rate / 2) 111 112 self.buf = np.frombuffer(in_data, dtype="float32") 113 filt = signal.lfilter(filter1, 1, self.buf) 114 self.noise_data.extend(self.buf) # 環境音データ 115 # self.voice_data.extend(self.buf) # 加工前の音声データ 116 self.filtered_data.extend(filt) # 加工後の音声データ 117 out_data = filt.astype("float32").tostring() # 加工した音声データを出力 118 return (out_data, pyaudio.paContinue) 119 120 def filtering(self): 121 return 0 122 123 def close(self): 124 self.p.terminate() 125 126 127if __name__ == '__main__': 128 129 freqList = np.fft.fftfreq(int(sampling_rate * record_seconds), d=1.0 / sampling_rate) 130 pt = Plot() # プロット用 131 132 af = AudioFilter() # AudioFilterのインスタンス 133 af.stream.start_stream() # ストリーミングを始める 134 135 # ノンブロッキングなので好きなことをしていていい場所 136 while af.stream.is_active(): 137 if (len(af.noise_data) >= int(sampling_rate * record_seconds)): 138 139 data = np.array(af.noise_data) 140 af.noise_data.clear() 141 x = np.fft.fft(data) 142 143 filtered_data = np.array(af.filtered_data) 144 af.filtered_data.clear() 145 fft_filtered_data = np.fft.fft(filtered_data) 146 147 amplitude = np.array([np.sqrt(c.real ** 2 + c.imag ** 2) for c in x]) # 振幅スペクト 148 amplitude_filtered_data = np.array([np.sqrt(c.real ** 2 + c.imag ** 2) for c in fft_filtered_data]) 149 pt.set(freqList[:int(len(freqList) / 2)], amplitude[:int(len(freqList) / 2)]) # 環境音プロット 150 pt.set2(freqList[:int(len(freqList) / 2)], amplitude_filtered_data[:int(len(freqList) / 2)]) # 加工後音声プロット 151 152 # 下限ピーク検出 153 af.min_id = signal.argrelmin(amplitude, order=1000) # small peaks 154 ary = amplitude[af.min_id] 155 pt.set_points(af.min_id, ary) 156 targets = np.sort(ary) 157 pt.pause() 158 print(ary) 159 160 # 下限ピークを昇順に並び替え 161 af.minimum = af.min_id[0][ary.argsort()] 162 print(af.minimum) 163 164 pt.close() 165 166 # ストリーミングを止める場所 167 af.stream.stop_stream() 168 af.stream.close() 169 af.close()
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/06 05:54