HSP3.0でWavファイルの読み込み

16bitフォーマットのWavファイルからバイナリデータの読み込み

16ビットのWavファイルは1サンプル=符号付16ビット(2バイト)で記録されています。
しかし、次のようにbload命令でファイルから2バイトを取りだすと、*1

bload filename,wavedata,2,44+cnt*2

取り出した2バイトは符号付16ビットであるとは定義されず、そのままHSPの整数型である符号付32ビット(4バイト)に格納されました。おそらく符号を表すはずだった桁も、符号付32ビットの数値部分のひとつとして書きこまれています。他の言語であれば、符号付16ビット型を用意して格納する方法を使うと思いますが、HSPではそういうことができないのかな、、、、

市販のオーディオ編集ソフトと出力データを比較してみると、

バイナリ 符号付16ビット整数 HSPの整数型
01111111 11111111 +32767 32767
(中略) (中略) (中略)
00000000 00000001 +1 1
00000000 00000000 0 0
11111111 11111111 -1 65535
11111111 11111110 -2 65534
(中略) (中略) (中略)
10000000 00000000 -32768 32768

となっているらしいことがわかりました。
32768から65535の範囲の数値が本来は負の数となるべきで、かつ、32768が-32768で、65535は-1です。
これは、ウィキペディアによると「2の補数」と呼ばれる表現方法のようです。

16ビットフォーマット用のデータ取り込みループ

そこで、16ビットをそのまま符号付32ビットに書き込みつつ、本来は負の数になるはずの数値を調べて負の数に直してみました。MaxDataはデータのバイト数。2バイトで1サンプルなので、サンプル数回のループを実行します。

repeat MaxData/2 - 1
bload filename,wavedata(cnt),2,44+cnt*2
if wavedata(cnt)>32767:wavedata(cnt)=-(65536-wavedata(cnt))
loop

これで数値を調べてみると、市販のWav編集ソフトで読み込んだのと同じ値になりました。

*1:大多数のWavファイルはバイト番号44からオーディオデータが始まっています。が、本当はそれを確認するコードを書くべきです。