音声データを操作してみる(ファイルの読み込み/書き込み)
この記事では音声データを自在に操れるようになることを目標に以下のことを学びます。
基本的に使用するプログラミング言語はPythonです。必要に応じて外部ツールや多言語にも触れていきます。
音声データの基礎知識で学んだことを生かして学習を進めます。
waveファイルは波形をバイナリデータで保存していますが、1つのデータは2byte(Int16)で表現されています。
なのでデータの読み書きはバイナリデータを扱うことになります。
音声ファイル(wav)の読み込み
音声ファイルを扱う時はwaveモジュールを使用してWave_readオブジェクトを生成します。
waveモジュールは音声ファイルを読み込みモードまたは書き込みモードで開くことができます。
ただし、同時に両方のモードで開くことができないため、読み込みモードで開いた音声ファイルにデータを書き込むことはできません。
オブジェクトの持つメソッドについては以下のドキュメントを参照するのがオススメです。
docs.python.org
import wave file_path = '音声ファイルのパス' #指定した音声ファイルを読み込んだwaveオブジェクト wf = wave.open(file_path, "r") #wfオブジェクトからサンプリングレートを取得 fs = wf.getframerate() #オブジェクトからチャンネル数を取得 ch = wf.getnchannels() #オブジェクトからデータを読み取る wave_data = wf.readframes(wf.getnframes()) #バッファから1次元配列に変換(バイナリデータをInt16で読み込み、正規化も行っている。) wave_data = np.frombuffer(wave_data, dtype="int16") / 32768.0
読み込んだ音声データは1次元リストになってwave_dataに記憶されます。
今後はこのように音声データを読み込んで解析・処理に使用します。
音声ファイル(wav)の書き込み
読み込みと同様に書き込み処理もwaveモジュールを呼び出します。
Wave_writeオブジェクトを使用して書き込みます。
import wave #正規化されている音声をint16へ変換 data = [int(x * 32767.0) for x in data] #バイナリ化 binwave = struct.pack("h" * len(data), *data) wf = wave.Wave_write(filename) wf.setparams(( 1, # channel 2, # byte width fs, # sampling rate len(data), # number of frames "NONE", "not compressed" # no compression )) wf.writeframes(binwave) wf.close()
音声データを可視化してみる
グラフの作成にはmatplotlibモジュールを使用します。
音声に限らずpythonでグラフを出力したい場合はこのmatplotlibを使うことになるでしょう。
matplotlibはできることがたくさんありますがここでは必要な機能に限り紹介します。
import matplotlib.pyplot as plt #グラフの描画サイズを変更 plt.figure(figsize=(10,5)) #x軸の値を配列で作成 x = np.linspace(0.,len(wave_data)/fs,len(wave_data)) #グラフを描画 plt.plot(x,wave_data) #グラフを出力 plt.show()
グラフの出力結果が以下のようになります。
読み込んだ音声は60秒間の音声であることがグラフの横軸からも確認できます。