開発環境
- Google Colob T4(Free)
音の解析
以下で sample.wav
に対する周波数別の解析をします
import numpy as np import matplotlib.pyplot as plt import japanize_matplotlib from scipy.io import wavfile # WAVファイルの読み込み sample_rate, data = wavfile.read('sample.wav') # データがステレオ(2チャンネル)の場合、モノラルに変換 if data.ndim == 2: data = data.mean(axis=1) # FFTの実行 N = len(data) fft_data = np.fft.fft(data) fft_freq = np.fft.fftfreq(N, 1/sample_rate) # 正の周波数成分のみを抽出 positive_freqs = fft_freq[:N // 2] positive_fft_data = np.abs(fft_data[:N // 2]) # プロット plt.figure(figsize=(10, 6)) plt.plot(positive_freqs, positive_fft_data) plt.xlabel('周波数 [Hz]', fontsize=10) plt.ylabel('振幅', fontsize=10) plt.title('FFTによる周波数スペクトル', fontsize=12) plt.grid(True) plt.show()
特定の周波数のみの音にする
以下で特定の周波数のみににした後に、逆フーリエ変換で元に戻します
import numpy as np import matplotlib.pyplot as plt import japanize_matplotlib from scipy.io import wavfile from IPython.display import Audio, display # WAVファイルの読み込み sample_rate, data = wavfile.read('sample.wav') # データがステレオ(2チャンネル)の場合、モノラルに変換 if data.ndim == 2: data = data.mean(axis=1) # FFTの実行 N = len(data) fft_data = np.fft.fft(data) fft_freq = np.fft.fftfreq(N, 1/sample_rate) # 正の周波数成分のみを抽出 positive_freqs = fft_freq[:N // 2] positive_fft_data = np.abs(fft_data[:N // 2]) filtered_indices = (positive_freqs >= 500) & (positive_freqs <= 2500) # フィルタリングを元のFFTデータに反映 filtered_fft_full = np.zeros_like(fft_data) filtered_fft_full[:N // 2][filtered_indices] = fft_data[:N // 2][filtered_indices] filtered_fft_full[-(N // 2):][filtered_indices] = fft_data[-(N // 2):][filtered_indices] # 逆FFTで音声信号を再構築 filtered_data = np.fft.ifft(filtered_fft_full).real # WAVファイルとして保存 filtered_filename = 'sample_remove1.wav' wavfile.write(filtered_filename, sample_rate, filtered_data.astype(np.int16)) # フィルタリングしたFFTデータの正の周波数成分のみを抽出 filtered_positive_fft_data = np.abs(filtered_fft_full[:N // 2]) # プロット plt.figure(figsize=(10, 6)) plt.plot(positive_freqs[filtered_indices], filtered_positive_fft_data[filtered_indices]) plt.xlabel('周波数 [Hz]', fontsize=10) plt.ylabel('振幅 (Amplitude)', fontsize=10) # 振幅を明確にするためのラベル plt.title('FFTによる周波数スペクトル(特定の範囲の成分)', fontsize=12) plt.grid(True) plt.show() # 作成された音声を再生 display(Audio(filtered_filename))