【サンプルコード】SciPyを使いwavファイルをフーリエ変換し周波数帯域をプロットする

最終更新日

SciPyとは、Pythonで科学計算を行うための一般的なライブラリの一つで、多様なサブモジュールを持っています。

音響関連の機能に関しては、主に信号処理に関連する機能が役立ちます。

具体的には、scipy.signal サブモジュールが重要です。

Profile

この記事を担当:こうたろう

1986年生まれ
音大卒業後日本、スウェーデン、ドイツにて音楽活動
ドイツで「ピアノとコントラバスのためのソナタ」をリリースし、ステファン・デザイアーからマルチマイクREC技術を学び帰国
金田式DC録音のスタジオにて音響学を学ぶ
独立後芸術工房Pinocoaを結成しアルゼンチンタンゴ音楽を専門にプロデュース
その後写真・映像スタジオで音響担当を経験し、写真を学ぶ
現在はヒーリングサウンド専門の音楽ブランド[Curanz Sounds]を立ち上げ、ピアニスト, 音響エンジニア, マルチメディアクリエーターとして活動中
当サイトでは音響エンジニアとしての経験、写真スタジオで学んだ経験を活かし、制作機材の解説や紹介をしています。
♪この記事には広告リンクを含みます♪

scipy.signal の主な機能:

  1. フィルタ設計: 高域通過フィルタ、低域通過フィルタ、バンドパスフィルタなど、さまざまな種類のフィルタを設計し、信号に適用することができます。
  2. フーリエ変換: 信号を時間領域から周波数領域に変換することができます。これは音響信号の分析において非常に重要です。
  3. ウィンドウ関数: ハニング窓、ハミング窓、ブラックマン窓など、さまざまなウィンドウ関数を提供しています。これらは信号処理において重要な役割を果たします。
  4. 畳み込みと相関: 信号の畳み込みや相関を計算できます。これにより、信号の特性を分析したり、ある信号が別の信号にどのように関連しているかを理解することができます。
  5. スペクトログラム: 時間によって変化する信号の周波数コンテンツを視覚化するために使用されます。

音響信号処理の例:

  • ノイズリダクション: ノイズを含む音響信号から、特定のフィルタを使用してノイズ成分を除去する。
  • エコー除去: 録音された音声信号からエコーを除去する。
  • 音声認識: フーリエ変換やスペクトログラムを用いて、音声信号から特徴を抽出し、それを基に音声認識を行う。

注意点:

  • SciPyは非常に強力なツールですが、特定の音響処理のニーズに応じて他のライブラリ(例えばlibrosapydubなど)と組み合わせることが有効です。
  • SciPyを使用する際には、数学的な知識(特にフーリエ変換やデジタル信号処理に関する知識)が必要になることがあります。

SciPyのこれらの機能を活用することで、音響信号処理に関連する様々なタスクを実行することができます。

フーリエ変換を使って周波数領域への変換

まず、必要なライブラリをインポートします。

ここではscipy.io.wavfileを使ってwavファイルを読み込み、numpyで数値計算を行い、matplotlib.pyplotでプロットを作成します。

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

# WAVファイルを読み込む
file_path = 'path_to_your_file.wav'  # ここにWAVファイルのパスを入力してください
sampling_rate, data = wavfile.read(file_path)

# ステレオ録音の場合は、一方のチャンネルだけを使う
if len(data.shape) > 1:
    data = data[:, 0]

# フーリエ変換を実行
fft_out = np.fft.fft(data)
fft_freq = np.fft.fftfreq(len(fft_out), 1 / sampling_rate)

# プロットする
plt.plot(fft_freq, np.abs(fft_out))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude')
plt.title('Frequency Domain of the WAV file')
plt.xlim(0, 22050)  # 人間の聴覚範囲内の周波数に限定する
plt.show()

このコードは、以下の手順を実行します:

  1. WAVファイルを読み込みます。
  2. フーリエ変換を実行して、時間領域の信号を周波数領域に変換します。
  3. 絶対値を取って振幅スペクトルを得ます(np.abs(fft_out))。
  4. 周波数(Hz)に対して振幅をプロットします。

file_pathには、分析したいWAVファイルのパスを指定してください。

また、このコードは単一チャンネル(モノラル)のデータを前提としています。

ステレオの場合、両チャンネルを別々に処理するか、一方のチャンネルのみを使用します。

エラーのデバッグ

/var/folders/6s/twllp8g10gg9721hjzfkgpt80000gn/T/ipykernel_14541/862441.py:7: WavFileWarning: Chunk (non-data) not understood, skipping it.
  sampling_rate, data = wavfile.read(file_path)

このエラーメッセージは、wavfile.read関数がWAVファイルを読み込む際に、予期しないチャンク(データではない部分)に遭遇し、それをスキップしたことを示しています。

WAVファイルには、音声データの他にもメタデータや他の種類の非音声情報を含むことがあります。

このメッセージは警告(WavFileWarning)であり、エラーではありません。

つまり、ファイルの読み込み自体は成功していますが、全てのチャンクが認識されたわけではないということです。

多くの場合、この警告は無視しても問題なく、読み込まれた音声データをそのまま使用することができます。

ただし、もし音声データが正しく読み込まれているか確認したい場合や、特定のメタデータにアクセスしたい場合は、wavfile.readの代わりに他のライブラリを使用することを検討してみてください。

例えば、pydublibrosaはより多機能で柔軟な音声処理ライブラリです。

これらのライブラリは追加のメタデータや非標準フォーマットの扱いにおいて、wavfileよりも高度な機能を提供します。