[Python] wavファイル再生時に波形を表示する方法

Pythonでwavファイルを再生しながら波形を表示するには、matplotlibsounddeviceなどのライブラリを使用します。

scipy.io.wavfileでwavファイルを読み込み、matplotlibで波形をプロットします。

再生はsounddevice.play()を使います。

具体的には、wavファイルを読み込んで波形データを取得し、matplotlibでリアルタイムに更新しながら再生することで、視覚的に波形を確認できます。

この記事でわかること
  • wavファイルの再生方法
  • 波形表示の手法
  • 音声フィルタリングの実装
  • 音量のリアルタイム表示
  • スペクトログラムの活用方法

目次から探す

Pythonでwavファイルを再生する方法

sounddeviceライブラリのインストール

Pythonでwavファイルを再生するためには、まずsounddeviceライブラリをインストールする必要があります。

このライブラリは、音声の再生や録音を簡単に行うことができます。

以下のコマンドを使用してインストールします。

pip install sounddevice

sounddeviceを使ったwavファイルの再生

sounddeviceライブラリを使ってwavファイルを再生する方法は非常にシンプルです。

以下のサンプルコードでは、sounddevicescipy.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ファイルの再生と波形表示を同時に行うためには、sounddevicematplotlibを組み合わせて使用します。

以下のサンプルコードでは、音声を再生しながら波形を表示します。

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()

このコードでは、音声が再生されると同時に波形がリアルタイムで更新されます。

再生中に波形を動的に更新する方法

再生中に波形を動的に更新するためには、matplotlibpause関数を使用します。

上記のコード例でも示したように、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ファイルのスペクトログラムを表示し、音声を再生します。

これにより、音声データの周波数成分を視覚的に理解することができます。

よくある質問

wavファイルの再生が途中で止まるのはなぜ?

wavファイルの再生が途中で止まる原因はいくつか考えられます。

主な理由は以下の通りです。

  • ファイルの破損: wavファイルが破損している場合、再生中にエラーが発生することがあります。
  • メモリ不足: 大きなwavファイルを再生する際に、メモリが不足していると再生が途中で止まることがあります。
  • オーディオデバイスの問題: 使用しているオーディオデバイスに問題がある場合、再生が正常に行われないことがあります。
  • プログラムのバグ: コードにバグがある場合、再生が途中で止まることがあります。

エラーメッセージを確認し、デバッグを行うことが重要です。

波形が正しく表示されない場合の対処法は?

波形が正しく表示されない場合、以下の点を確認してください。

  • データの正規化: 音声データが正規化されていないと、波形が正しく表示されないことがあります。

データを-1から1の範囲に正規化することを確認してください。

  • プロット範囲の設定: matplotlibのプロット範囲が適切に設定されていない場合、波形が見えないことがあります。

x軸とy軸の範囲を適切に設定してください。

  • データの形式: wavファイルがモノラルかステレオかによって、データの形状が異なります。

ステレオの場合は、片方のチャンネルを選択する必要があります。

  • ライブラリのバージョン: 使用しているライブラリのバージョンが古い場合、互換性の問題が発生することがあります。

最新のバージョンにアップデートしてください。

他の音声フォーマット(mp3など)でも同じ方法で波形を表示できる?

他の音声フォーマット(mp3など)でも波形を表示することは可能ですが、いくつかの追加手順が必要です。

具体的には、以下の点に注意してください。

  • 音声ファイルの読み込み: scipy.io.wavfileはwavファイル専用のため、mp3ファイルを読み込むにはpydublibrosaなどのライブラリを使用する必要があります。
  • データの変換: mp3ファイルを読み込んだ後、numpy配列に変換する必要があります。

これにより、波形をプロットするためのデータが得られます。

  • サンプルコードの変更: wavファイル用のサンプルコードをmp3ファイル用に変更する必要があります。

具体的には、ファイルの読み込み部分を適切なライブラリに置き換える必要があります。

以下は、pydubを使用してmp3ファイルを読み込む例です。

from pydub import AudioSegment
import numpy as np
# mp3ファイルの読み込み
audio = AudioSegment.from_file('sample.mp3')
data = np.array(audio.get_array_of_samples())

pydubを使用するためには、FFmpegまたはlibavが必要です。

ただ使うだけならプログラムと同じフォルダ(カレントディレクトリ)に配置するだけで構いません。

このように、他の音声フォーマットでも波形を表示することができますが、適切なライブラリと手順を使用することが重要です。

まとめ

この記事では、Pythonを使用してwavファイルを再生し、その波形を表示する方法について詳しく解説しました。

また、音声処理の応用例として、フィルタリングや音量の変化の表示、複数の音声ファイルの同時再生、さらにはスペクトログラムの表示方法についても触れました。

これらの技術を活用することで、音声データの分析や視覚化がより効果的に行えるようになりますので、ぜひ実際にコードを試してみてください。

音声処理のスキルを向上させるために、さまざまな音声ファイルを使って実験を重ねてみることをお勧めします。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • URLをコピーしました!
目次から探す