PyOpenGLでwavファイルの波形を表示させた
wave標準モジュールを使った自作wavユーティリティとOpenGLのpythonバインディングのPyOpenGLを使ってwavファイルの波形を表示させてみた。pythonはwavファイルを扱うモジュールが標準であるのでバイナリファイルフォーマットをパースする処理は全てライブラリに任せられる。
それとpythonでwavのプログラムするとビットレートやチャンネル数の違いを簡単に吸収できるのでCで組むよりずっと楽に感じる。速度は・・比べてないけどCのがずっと早いと思う。
三角波
wavファイルのデータフォーマットは以下の書籍を参考にさせてもらった。始めてサウンドプログラミングする自分にとってプログラムコードが沢山収録されているこの本はわかりやすいと感じた。
- 作者: 北山洋幸
- 出版社/メーカー: カットシステム
- 発売日: 2008/06
- メディア: 単行本
- クリック: 47回
- この商品を含むブログ (9件) を見る
以下のような感じに抽象化してwavファイルを作成しそれをPyOpenGLで表示させた。
- WaveInfoクラスはwavデータのチャンネル数、ビットレート、サンプリング周波数、オーディオフレーム数の情報を保持するクラス。
- AudioFrameクラスは音の記憶単位を保持するクラスで、チャンネル数が1のときvalueプロパティ、2のときleft,rightプロパティをもち、それぞれへの数値の代入は内部的にはメンバ変数によってバインドされたwavの生データへの代入になる。またAudioFrame,intに対する四則演算がオーバーロードされているのでチャンネル数の違いを簡単に吸収できる。
- Waveオブジェクトは、概念的にはWaveInfoオブジェクトとAudioFrame(音の記憶単位)の配列をメンバに持つように振舞う。実際はWaveInfoオブジェクトと生データをメンバに持つクラス。そのほか、WaveInfoオブジェクトによって指定されたビットレートにおける最大値、最小値、無音の値を表すread onlyなプロパティ、maxvalue,minvalue,silentを持つ。
- Waveオブジェクトは初期化時にファイル名、またはWaveInfoオブジェクトを受け取れる。このとき、WaveInfoオブジェクトと同時にWaveInitオブジェクトを渡すことができる。この場合データのセットアップ後にWaveInit.initメソッドを呼びデータを初期化する。
たとえば、「ラ」の音(440Hz)を作りたい場合
Wave(WaveInfo(2, 16, 44100, 44100), SinWaveInit(440))
のようになる。また、上に紹介した本ででてくるいくつかの課題は以下のように書ける。
ステレオwavファイルの左のチャンネルの音を消す
wav = Wave("music.wav") for frame in wav: frame.left = wav.silent
ステレオwavファイルの左右のチャンネルの音を交換する
wav = Wave("music.wav") for frame in wav: frame.left, frame.right = frame.right, frame.left
音量を半分に
wav = Wave("music.wav") for i in xrange(len(wav)): wav[i] = wav[i] / 2
最後に、http://humansci.let.hokudai.ac.jp/g/toyo/matlab.htmlにある「あ」の音の波形を表示させてみた。
[,h200]