任意のサイン波を作って、それをwavファイルとして保存するプログラム。子ども向けの学習サンプルとして作ってみた。下の例ではサイン波の足し算をしているが、掛け算などすることで、フーリエ変換の学習にもなる。下記のプログラムで作ったwavファイルはヘッダを含まないので、Audacityなどの波形編集ソフトでRawデータとして読み込む必要がある。サンプルフォーマット(音量の分解能)は32bit float。
サイン波の合成
#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 step = 2 * M_PI / samplingfreq;/* 点間のステップ */
int i;
/* 新規ファイル作成 */
fpw = fopen("32bitF_raw.wav", "wb");
/* 失敗時終了 */
if (fpw == NULL) exit(EXIT_FAILURE);
/* メモリを確保して先頭アドレスをpbuffに入れる */
pbuff = (float*)malloc(sizeof(float) * fileSize);
/* 失敗時終了 */
if (pbuff == NULL) exit(EXIT_FAILURE);
/* データ作成 & メモリに書き込み */
for(i=0; i<fileSize; i++){
*(pbuff+i) =
/* 例 0.3は振幅 440は周波数Hz */
(0.3 * sin(i * step * 440))+
(0.2 * sin(i * step * 880))+
(0.2 * sin(i * step * 1760));
}
/* ファイルへ書き込み */
fwrite(pbuff, sizeof(float), fileSize, fpw);
/* ファイル閉じる */
fclose(fpw);
/* メモリ解放 */
free(pbuff);
return 0;
}
|
プログラムは、新規ファイルを用意して、サンプル数と波形の長さからメモリを確保。for文を使ってサイン波を作り、1点、1点メモリに書き込んでいく。その後ファイルにメモリの内容をコピーして終了。
上記を実行すると、32bitF_raw.wavというファイルが同じディレクトリに作られる。これをAudacityで読み込んで表示させてみた。サイン波の合成波形になっているのが確認できる。
サイン波の掛け算
上記プログラムのfor文のところだけを変更。
for(i=0; i<fileSize; i++){
*(pbuff+i) = (0.5 * sin(i * step * 440)) * (1.0 * sin(i * step * 440));
}
|
下は同じ周波数のサイン波を掛けた場合の例。積分して0にならない波形はフーリエ変換の基本となる部分。
C言語 ANSI C89 GCC 目次