web-dev-qa-db-ja.com

pyaudioを使用する場合のチャンク、サンプル、フレームとは

Pyaudioのドキュメントを読んで、ウェブ上の他の記事を読んだ後、私の理解が正しいかどうか混乱しています。

これは、pyaudioのサイトにある音声録音のコードです。

_import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.Paint16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()
_

これらの行を追加すると、記録したものは何でも再生できます。

_play=pyaudio.PyAudio()
stream_play=play.open(format=FORMAT,
                      channels=CHANNELS,
                      rate=RATE,
                      output=True)
for data in frames: 
    stream_play.write(data)
stream_play.stop_stream()
stream_play.close()
play.terminate()
_
  1. 「レート」は、1秒あたりに収集されるサンプルの数です。
  2. 「CHUNK」は、バッファ内のフレーム数です。
  3. 各フレームには、「CHANNELS = 2」として2つのサンプルがあります。
  4. 各サンプルのサイズは2バイトで、関数pyaudio.get_sample_size(pyaudio.Paint16)を使用して計算されます。
  5. したがって、各フレームのサイズは4バイトです。
  6. 「フレーム」リストでは、各要素のサイズは1024 * 4バイトである必要があります。たとえば、_frames[0]_のサイズは4096バイトである必要があります。ただし、sys.getsizeof(frames[0])は_4133_を返しますが、len(frames[0])は_4096_を返します。
  7. forループはint(RATE / CHUNK * RECORD_SECONDS)回実行されますが、その理由はわかりません。 ここ は「ルーベン・サンチェス」が答えたのと同じ質問ですが、彼が_CHUNK=bytes_と言うように正しいかどうかはわかりません。そして、彼の説明によると、int(RATE / (CHUNK*2) * RECORD_SECONDS)でなければなりません。なぜなら_(CHUNK*2)_は、各反復でバッファに読み込まれたサンプルの数だからです。
  8. 最後に_print frames[0]_を書くと、文字列をASCIIエンコードされたものではなく、単なるバイトストリームになります。 structモジュールを使用してこのバイトストリームを16進数で印刷しますか?また、後で16進数の値を選択した値に変更しても、再生可能なサウンドが生成されますか?

私が上に書いたものは何でも物事の私の理解であり、それらの多くは間違っているかもしれません。

14
shiva
  1. 「RATE」は「サンプリングレート」、つまり1秒あたりのframesの数です
  2. 「CHUNK」は、フレームの(任意に選択された)数ですこの例では(潜在的に非常に長い)信号が分割されます
  3. はい、各フレームには「CHANNELS = 2」として2つのサンプルがありますが、このコンテキストでは「サンプル」という用語はめったに使用されません(混乱を招くため)
  4. はい、この例では各サンプルのサイズは2バイト(= 16ビット)です
  5. はい、各フレームのサイズは4バイトです
  6. はい、「フレーム」の各要素は4096バイトでなければなりません。 sys.getsizeof()は、Pythonインタープリターが必要とするストレージスペースを報告します。通常、これは生データの実際のサイズよりも少し大きくなります。
  7. _RATE * RECORD_SECONDS_は、記録する必要があるframesの数です。 forループは各frameではなく、各chunk、ループの数をチャンクサイズCHUNKで割る必要があります。これはsamplesとは関係がないため、_2_の要因はありません。
  8. 16進値を本当に見たい場合は、[hex(x) for x in frames[0]]のようなものを試すことができます。実際の2バイトの数値を取得する場合は、structモジュールでフォーマット文字列_'<H'_を使用します。

waveモジュールを使用したWAVファイルの読み取りに関する私のチュートリアルに興味があるかもしれません。これは、質問のいくつかをより詳細にカバーしています: http://nbviewer.jupyter.org/github/mgeier/python -audio/blob/master/audio-files/audio-files-with-wave.ipynb

20
Matthias