(C) by T.IZUMI @ Ritsumeikan U, Jul 2017 - 無断複製・再配布を禁ず


中高生・学部低回生向け実験
by 立命館大学 理工学部 電子情報工学科 いずみ研

音と波とコンピュータ

〜WAVファイル生成〜


準備

以下を復習・予習しておくこと。

以下をインストールし使い方を確認しておくこと。

以下をダウンロードして適当な作業フォルダに展開しておくこと。


課題

課題1

ともかく、サンプルプログラムをコンパイルして実行してみる。 青字が入力する部分、斜体は実行環境によって異なる部分。
※Windows のファイルは Cygwin から /cygdrive/ドライブ文字/ でアクセスできる。 例えば、D:\work\sinwave なら /cygdrive/d/work/sinwave になる。


izumi@izumipc$ cd /cygdrive/w/sinwave

izumi@izumipc$ ls
Makefile  sinwave.c  wavfast.c  wavfile.c  wavfile.h

izumi@izumipc$ make
gcc -O -Wall -g -c sinwave.c
gcc -O -Wall -g -c wavfile.c
gcc -O -Wall -g -osinwave.exe sinwave.o wavfile.o -lm

izumi@izumipc$ ls
Makefile   sinwave.exe  wavfast.c  wavfile.h
sinwave.c  sinwave.o    wavfile.c  wavfile.o

izumi@izumipc$ ./sinwave.exe
usage: ./sinwave [outputfile]
generate a PCM wav file for tests
                                        Copyright: Tomonori IZUMI, Apr 2017
output file "out.wav"

izumi@izumipc$ ls
Makefile  sinwave.c    sinwave.o  wavfile.c  wavfile.o
out.wav   sinwave.exe  wavfast.c  wavfile.h
                                                                                                

課題2

ソースコードを確認する。Windowsのメモ帳(notepad)等で sinwave.c を開いてみる。

以下の部分を確認する。


#define NUMCH          2  /* number of channels = 2 (left, right)*/
#define BITPERSMPL    16  /* quantization bits = 16bits */
#define SMPLPERSEC 44100  /* sampling rate = 44100Hz (samples/second)*/
#define NUMSMPL    88200  /* sound length  */

#define OUTFILE    "out.wav"
                                                                                

ここで、SMPLPERSEC (samples per second) はサンプリング周波数を定義している。 ここでは CD と同じ 44100Hz (44.1kHz) としている。 NUMSMPL (number of samples) は出力する音のサンプル数を定義している。 ここでは 88200 サンプルでサンプリング周波数が44100Hzなので、 88200/44100=2秒分の音データを出力する。 この値を替えることで音の長さを替えることができる。 OUTFILE は出力ファイル名を定義している。

さらに、以下の部分を確認する。


  for (t=0;t<NUMSMPL;t++){
    double v0,v1;
    v0=1.0*sin(2.0*M_PI*440.0*t/SMPLPERSEC);
    v1=1.0*sin(2.0*M_PI*440.0*t/SMPLPERSEC);
    smpl.smpl[0]=sature16(32767.0*v0);
    smpl.smpl[1]=sature16(32767.0*v1);
    writewavsmpl(fpo,&wavo,&smpl);
  }
                                                                                

ここで、変数 t が時間ステップ(44.1kHzで何個目か)を表しており、 青字の部分の式で正弦波を計算している。 これはCプログラムの計算式で、数学・物理の表現では下の式のようになる。 v0は左チャンネルの音、v1は右チャンネルの音である。 M_PI は円周率πを表し、 1.0 が正弦波の振幅、t/SMPLPERSEC が時刻(秒)、440.0が音波の周波数である。 プログラム中、数値が整数ではなく小数点を含む計算であることを明示するため、 「.0」を敢えて付与していることに注意。 この式を変更すると振幅や周波数を替えることができる。

音の周波数を替えてみよ。sinwave.cを保存、再コンパイルし、 音声ファイルを生成、再生して確認せよ。
注…sinwave.exe の実行時には Media Player を閉じること。 Media Playerが out.wav を開いていると、 sinwave.exe が out.wav を書くことができない。

参考… 2i/12の表
21/121.059
22/121.122
23/121.189
24/121.260
25/121.335
26/121.414
27/121.498
28/121.587
29/121.682
210/121.782
211/121.888
212/122.000

課題3

音を生成する部分を以下のように変更して音を確認せよ。


  for (t=0;t<NUMSMPL;t++){
    double v0,v1;
    v0=0.33*sin(2.0*M_PI*440.0*1.0/1.0*t/SMPLPERSEC)
      +0.33*sin(2.0*M_PI*440.0*5.0/4.0*t/SMPLPERSEC)
      +0.33*sin(2.0*M_PI*440.0*3.0/2.0*t/SMPLPERSEC);
    v1=0.0;
    smpl.smpl[0]=sature16(32767.0*v0);
    smpl.smpl[1]=sature16(32767.0*v1);
    writewavsmpl(fpo,&wavo,&smpl);
  }
                                                                                

ここでは、左音声を440Hzとその4分の5倍、2分の3倍の音を合成している。 3つの波を足しているのでそれぞれの波の振幅を0.33倍にしていることに注意。 なお、右音声は一定値0で無音にしている。

分数を変更して、様々な和音を鳴らしてみよ。

課題4

正弦波以外の、方形波や鋸波を生成せよ。

課題5

♪チューリップ♪の音楽を生成せよ。


参考資料・関連リンク


その他の課題


泉 知論立命館大学 理工学部 電子情報工学科