実現したいこと
音波測定機器から吐き出した.wav形式の24bitの波形データをpythonで開き、波形のグラフを得たいです。
測定機に付属の波形編集ソフトでも波形は確認できますが、データ数が多いので、pythonでグラフ生成効率化を試みています。
waveデータを開くために、下記リンクを参考にしました。
参照
また、過去に以下のような質問をして、回答をいただいております。
過去の質問
困っていること
pythonでunpackしたwaveデータの値と、測定器付属の波形編集ソフトで確認できるwaveデータの値に差異があります。
センサーの感度や、A/Dコンバータの変換係数などは、取扱説明書から把握できており、
あとはpythonのwave値にそれらの係数を乗算するのみなのですが、pythonのwave値が付属ソフトの値とオーダーが2つくらい異なり、
正しい値になっていません。
python
1import numpy as np 2import matplotlib.pyplot as plt 3import wave 4 5from struct import unpack 6 7fname = "../wav/souvenir.wav" 8fp = wave.open(fname, "r") 9 10nframe = fp.getnframes() 11nchan = fp.getnchannels() 12nbyte = fp.getsampwidth() 13fs = fp.getframerate() 14 15print("frame:{0}, " 16 "channel:{1}, " 17 "bytewidth:{2}, " 18 "fs:{3}".format(nframe, nchan, nbyte, fs)) 19 20buf = fp.readframes(nframe * nchan) 21fp.close() 22 23read_sec = 40 24read_sample = read_sec * nchan * fs 25print("read {0} second (= {1} frame)...".format(read_sec, 26 read_sample)) 27 28# 最下位bitに0を詰めてintにunpackすることで 29# 24bitの値を32bit intとして値を取り出す 30# (<iはリトルエンディアンのint値を仮定) 31unpacked_buf = [unpack("<i", 32 bytearray([0]) + buf[nbyte * i:nbyte * (i + 1)])[0] 33 for i in range(read_sample)] 34 35ndarr_buf = np.array(unpacked_buf) 36wav_1 = ndarr_buf[::4] 37wav_2 = ndarr_buf[1::4] 38wav_3 = ndarr_buf[2::4] 39wav_4 = ndarr_buf[3::4] #ここまでは理解できた。(前回答者の方々ありがとうございました)
試したこと・わからないこと
pythonの値は、付属波形編集ソフトの値の256倍である ということが、いろいろと検算するうちにわかりました。
256=2^8 であり、8bit という数字が関係しそうです。
上記のコードでは、24bitデータに0をくっつけて、32bitとしてunpackしています。
たぶんここが関係しているだろうということまでは予想しているのですが、256という数字が、数学的?にどういう理屈
で関係しているのかわかりません。
(32bit=32列の1と0の組み合わせだけど、そのうち8列は0を詰めただけだから、実質の表現する値は24bitのデータと同じなんじゃないの?とか
これを256で割ると正しい値になるものなの?などなど疑問が解決しません。)
正直何も考えずにpythonの値を256で割り算すれば欲しい値になるのですが、ここが理解できないとスッキリ次に進めそうにないので、
教えていただけると幸いです。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー