37 昔コンパイルできたCプログラムがコンパイルできなくなってた

以前、

青木 直史, サウンドプログラミング入門――音響合成の基本とC言語による実装, 技術評論社 (2013/02/01)
という本に載っていたCプログラムを学生が使ったことがあった。 そのときは、 Mac で文字コードの変換 (Shift JIS→UTF8) をするくらいで無修正で動作した記憶があるのだけれど、 久しぶりにやってみたら、正しく動かない。 あれ? とりあえず “青木 サウンドプログラミング mac” で検索したら
「サウンドプログラミング入門をMacでやる。」
というWWWページがヒットした。

wave.h にある
long riff_chunk_size;
long data_chunk_size;
という変数宣言に
long riff_chunk_size = 0;
long data_chunk_size = 0;
のような初期化をつければ良さげ、ということだった (それが分かるために、デバッガーで追跡したそうで、 お疲れ様である)。 それにしても他人が作ったプログラムを動くように直すとき、 初期化し忘れの問題というのは意外によく遭遇するものだ。


それ以外に fft.h で定義してある int log2(int) という関数の名前が、 数学関数ライブラリィの double log2(double) と衝突するという問題があった (log2()_log2() に変更した)。


以上2点の修正で、1〜11章のプログラムはコンパイル&実行できるみたい。 多くのプログラムは正しく動作しているようである (付属する WAVE ファイルと同じファイルが生成される)。 擬似乱数を使っているプログラムは結果が食い違うが、 生成されたWAVEファイルを聴く限りは「同じように」聞こえる。


とりあえず自動的にソース・プログラムを入手して、 上の修正を施してコンパイル&実行するスクリプトを書いた (文字コードの変換に nkf を使っている)。
curl -O http://nalab.mind.meiji.ac.jp/~mk/misc/20201008/install-aoki.sh
chmod +x install-aoki.sh
./install-aoki.sh

以前は初期化の指示なしでなぜ動いていたか、という謎解きが残っている。 次に暇が出来たら調べてみよう。

(続く)

(2020/12/27追記) 謎が解けたわけではないけれど、 件のプログラムの中にあるWAVEファイルを読む関数 (read_{8|16}bit_{mono|stereo}())が いくつかのチャンクに対応していないことに気づいた。 ずっと以前、WAVEファイルを読む関数を自作したことがあって (「readwave.c (WAVE→テキスト・ファイル)」)、 そのとき自分が作ったプログラムが直面したのと同じ問題を抱えているわけだ。 「対応していないのは仕様である」と言うことも可能だけれど、 ちょっと頑張って対応してしまう方が良いように思う。
  fread(&bits_per_sample, 2, 1, fp);
  fread(data_chunk_ID, 1, 4, fp);
  fread(&data_chunk_size, 4, 1, fp);
と data チャンクが来ると決め打ちしているところを
  fread(&bits_per_sample, 2, 1, fp);
  while (1) {
    fread(data_chunk_ID, 1, 4, fp);
    fread(&data_chunk_size, 4, 1, fp);
    if (strncmp("data", data_chunk_ID, 4) == 0) {
      if (verbose)
        printf("data チャンク見つかった\n");
      break;
    }
    else {
      fseek(fp, data_chunk_size, SEEK_CUR);
    }
  }
のようにした (実際に “data” となっていることを確かめ、 そうでなければそのチャンクを読み飛ばして次に進む)。 これで読めなかったいくつかの WAVE ファイルが読めるようになった。



桂田 祐史