LoginSignup
2
1

More than 5 years have passed since last update.

waveモジュールのreadframes

Posted at

Pythonのwaveモジュールをちょっとハックする記事です。

waveモジュール

以前に音声系のネタをPythonでアレコレしていて、その時のメモをだいぶ前に記事にしてました。

Pythonでのwavファイル操作

そこでとある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という値に特別な意味はなく、マイナスの値であればいいです。ただ、どうも値のチェックが甘い気がしますし、たぶん何もテストされてないと思われます。

結論

鼻から悪魔・・・とまでは言いませんが、データを読み込めるからといってハックするような使い方はあまりよろしくないようです。適切にフレーム数を指定して読み込むようにしましょう。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1