2014/03/18

C言語 三角波をつくる

三角波

三角波は、のこぎり波や矩形波に比べ倍音は少なく、おとなし目の音。


生成方法

基音となるサイン波に奇数倍音のサイン波を合成することで、三角波を生成。また振幅は2乗の逆数に比例して減衰させることで三角波になる。1オクターブにつき-12dB傾斜する。ちなみに矩形波は1オクターブにつき-6dBなので、倍音成分は三角波よりも多い。

サイン波の合成で三角波をつくる

/* triangle wave
 * sin波の合成による生成 
 * 32bit float RAW ヘッダなしwaveファイル出力
 */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void){
  FILE *fpw;/* 書き込み用ファイルポインタ */
  float *pbuff; /* メモリのデータを指す */
  int samplingfreq = 44100;/* サンプリング周波数 */
  int sec = 10; /* 作成する波形の長さ(秒) */
  int fileSize = samplingfreq * sec; /* ファイルの大きさ */
  float a = 0.5; /* Aの値 初期振幅 */
  float note = 440;
  float step = 2 * M_PI / samplingfreq;/* 点間のステップ */
  int i;
  int j;

  /* 新規ファイル作成 */
  fpw = fopen("triangle_32bitF_raw.wav", "wb");
  /* 失敗時終了 */
  if (fpw == NULL) exit(EXIT_FAILURE);
  /* メモリを確保して先頭アドレスをpbuffに入れる */
  pbuff = (float*)malloc(sizeof(float) * fileSize);
  /* 失敗時終了 */
  if (pbuff == NULL) exit(EXIT_FAILURE);

  /* triangle 奇数倍音の合成(15回) メモリ書き込み */
  for(i=1; i<=29; i++){
   for(j=0; j<fileSize; j++){
     if (i % 2 == 1){
        *(pbuff+j) += a/i/i * sin(M_PI * i / 2.0) * sin(i * j * step * note);
     }
   } 
  }
  /* ファイルへ書き込み */
  fwrite(pbuff, sizeof(float), fileSize, fpw);
  /* ファイル閉じる */
  fclose(fpw);
  /* メモリ解放 */
  free(pbuff);
  return 0;
}

上記をコンパイルしてから実行すると、triangle_32bitF_raw.wavというファイルが同じディレクトリに作られる。注意点としてはヘッダのないwaveファイルなので、普通のミュージックプレーヤーでは再生できない。ここではRAWデータ(32bit float, Mono, Little-endian)としてAudacityで読み込んで表示させている。

サイン波を15回重ねて作った三角波の音

下は合成回数を1から5回(9倍音)までの三角波。はじめの1回目はサイン波だけなので合成になっていない。2回目以降から三角波に変わっていくのが分かると思う。他ののこぎり波や矩形波よりも収束は早い。



C言語 ANSI C89 GCC 目次