明日の課題ができたっぽい
今回の課題は、WAVEファイルのエントロピーを求めましょうってやつだよね。
で、今回使用するWAVEファイルは16ビットでステレオ。
ここだけ押さえてしまえばOK
とりあえず変数を準備
double le=0, re=0, lp=0, rp=0; int c, histl[MAX_LENGTH], histr[MAX_LENGTH], total=0; int l=0, r=0, m=0;
ステレオは、右左の音(値)が違うので
を左右別々に作った。
必要ないかもしれないけど、念のため。
MAX_LENGTHって書いてあるのは2^16にあたる65536ね。
プログラムの最初に
#define MAX_LENGTH 65536
と書いてます。
次に、元ファイルの
for (count = 0; count != samples_to_output; count++) { for (i = 0; i < channels; i++) { if (bits <= 8) { if ((x = fgetc(f)) == EOF) goto loopend; x -= 128; } else { if (fread(s, 2, 1, f) != 1) goto loopend; x = (short)(s[0] + 256 * s[1]); } printf("%d", x); if (i != channels - 1) printf(" "); } printf("\n"); }
となってる部分を
for (count = 0; count != samples_to_output; count++) { for (i = 0; i < channels; i++) { if (bits <= 8){ if ((x = fgetc(f)) == EOF) goto loopend; x -= 128; } else { if (fread(s, 2, 1, f) != 1) goto loopend; x = (short)(s[0] + 256 * s[1]); } if (i != channels - 1) m = l; if (i == channels - 1) m = r; //printf("%d", x-m); //if (i != channels - 1) printf(" "); if (i != channels - 1){ histl[(x-m)+32768]++; l = x; } if (i == channels - 1){ histr[(x-m)+32768]++; r = x; } } //printf("\n"); total++; }
に変えることで、読み込むWAVEファイルの差分をとることができる。
もし、差分の値を表示させたい場合は、コメントアウトしている部分の//を消せばOK
なんか配列の添え字が
(x-m)+32768
となってるが、これにはわけがある。
- xの取りうる範囲Nは、-2^(16-1)≦N≦2^(16-1)-1、つまり、-32768≦N≦32767である。
- 添え字には整数しか使えない。
との理由から、-32768を底上げし、0まで持ってこれるようにするには、Nに32768を足さなければならない。
1.についての詳しい解説は、コン基礎の教科書(P86)に載ってる。
最後に、エントロピーを求める。
さっきのプログラムの後に、次を追加。
for (i = 0; i < MAX_LENGTH; i++) { double lp = (double)histl[i] / total; double rp = (double)histr[i] / total; if (lp != 0) le -= lp * log(lp); if (rp != 0) re -= rp * log(rp); } printf("left : %g\n", le/log(2)); printf("right: %g\n", re/log(2));
これで出来上がり。
left : 8.90779 right: 8.94058
になった。
合ってるかどうかは不明。