[Python] wavファイル再生時に波形を表示する方法
Pythonでwavファイルを再生しながら波形を表示するには、matplotlib
とsounddevice
などのライブラリを使用します。
scipy.io.wavfile
でwavファイルを読み込み、matplotlib
で波形をプロットします。
再生はsounddevice.play()
を使います。
具体的には、wavファイルを読み込んで波形データを取得し、matplotlib
でリアルタイムに更新しながら再生することで、視覚的に波形を確認できます。
Pythonでwavファイルを再生する方法
sounddeviceライブラリのインストール
Pythonでwavファイルを再生するためには、まずsounddevice
ライブラリをインストールする必要があります。
このライブラリは、音声の再生や録音を簡単に行うことができます。
以下のコマンドを使用してインストールします。
pip install sounddevice
sounddeviceを使ったwavファイルの再生
sounddevice
ライブラリを使ってwavファイルを再生する方法は非常にシンプルです。
以下のサンプルコードでは、sounddevice
とscipy.io.wavfile
を使用してwavファイルを読み込み、再生します。
import sounddevice as sd
from scipy.io import wavfile
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
# wavファイルの再生
sd.play(data, sample_rate)
# 再生が終わるまで待機
sd.wait()
このコードを実行すると、指定したsample.wav
ファイルが再生されます。
sd.play()関数
で音声を再生し、sd.wait()
で再生が完了するまでプログラムを待機させます。
再生中のエラー処理とデバッグ方法
音声再生中にエラーが発生することがあります。
以下のようなエラー処理を追加することで、問題を特定しやすくなります。
import sounddevice as sd
from scipy.io import wavfile
try:
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
# wavファイルの再生
sd.play(data, sample_rate)
# 再生が終わるまで待機
sd.wait()
except FileNotFoundError:
print("指定したファイルが見つかりません。")
except Exception as e:
print(f"エラーが発生しました: {e}")
このコードでは、ファイルが見つからない場合やその他のエラーが発生した場合に、適切なメッセージを表示します。
これにより、デバッグが容易になります。
wavファイルの波形を表示する方法
matplotlibライブラリのインストール
wavファイルの波形を表示するためには、matplotlib
ライブラリを使用します。
以下のコマンドを実行して、matplotlib
をインストールします。
pip install matplotlib
scipy.io.wavfileでwavファイルを読み込む
scipy.io.wavfile
を使用して、wavファイルを読み込むことができます。
以下のサンプルコードでは、wavファイルを読み込み、サンプルレートとデータを取得します。
from scipy.io import wavfile
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
print(f"サンプルレート: {sample_rate} Hz")
print(f"データの形状: {data.shape}")
このコードを実行すると、wavファイルのサンプルレートとデータの形状が表示されます。
波形データの取得と加工
wavファイルから取得したデータは、通常は多次元配列として表現されます。
モノラル音声の場合は1次元配列、ステレオ音声の場合は2次元配列になります。
以下のコードでは、モノラル音声データを取得し、必要に応じて正規化します。
import numpy as np
# モノラル音声データの取得
if len(data.shape) > 1:
data = data[:, 0] # ステレオの場合、左チャンネルを選択
# データの正規化
data = data / np.max(np.abs(data))
このコードでは、ステレオ音声の場合は左チャンネルのデータを選択し、データを-1から1の範囲に正規化しています。
matplotlibで波形をプロットする方法
matplotlib
を使用して、波形をプロットすることができます。
以下のサンプルコードでは、時間軸に対して波形データをプロットします。
import matplotlib.pyplot as plt
# 時間軸の作成
time = np.linspace(0, len(data) / sample_rate, num=len(data))
# 波形のプロット
plt.figure(figsize=(10, 4))
plt.plot(time, data)
plt.title('Wavファイルの波形')
plt.xlabel('時間 (秒)')
plt.ylabel('振幅')
plt.grid()
plt.show()
このコードを実行すると、wavファイルの波形が表示されます。
時間軸はサンプル数に基づいて計算され、振幅がプロットされます。
これにより、音声データの視覚的な理解が得られます。
wavファイル再生と波形表示の統合
再生と波形表示を同時に行う方法
wavファイルの再生と波形表示を同時に行うためには、sounddevice
とmatplotlib
を組み合わせて使用します。
以下のサンプルコードでは、音声を再生しながら波形を表示します。
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
data = data / np.max(np.abs(data)) # 正規化
# 時間軸の作成
time = np.linspace(0, len(data) / sample_rate, num=len(data))
# 波形のプロット
plt.figure(figsize=(10, 4))
plt.plot(time, data)
plt.title('Wavファイルの波形')
plt.xlabel('時間 (秒)')
plt.ylabel('振幅')
plt.grid()
# wavファイルの再生
sd.play(data, sample_rate)
sd.wait() # 再生が終わるまで待機
plt.show() # 波形を表示
このコードでは、音声を再生しながら波形を表示します。
再生が完了した後に波形が表示されます。
matplotlibのリアルタイム更新機能を使う
matplotlib
のリアルタイム更新機能を使用することで、再生中に波形を動的に更新することができます。
以下のサンプルコードでは、音声再生中に波形をリアルタイムで更新します。
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
data = data / np.max(np.abs(data)) # 正規化
# 時間軸の作成
time = np.linspace(0, len(data) / sample_rate, num=len(data))
# 波形のプロット
plt.ion() # インタラクティブモードをオン
fig, ax = plt.subplots(figsize=(10, 4))
line, = ax.plot(time, data, color='b')
ax.set_title('Wavファイルの波形')
ax.set_xlabel('時間 (秒)')
ax.set_ylabel('振幅')
ax.grid()
# wavファイルの再生
sd.play(data, sample_rate)
# 再生中に波形を更新
for i in range(len(data)):
line.set_ydata(data[:i]) # 波形を更新
plt.pause(0.01) # 更新間隔
sd.wait() # 再生が終わるまで待機
plt.ioff() # インタラクティブモードをオフ
plt.show()

このコードでは、音声が再生されると同時に波形がリアルタイムで更新されます。
再生中に波形を動的に更新する方法
再生中に波形を動的に更新するためには、matplotlib
のpause関数
を使用します。
上記のコード例でも示したように、plt.pause()
を使って一定の間隔で波形を更新することができます。
再生と波形表示の同期を取るための工夫
再生と波形表示の同期を取るためには、音声の再生時間に基づいて波形を更新する必要があります。
以下のように、再生中の時間を取得し、それに応じて波形を表示することができます。
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np
import time as time_module # Renaming the time module to avoid conflict
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
data = data / np.max(np.abs(data)) # 正規化
# 時間軸の作成
time_axis = np.linspace(0, len(data) / sample_rate, num=len(data))
# 波形のプロット
plt.figure(figsize=(10, 4))
plt.plot(time_axis, data)
plt.title('Wavファイルの波形')
plt.xlabel('時間 (秒)')
plt.ylabel('振幅')
plt.grid()
# wavファイルの再生
sd.play(data, sample_rate)
# 再生中の時間を取得し、波形を更新
start_time = time_module.time() # Using the renamed time module
while sd.get_stream().active:
elapsed_time = time_module.time() - start_time
plt.xlim(0, elapsed_time) # x軸の範囲を更新
plt.pause(0.02) # 更新間隔
sd.wait() # 再生が終わるまで待機
plt.show()
このコードでは、再生中の経過時間に基づいてx軸の範囲を更新し、波形を表示します。
これにより、再生と波形表示の同期が取れます。
応用例:音声処理と波形表示
音声フィルタリングと波形の変化を確認する
音声フィルタリングを行うことで、特定の周波数帯域を強調したり、ノイズを除去したりすることができます。
以下のサンプルコードでは、ローパスフィルタを適用し、フィルタリング前後の波形を比較します。
import numpy as np
import sounddevice as sd
from scipy.io import wavfile
from scipy.signal import butter, lfilter
import matplotlib.pyplot as plt
# ローパスフィルタの設計
def butter_lowpass(cutoff, fs, order=5):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low', analog=False)
return b, a
def lowpass_filter(data, cutoff, fs, order=5):
b, a = butter_lowpass(cutoff, fs, order=order)
y = lfilter(b, a, data)
return y
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
data = data / np.max(np.abs(data)) # 正規化
# フィルタリング
cutoff = 1000 # カットオフ周波数
filtered_data = lowpass_filter(data, cutoff, sample_rate)
# 波形のプロット
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(data, label='元の波形')
plt.title('元の波形')
plt.xlabel('サンプル数')
plt.ylabel('振幅')
plt.grid()
plt.subplot(2, 1, 2)
plt.plot(filtered_data, label='フィルタリング後の波形', color='orange')
plt.title('フィルタリング後の波形')
plt.xlabel('サンプル数')
plt.ylabel('振幅')
plt.grid()
plt.tight_layout()
plt.show()
# フィルタリング後の音声再生
sd.play(filtered_data, sample_rate)
sd.wait()
このコードでは、ローパスフィルタを適用した後、元の波形とフィルタリング後の波形を比較して表示します。
音量の変化をリアルタイムで表示する
音声の音量をリアルタイムで表示するためには、音声データの振幅を計算し、グラフにプロットします。
以下のサンプルコードでは、音声再生中に音量の変化を表示します。
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
data = data / np.max(np.abs(data)) # 正規化
# 音量の計算
def calculate_volume(data):
return np.sqrt(np.mean(data**2))
# 波形のプロット
plt.ion() # インタラクティブモードをオン
fig, ax = plt.subplots(figsize=(10, 4))
line, = ax.plot([], [], color='b')
ax.set_ylim(0, 1)
ax.set_xlim(0, 1)
ax.set_title('音量の変化')
ax.set_xlabel('時間 (秒)')
ax.set_ylabel('音量')
ax.grid()
# wavファイルの再生
sd.play(data, sample_rate)
# 音量の変化をリアルタイムで表示
while sd.get_stream().active:
volume = calculate_volume(data)
line.set_xdata(np.append(line.get_xdata(), sd.get_stream().time))
line.set_ydata(np.append(line.get_ydata(), volume))
plt.pause(0.1) # 更新間隔
sd.wait() # 再生が終わるまで待機
plt.ioff() # インタラクティブモードをオフ
plt.show()
このコードでは、音声再生中に音量の変化をリアルタイムで表示します。
複数のwavファイルを同時に再生・表示する
複数のwavファイルを同時に再生し、それぞれの波形を表示することも可能です。
以下のサンプルコードでは、2つのwavファイルを同時に再生し、波形を比較します。
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np
# wavファイルの読み込み
sample_rate1, data1 = wavfile.read('sample1.wav')
sample_rate2, data2 = wavfile.read('sample2.wav')
# データの正規化
data1 = data1 / np.max(np.abs(data1))
data2 = data2 / np.max(np.abs(data2))
# 波形のプロット
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(data1, label='サンプル1')
plt.title('サンプル1の波形')
plt.xlabel('サンプル数')
plt.ylabel('振幅')
plt.grid()
plt.subplot(2, 1, 2)
plt.plot(data2, label='サンプル2', color='orange')
plt.title('サンプル2の波形')
plt.xlabel('サンプル数')
plt.ylabel('振幅')
plt.grid()
plt.tight_layout()
plt.show()
# 複数のwavファイルを同時に再生
sd.play(data1, sample_rate1)
sd.play(data2, sample_rate2)
sd.wait() # 再生が終わるまで待機
このコードでは、2つのwavファイルを同時に再生し、それぞれの波形を表示します。
スペクトログラム表示との併用
音声データの周波数成分を視覚化するために、スペクトログラムを表示することもできます。
以下のサンプルコードでは、wavファイルのスペクトログラムを表示します。
import numpy as np
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
from scipy.signal import spectrogram
# wavファイルの読み込み
sample_rate, data = wavfile.read('sample.wav')
data = data / np.max(np.abs(data)) # 正規化
# スペクトログラムの計算
frequencies, times, Sxx = spectrogram(data, sample_rate)
# スペクトログラムのプロット
plt.figure(figsize=(10, 6))
plt.pcolormesh(times, frequencies, 10 * np.log10(Sxx), shading='gouraud')
plt.title('スペクトログラム')
plt.ylabel('周波数 (Hz)')
plt.xlabel('時間 (秒)')
plt.colorbar(label='強度 (dB)')
plt.ylim(0, 2000) # 表示する周波数範囲
plt.show()
# 音声の再生
sd.play(data, sample_rate)
sd.wait() # 再生が終わるまで待機
このコードでは、wavファイルのスペクトログラムを表示し、音声を再生します。
これにより、音声データの周波数成分を視覚的に理解することができます。
まとめ
この記事では、Pythonを使用してwavファイルを再生し、その波形を表示する方法について詳しく解説しました。
また、音声処理の応用例として、フィルタリングや音量の変化の表示、複数の音声ファイルの同時再生、さらにはスペクトログラムの表示方法についても触れました。
これらの技術を活用することで、音声データの分析や視覚化がより効果的に行えるようになりますので、ぜひ実際にコードを試してみてください。
音声処理のスキルを向上させるために、さまざまな音声ファイルを使って実験を重ねてみることをお勧めします。