音の値
音の値
ということで、PyAudioで音のデータを扱えるようになったとして、その値ってどう解釈すればよいのだろうか、というのが課題です。
音量情報が欲しい時、pyaudioにより開かれたストリームをread()で読み込む事で値を得る事が出来るらしいんですけどね。例えばこんな感じで。
import pyaudio import time import numpy audioChank = 1024 audioWidth = 2 audioRate = 44100 audioChn = 1 input_device_index = 0 p = pyaudio.PyAudio() stream = p.open( format = pyaudio.paInt16,\ channels = audioChn,\ rate = audioRate,\ input_device_index = input_device_index,\ input = True,\ frames_per_buffer = audioChank ) #for i in range( audioRate/audioChank * 60 ): while True: data = stream.read( audioChank ) a = numpy.frombuffer( data, dtype = "int16" ) #convert int print a stream.close() p.terminate()
read()で得られる値を取り扱いやすいものにする時、numpyってのを使うのが定番らしいっすね。read()で得られる値はそれに与えるパラメータの整数値(上のコードだとaudioChank == 1024)の数の配列のようです。この例だと [ 31 36 42 ..., -29 -20 -10] というような形で1024個の要素が入った配列を得られます。
で、中身は符号付きの16bitの整数なので、-32767~32767の範囲の数字だと思うのですが、これをどうとらえればいいのか。
とりあえず各配列の最大値のみを得てみると、つまり print a の部分を print numpy.max( a ) とすると、
84, 77, 74, 688, 550, 26682, 32373, 1899, 601, 217, 184, 99, 145, 65, 71, 54, 79, 65, 32, 59, 81, 53, 32582, 7460, 1261, 431, 219, 119, 122, 131, 64, 70, 80, 66, 46, 85, 81
となります(改行を "," に置き換えてます)。二回パンパンってマイク前で手をたたいてみました。んじゃ、最小値(print numpy.min( a ) )はというと、
-31, -284, -483, -527, -335, -148, -125, -26447, -5682, -1406, -294, -158, -111, -95, -110, -106, -88, -46, -41, -43, -39, -26, -20, -25, -32677, -12878, -1885, -444, -204, -146, -135, -174, -58
という感じ。音が大きい時、負数の絶対値も大きな値になっています。つまり振幅が大きかったって事すかね。
ってことは、絶対値の最大値をとってやれば何となく音量の傾向が出てくるのでしょうか。
いやぁ、正直わかりませんわ(^^;
PyAudioを入れてみた
PyAudio。PortAudioっていう音関係のライブラリをPythonにバインドしたもんってことらしい。インストーラが各プラットホーム向けに出ているからインストールは簡単でございました。
いれたはいいものの音に関しては全くの素人。さっぱり分かりません。
とりあえず既存のwaveファイルを再生するというのは、PyAudioのドキュメントに書かれているサンプルコードで出来ました。
import pyaudio import wave import sys import time if len(sys.argv) < 2: print("Plays a wave file. \n\nUsage:%s "%sys.argv[0]) sys.exit(-1) wf = wave.open( sys.argv[1], 'rb') p = pyaudio.PyAudio() def callback( in_data, frame_count, time_info, status ): data = wf.readframes(frame_count) return (data, pyaudio.paContinue) stream = p.open( format=p.get_format_from_width(wf.getsampwidth()),\ channels = wf.getnchannels(),\ rate = wf.getframerate(),\ output=True,\ stream_callback=callback ) stream.start_stream() while( stream.is_active() ): time.sleep(0.1) stream.stop_stream() stream.close() wf.close() p.terminate()
続いて録音です。入力デバイスがどんだけあるか調べたり、各々のデバイスがどんなものかの情報を得るにはこんな感じに書けばいいようです。
import pyaudio p = pyaudio.PyAudio() apiCnt = p.get_host_api_count() print("Host API Count: %d"%apiCnt) for cnt in range(apiCnt): print(p.get_host_api_info_by_index(cnt))
これを走らせると、僕のMacBook Proではこんな風に返事が返ってきました。
Host API Count: 1
{'index': 0, 'name': u'Core Audio', 'defaultOutputDevice': 1L, 'type': 5L, 'deviceCount': 5L, 'defaultInputDevice': 0L, 'structVersion': 1L}
入力デバイスは一つしかなく、そのインデックスは0と。ということで、こちら [工作と競馬] をほぼ丸写しで、input_device_indexの値だけ0にする事で、MacBook Proのマイクからの音を録音したファイルを作成する事が出来ました。
import pyaudio import wave import time wf = wave.open('text.wav', 'w') wf.setsampwidth(2) wf.setframerate(44100) wf.setnchannels(2) p = pyaudio.PyAudio() input_device_index = 0 def callback(in_data, frame_count, time_info, status): wf.writeframes(in_data) return (None, pyaudio.paContinue) stream = p.open( format = p.get_format_from_width(wf.getsampwidth()),\ channels = wf.getnchannels(),\ rate = wf.getframerate(),\ input_device_index = input_device_index,\ input = True,\ stream_callback = callback) stream.start_stream() time.sleep(5) stream.stop_stream() stream.close() wf.close() p.terminate()
まずはとりあえず…。