Pythonのwaveモジュールをちょっとハックする記事です。
waveモジュール
以前に音声系のネタをPythonでアレコレしていて、その時のメモをだいぶ前に記事にしてました。
そこでとあるteratailの質問が目に入ったのですが、何やらwavファイルを全部読み込みたい様子。
Pythonの公式ドキュメントにあるwaveモジュールの説明に従うなら、次のようになります。
import wave
fname = 'xxx.wav' # mono
wf = wave.open(fname, 'rb')
nframes = wf.getframes() # フレーム数を取得
buf = wf.readframes(nframes) # 指定したフレーム数の読み込み
wf.close()
ところで、以前の記事にもちらっと書いたのですが、全てのフレームを読み込むだけならwf.readframes(-1)
とすればいいのでした。
import wave
fname = 'xxx.wav' # mono
wf = wave.open(fname, 'rb')
buf = wf.readframes(-1) # データを全部読み込む
wf.close()
ただ、この方法がドキュメントに書かれていないのです。どういうことか気になってソースコードを見に行くと、実際の読み込みは内部に保持しているChunkクラスのインスタンスにデリゲートしていました。下記のself._data_chunk
がChunkクラスのインスタンスですね。
class Wave_read:
...
def readframes(self, nframes):
...
data = self._data_chunk.read(nframes * self._framesize)
...
そこでさらにChunkクラスのソースコードを見に行くと、readメスッドのsize
引数がマイナスの値の場合はchunkの最後まで読み込む記載されていますね。
https://github.com/python/cpython/blob/3.7/Lib/chunk.py#L122-L126
class Chunk:
...
def read(self, size=-1):
"""Read at most size bytes from the chunk.
If size is omitted or negative, read until the end
of the chunk.
"""
...
実際のところ、実用上はのWave_read のframesize
がマイナスになることはないので、readframes(-1)
で全部読み込めたみたいです。ここまでくればもはや蛇足ですが、-1
という値に特別な意味はなく、マイナスの値であればいいです。ただ、どうも値のチェックが甘い気がしますし、たぶん何もテストされてないと思われます。
結論
鼻から悪魔・・・とまでは言いませんが、データを読み込めるからといってハックするような使い方はあまりよろしくないようです。適切にフレーム数を指定して読み込むようにしましょう。