2022.1.21

  1. 2022-01-21-演習 , (youtube, 限定公開). asir から C 言語の参考資料. printf 文を入れて調べる.
  2. Q. 音色を変えるには?
    A. Fourier 展開で習うように $\sum_{k=1}^n a_k \sin(2\pi kt/L)$ で $[0,L]$ 区間上の $t$ 変数のいろんな関数を表現できます.
    例:
    440.0 0.4 880.0 0.7 1320 1.0 1760 1.2 (Hz と強さ, Hz と強さ, ...)
    と sin を足した音は これ . つまり 440 Hz を強さ 0.4, 880 Hz を強さ 0.7, 1320 Hz を 強さ 1.0, 1760 Hz を強さ 1.2 とした音. さらに全体に exp(-t) をかけて減衰させています. ラの音に聞こえますが単独の sin 音とは音色が違います.
    例: バイオリンの波形を Fourier 展開してみると
    440 0.023 880 0.81 1320 0.014 1760 0.1 2200 0.15 2640 0.001 3080 0.007 3960 0.014 
    なる結果になりました. このデータで合成した 音は これ ですが, さらに音の立ち上がり, 減衰も工夫しないとそれらしくならないようです.
    例: 円盤の波動方程式の固有値, 固有関数(Bessel 関数)を利用して作った 円形のかね音1 , 円形のかね音2 .
    例: Fourier 展開を高次にすると音色が変わっていく様子 .
  3. Q. 実行で Segmentation fault が出たら?
    A. これは書き込みができないメモリ領域にデータを書き込んでいるエラーです.
    例:
    #include 
    int main() {
      int *a;
      int i;
      a=0;
      for (i=0; i<200; i++) a[i]=i;
      for (i=0; i<200; i++) printf("%d ",a[i]);
    }
    
    このプログラムを実行すると segmentation fault エラーが出ます. 書き込みができない 0 番地からのメモリにデータを書き込もうとしているからです.
    配列のサイズに注意してください.
  4. Q. 配列を関数引数に使う時の注意点は?
    A. Asir のベクトルや行列と同様で, 関数の中での変更が呼び出し元データに反映されます. 関数側は配列の大きさを知る方法がないので, 最初から決まった長さでないなら, 引数に配列の長さも与える必要があります.
  5. Q. printf で変数を表示したら nan と表示されました. これは何?
    A. nan は Not A Number の略で, お求めの数が計算できませんでした、の意味です.
    ちなみに
      double mypower(double x,double i) {
      double s;
      s = exp(i*log(x));
      return(s);
    }
    
    は x が負の時は nan となります. $|x|^i$ を計算するには
      double mypower(double x,double i) {
      double s;
      if (x < 0) x = -x;
      s = exp(i*log(x));
      return(s);
    }
    
  6. Q. C言語の random() の仕様
    A. random() の man ページ を参照.
  7. Q. 音のつなぎ目でプチプチ音がある.
    A. 波形を滑らかにつなげばよい.
  8. Q. 長い音データを genwav*.c で作れない
    A. 配列 data は stack 領域に作られます. stack 領域のサイズは上限があり unix shell (端末) で
    ulimit -s
    
    と入力して調べることができます(キロbytes). 制限を外すには
    ulimit -s unlimited
    
    としますが, この場合 stack を食い尽くしてシステムを暴走させる危険もあるので たとえば
    ulimit -s 20000
    
    などと必要なサイズにすると安全でしょう.