2010年9月13日月曜日

PyAudioリベンジ

引き続きPyAudio。

前回、オーディオデータをフレーム単位で扱う必要がある、ということに気づいた。

そのことを意識してPyAudioのサンプルソースを見ていたら、何やら関係がありそうな記述が。


FORMAT = pyaudio.paInt16

p = pyaudio.PyAudio()
stream = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
output = True,
frames_per_buffer = chunk)


どうやらオーディオストリームを開く時に、データフォーマットをint16で定義していたみたい。
きちんとソースは読まなくては…。

ということでこの場合、1フレームは16ビット=2バイトということがわかった。

ordにいちいち一つずつデータを渡すのは面倒なのでnumpyのfrombufferメソッドに型指定して渡すと


>>> a = frombuffer(data,dtype = "int16")
>>> a
array([ 1, -4, -4, ..., 0, 0, 0], dtype=int16)


dataは無音環境で録ったマイクからのデータなので、それらしい値になっている。
めでたくオーディオデータを数値として取り出すことができた。


これまでの経緯をもとに録音、表示プログラムを改良したものがこちら。

from pylab import *
from numpy import *
import pyaudio
import sys

chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 10

p = pyaudio.PyAudio()

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

inp = []

print "* recording"
for i in range(0, 44100 / chunk * RECORD_SECONDS):
data = stream.read(chunk)
inp.extend(frombuffer(data,dtype = "int16"))

print "* done"

plot(inp)
show()


出力結果は下の画像。



マイクに息を吹きかけたりかけなかったりした波形。

うまくいっているようだ。

ちなみにいろいろ調べている途中でPyAudio使って音楽ファイルにFFTかけたり、フィルタリングするコードが載ったサイトを発見した。参考までに。

0 件のコメント:

コメントを投稿