PythonでWAVファイルの読み込み(soundfile.read)

Python で WAVファイルを読み込むには soundfile.read() 関数を使います。主な使用例を説明したいと思います。

パラメータと返り値

soundfile.read の主なパラメータと返り値は以下です。

soundfile.read(file, frames=-1, start=0, stop=None, dtype='float64')
表:soundfile.readのパラメータ
パラメータ名 データ型 概要
file str 入力WAVファイル名
frames int 読み込むフレーム数
start int データの開始位置
stop int データの終了位置
dtype str 返り値のデータ型
表:soundfile.readの返り値
返り値 データ型 概要
audiodata np.ndarray オーディオデータ
samplerate int サンプリングレート

主な使用例

モノラルデータの読み込み

モノラルのWAVデータを読み込んで、波形を保存するソースコードは以下です。

import soundfile as sf
import matplotlib.pyplot as plt

data, samplerate = sf.read('input.wav')
print(data.shape)
# (484611,)
plt.plot(data)               # グラフプロット
plt.savefig("graph1.png")    # グラフ保存

基本的にはsf.readにファイル名を与えるだけでWAVデータを得ることができます。WAVデータの波形は以下のようになり、-1.0~1.0の64bit浮動小数点数型の値が出力されます。

図:モノラルデータの波形
図:モノラルデータの波形

ステレオデータの読み込み

ステレオの場合のソースコードは以下です。とはいってもモノラルのときとほとんど変わりません。

import soundfile as sf
import matplotlib.pyplot as plt

data, samplerate = sf.read('stereo.wav')
print(data.shape)
# (472963, 2)
plt.plot(data)             # グラフプロット
plt.savefig("graph2.png")    # グラフ保存

ステレオの場合、 data[ : , 0] に左チャネルのデータ、data[ : , 1] に右チャネルのデータが格納されます。

図:ステレオデータの波形
図:ステレオデータの波形

補足:1つのWAVファイルに4chのデータが含まれている場合でも data.shape=(データ数, 4)でデータを得ることができるのは確認しています。

16bit整数型で受け取る

モノラルのWAVデータを16bit整数型で読み込んで、波形を保存するソースコードは以下です。

import soundfile as sf
import matplotlib.pyplot as plt

data, samplerate = sf.read('input.wav',dtype="int16")
print(data.shape)
# (484611,)
plt.plot(data)             # グラフプロット
plt.savefig("graph3.png")  # グラフ保存

dtype="int16"を指定することで、16bit整数型で読むことができます。他には"int32""float32"を指定することができます。

WAVデータの波形は以下のようになり、-32768~32767の値となっています。

図:16bit整数型のデータ
図:16bit整数型のデータ

開始位置と終了位置を指定

データの開始位置と終了位置を指定する場合のソースコードは以下です。

import soundfile as sf

data, samplerate = sf.read('input.wav',start=120000, stop=150000)
print(data.shape)
# (30000,)
print(data)
# [0.20709229 0.259552   0.30130005 ... 0.07809448 0.09100342 
#  0.07952881]

ちなみにstopをデータ数以上にした場合、データの終わりまで読み込みます。

開始位置とデータ数を指定

データの開始位置とデータ数を指定する場合のソースコードは以下です。

import soundfile as sf

data, samplerate = sf.read('input.wav', frames=5000, start=120000)
print(data.shape)
# (5000,)
print(data)
# [ 0.20709229  0.259552    0.30130005 ... -0.18707275 -0.17260742 
#  -0.17138672]

framesについてもデータ数以上にした場合、0埋めとかはされず、データの終わりまでしか読み込みません。ただし、後述するfill_valueに値を入れるとその値で埋められたデータが返されます。

ちなみにデータの終了位置 stop にも値を与えるとエラーとなりますので、気を付けてください。パラメータ framesstop はどちらか一方しか使えません。

おまけ

読み込めるオーディオファイル

soundfile.read はWAVファイル以外も読みこめます。読み込めるデータフォーマットは以下のリンクに記載があります。

■対応するデータフォーマット一覧
http://www.mega-nerd.com/libsndfile/#Features

私はWAV以外をsoundfile.readで読み込んだことはないです。

その他のパラメータ

always_2d
always_2d=Trueを指定することで、モノラルデータを読み込んだ場合でもdata.shape=(データ数, 1)の2次元配列を返します。

fill_value
framesをデータ数以上にした場合、fill_valueの値で埋められ、framesで指定したデータ数が返されます。stopをデータ数以上にした場合は適用されないみたいです。

out
outにnumpy配列を与えることでその配列にデータを書き込みます。

samplerate, channels, format, subtype, endian, closefd
closefd 以外はヘッダ情報がない RAW ファイルを読み込む場合に使用するパラメータです。一応、詳細はsoundfile.SoundFileに記載があります。closefdはファイルディスクリプタを閉じるか否かのパラメータです。

おわりに

本記事では、WAVファイルを読み込む関数 soundfile.read について紹介しました。個人的には Python のWAVを読み込む関数の中では最も使いやすいものだと思っています。

■参考文献
[1] Bastian Bechtold.“python-soundfile”. Read the Docs. 2015.
https://python-soundfile.readthedocs.io/en/0.11.0/, (参照2024-02-04)