report11-1.c |
---|
#include<stdio.h> #include<stdlib.h> int main(void){ FILE *fp; int chk; const char *s1="RIFF"; int data_i=1; const char *s2="WAVE"; fp=fopen("report11-1.dat", "wb"); if(fp==NULL){ printf("File Can't Open\n"); exit(1); } chk=fwrite(s1, sizeof(s1[0]), strlen(s1), fp); if(chk<strlen(s1)){ printf("Write Error\n"); } chk=fwrite(&data_i, sizeof(data_i), 1, fp); if(chk<1){ printf("Write Error\n"); } chk=fwrite(s2, sizeof(s2[0]), strlen(s2), fp); if(chk<strlen(s2)){ printf("Write Error\n"); } fclose(fp); return 0; } |
xmms sample.wav & |
sox -V sample.wav -t ossdsp /dev/dsp0 |
WAVファイルフォーマットは次の通りです:
サンプリングレート8000[Hz],16[Bit]符号付きデータ、モノラルで、 ピッチ1[kHz]、音量最大、2秒のWAVファイルを作成して下さい. 次の問題を解いてからの方が良いと思います。 次の雛型を使用してもかまいません.
wavep.c |
---|
#include<stdio.h> #include<limits.h> #include<math.h> #define WAVEDATASIZE 16000 int main(void){ FILE *fp; /***文字列"RIFF"の設定***/ const char *s_riff=/***ここに何か書く***/ /***文字列"WAVE"の設定***/ const char *s_wave=/***ここに何か書く***/ /***ファイルサイズWholeSizeの宣言***/ int WholeSize; /***文字列"fmt "の設定***/ const char *s_fmt="fmt "; /***fmtチャンクサイズの宣言***/ /***ここに何か書く***/ FmtChunkSize; /***↓フォーマットID:FmtIDを設定***/ short FmtId=/***ここに何か書く***/ /***↓チャネル数Channelを設定***/ short Channel=/***ここに何か書く***/ /***↓サンプリングレートSamplingRateを設定***/ int SamplingRate=/***ここに何か書く***/ /***↓データ速度DataVelocityを宣言***/ /***ここに何か書く***/ DataVelocity; /***↓ブロックサイズBlockSizeを宣言***/ /***ここに何か書く***/ BlockSize; /***↓サンプル単位ビット数を設定***/ short Bps=/***ここに何か書く***/ /***文字列"data"の設定***/ const char *s_data=/***ここに何か書く***/ /***↓dataチャンクサイズを宣言***/ /***ここに何か書く***/ DataChunkSize; /***↓波形データ配列WaveDataを宣言***/ /***ここに何か書く***/ Data[WAVEDATASIZE]; int i, chk; /***↓データ速度DataVelocityを設定***/ DataVelocity=/***ここに何か書く***/ /***↓ブロックサイズBlockSizeを設定***/ BlockSize=/***ここに何か書く***/ /***↓fmtチャンクサイズFmtchunkSizeを設定***/ FmtChunkSize=/***ここに何か書く***/; /***↓dataチャンクサイズDataChunkSizeを設定***/ DataChunkSize=/***ここに何か書く***/; /***↓ファイルサイズWholeSizeを設定***/ WholeSize=/***ここに何か書く***/ /***↓波形データWaveDataの設定***/ /***ここに何か書く***/ fp=/***ここに何か書く***/ if(/***ここに何か書く***/){ printf("Cannot open File\n"); exit(1); } /***↓"RIFF"のファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for s_riff\n"); exit(1); } /***↓WholeSizeのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for WholeSize\n"); exit(1); } /***↓"WAVE"のファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for s_wave\n"); exit(1); } /***ここからfmtチャンクのファイル出力***/ /***↓"fmt "の書き込み***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for s_fmt\n"); exit(1); } /***↓fmtチャンクサイズFmtChunkSizeのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for FmtChunkSize\n"); exit(1); } /***↓フォーマットID:FmtIdのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for FmtId\n"); exit(1); } /***↓チャネル数Channelのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for Channel\n"); exit(1); } /***↓サンプリングレートSamplingRateのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for SamplingRate\n"); exit(1); } /***↓データ速度DataVelocityのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for DataVelocity\n"); exit(1); } /***↓ブロックサイズBlockSizeのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for BlockSize\n"); exit(1); } /***↓サンプル単位ビット数Bpsのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for Bps\n"); exit(1); } /***ここまでfmtチャンクのファイル出力***/ /***ここからdataチャンクのファイル出力***/ /***↓"data"のファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for s_data\n"); exit(1); } /***↓dataチャンクサイズDataChunkSizeのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く){ printf("Write Error for DataChunkSize\n"); exit(1); } /***↓波形データWaveDataのファイル出力***/ chk=/***ここに何か書く***/ if(chk</***ここに何か書く***/){ printf("Write Error for Data[%d]\n", i); exit(1); } /***ここまでdataチャンクのファイル出力***/ fclose(fp); return 0; } |
wave.c |
---|
#include<stdio.h> #include<limits.h> #include<math.h> #define WAVEDATASIZE 16000 int main(void){ FILE *fp; /***文字列"RIFF"の宣言・設定***/ const char *s_riff="RIFF"; /***文字列"WAVE"の宣言・設定***/ const char *s_wave="WAVE"; /***ファイルサイズWholeSizeの宣言***/ int WholeSize; /***文字列"fmt "の宣言・設定***/ const char *s_fmt="fmt "; /***fmtチャンクサイズの宣言***/ int FmtChunkSize; /***↓フォーマットID:FmtIDを宣言・設定***/ short FmtId=1; /***↓チャネル数Channelを宣言・設定***/ short Channel=1; /***↓サンプリングレートSamplingRateを宣言・設定***/ int SamplingRate=8000; /***↓データ速度DataVelocityを宣言***/ int DataVelocity; /***↓ブロックサイズBlockSizeを宣言・設定***/ short BlockSize; /***↓サンプル単位ビット数を設定***/ short Bps=16; /***文字列"data"の設定***/ const char *s_data="data"; /***↓dataチャンクサイズを宣言***/ int DataChunkSize; /***↓波形データ配列WaveDataを宣言***/ short wave[WAVEDATASIZE]; int i, chk; /***↓データ速度DataVelocityを設定***/ DataVelocity=SamplingRate*Bps/8*Channel; /***↓ブロックサイズBlockSizeを設定***/ BlockSize=Bps/8*Channel; /***↓fmtチャンクサイズFmtchunkSizeを設定***/ FmtChunkSize= sizeof(FmtId) +sizeof(Channel) +sizeof(SamplingRate) +sizeof(DataVelocity) +sizeof(BlockSize) +sizeof(Bps); /***↓dataチャンクサイズDataChunkSizeを設定***/ DataChunkSize=WAVEDATASIZE*BlockSize; /***↓ファイルサイズWholeSizeを設定***/ WholeSize=strlen(s_wave) +strlen(s_fmt) +sizeof(FmtChunkSize) +FmtChunkSize +strlen(s_data) +sizeof(DataChunkSize) +DataChunkSize; /***波形データwaveの設定***/ for(i=0;i<WAVEDATASIZE;i++){ wave[i]=(short)(SHRT_MAX*sin(2*M_PI*1000.0*((double)i)/(double)(SamplingRate))); } fp=fopen("pcm-8000Hz-1c-2byte-1000Hz-2sec.wav", "wb"); if(fp==NULL){ printf("Cannot open File\n"); exit(1); } /***↓"RIFF"のファイル出力***/ chk=fwrite(s_riff, sizeof(s_riff[0]), strlen(s_riff), fp); if(chk<strlen(s_riff)){ printf("Write Error for s_riff\n"); exit(1); } /***↓WholeSizeのファイル出力***/ chk=fwrite(&WholeSize, sizeof(WholeSize), 1, fp); if(chk<1){ printf("Write Error for WholeSize\n"); exit(1); } /***↓"WAVE"のファイル出力***/ chk=fwrite(s_wave, sizeof(s_wave[0]), strlen(s_wave), fp); if(chk<strlen(s_wave)){ printf("Write Error for s_wave\n"); exit(1); } /***ここからfmtチャンクのファイル出力***/ /***↓"fmt "のファイル出力***/ chk=fwrite(s_fmt, sizeof(s_fmt[0]), strlen(s_fmt), fp); if(chk<strlen(s_fmt)){ printf("Write Error for s_fmt\n"); exit(1); } /***↓fmtチャンクサイズFmtChunkSizeのファイル出力***/ chk=fwrite(&FmtChunkSize, sizeof(FmtChunkSize), 1, fp); if(chk<1){ printf("Write Error for FmtChunkSize\n"); exit(1); } /***↓フォーマットID:FmtIdのファイル出力***/ chk=fwrite(&FmtId, sizeof(FmtId), 1, fp); if(chk<1){ printf("Write Error for FmtId\n"); exit(1); } /***↓チャネル数Channelのファイル出力***/ chk=fwrite(&Channel, sizeof(Channel), 1, fp); if(chk<1){ printf("Write Error for Channel\n"); exit(1); } /***↓サンプリングレートSamplingRateのファイル出力***/ chk=fwrite(&SamplingRate, sizeof(SamplingRate), 1, fp); if(chk<1){ printf("Write Error for SamplingRate\n"); exit(1); } /***↓データ速度DataVelocityのファイル出力***/ chk=fwrite(&DataVelocity, sizeof(DataVelocity), 1, fp); if(chk<1){ printf("Write Error for DataVelocity\n"); exit(1); } /***↓ブロックサイズBlockSizeのファイル出力***/ chk=fwrite(&BlockSize, sizeof(BlockSize), 1, fp); if(chk<1){ printf("Write Error for BlockSize\n"); exit(1); } /***↓サンプル単位ビット数Bpsのファイル出力***/ chk=fwrite(&Bps, sizeof(Bps), 1, fp); if(chk<1){ printf("Write Error for Bps\n"); exit(1); } /***ここまでfmtチャンクのファイル出力***/ /***ここからdataチャンクのファイル出力***/ /***↓"data"のファイル出力***/ chk=fwrite(s_data, sizeof(s_data[0]), strlen(s_data), fp); if(chk<strlen(s_data)){ printf("Write Error for s_data\n"); exit(1); } /***↓dataチャンクサイズDataChunkSizeのファイル出力***/ chk=fwrite(&DataChunkSize, sizeof(DataChunkSize), 1, fp); if(chk<1){ printf("Write Error for DataChunkSize\n"); exit(1); } /***↓波形データwaveのファイル出力***/ chk=fwrite(wave, sizeof(wave[0]), sizeof(wave)/sizeof(wave[0]), fp); if(chk<sizeof(wave)/sizeof(wave[0])){ printf("Write Error for wave[%d]\n", i); exit(1); } /***ここまでdataチャンクのファイル出力***/ fclose(fp); return 0; } |
s_riff
とします。
WholeSize
とします。
これを4バイトで格納するのでint
型で宣言します。
これについては後で計算することにして宣言だけしておきます。
s_wave
とします。
ここからfmtチャンクの作成に必要な変数を宣言していきます。
s_fmt
とします。
FmtChunkSize
とします。
これについては後で計算することにして宣言だけしておきます。
これを4バイトで格納するのでint
型で宣言します。
FmtId
とします。
これを2バイトで格納するのでshort
型で宣言します。
本課題ではリニアPCMに限定して1に設定しておきます。
Channel
とします。
これを2バイトで格納するのでshort
型で宣言します。
本課題ではモノラルに限定して1に設定しておきます。
SamplingRate
とします。
これを4バイトで格納するのでint
型で宣言します。
本課題で指定されているサンプリングレートが8000[Hz]に設定しておきます。
DataVelocity
とします。
これを4バイトで格納するのでint
型で宣言します。
これはサンプリングレート×単位ビット数÷8×チャネル数で表され、
まだ単位ビット数を宣言設定していないので
DataVelocity
の宣言設定は後回しにします。
BlockSize
とします。
これを2バイトで格納するのでshort
型で宣言します。
これは単位ビット数÷8×チャネル数で表され、
まだ単位ビット数を宣言設定していないので
BlockSize
の宣言設定は後回しにします。
Bps
とします。
これを2バイトで格納するのでshort
型で宣言します。
本課題で指定されている16に設定しておきます。
factチャンクは無くても良いので本課題では扱いません。
ここからdataチャンクに必要な変数の宣言・設定を行います。
s_data
とします。
DataChunkSize
とします。
これを4バイトで格納するのでint
型で宣言します。
これについては後で計算することにして宣言だけしておきます。
WaveData
とします。
本課題では単位ビット数が16なのでshort
型で宣言します。
要素数は本課題の指定であるサンプリングレートと時間から16000とします。
LISTチャンクは無くても良いので本課題では扱いません。
これで一通り、プログラミングに必要な変数の宣言が終りました。 その他に必要な変数は適宜、宣言してください。
DataVelocity
を設定します。
データ速度はサンプリングレート×単位ビット数÷8×チャネル数で表され、
変数SamplingRate
, Bps
, Channel
を用いて
設定します。
BlockSize
を設定します。
ブロックサイズは単位ビット数÷8×チャネル数で表され、
変数Bps
, Channel
を用いて
設定します。
FmtChunkSize
を設定します。
すなわち、変数FmtId
, Chennel
, SamplingRate
, DataVelocity
, BlockSize
, Bps
の大きさの和をsizeof
演算子を用いて設定します。
DataChunkSize
を設定します。
すなわち、配列WaveData
の要素数16000にその要素の大きさsizeof(short)
を乗じた値を設定します。
WholeSize
を設定します。
すなわち、
文字列"WAVE", "fmt "の文字数をstrlen
関数を用いて、
変数FmtChunkSize
の大きさをsizeof
を用いて、
それ以降のfmtチャンクサイズは変数FmtchunkSize
に格納されている値を用いて、
文字列"data"の文字数をstrlen
関数を用いて、
変数DataChunkSIze
の大きさをsizeof
を用いて、
それ以降のdataチャンクサイズは変数DataChunkSize
に格納されている値を用いて、
これらの和を設定します。
波形データを作成します。 作成方法については前回のレポート課題を参考にしてください。
ファイルをオープンした後に、 各データをファイルに出力していきます。
fwrite
関数の
第1引数はs_riff
、
第2引数は1文字分の大きさsizeof(s_riff[0])
、
第3引数は文字数strlen(s_riff)
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
WholeSize
を出力します。
このときfwrite
関数の
第1引数は&WholeSize
、
第2引数はデータの大きさsizeof(WholeSize)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
fwrite
関数の
第1引数はs_wave
、
第2引数は1文字分の大きさsizeof(s_wave[0])
、
第3引数は文字数strlen(s_wave)
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
fwrite
関数の
第1引数はs_fmt
、
第2引数は1文字分の大きさsizeof(s_fmt[0])
、
第3引数は文字数strlen(s_fmt)
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
FmtChunkSize
を出力します。
このときfwrite
関数の
第1引数は&FmtChunkSize
、
第2引数はデータの大きさsizeof(FmtChunkSIze)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
FmtId
を出力します。
このときfwrite
関数の
第1引数は&FmtId
、
第2引数はデータの大きさsizeof(FmtId)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
Channel
を出力します。
このときfwrite
関数の
第1引数は&Channel
、
第2引数はデータの大きさsizeof(Channel)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
SamplingRate
を出力します。
このときfwrite
関数の
第1引数は&SamplingRate
、
第2引数はデータの大きさsizeof(SamplingRate)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
DataVelocity
を出力します。
このときfwrite
関数の
第1引数は&DataVelocity
、
第2引数はデータの大きさsizeof(DataVelocity)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
BlockSize
を出力します。
このときfwrite
関数の
第1引数は&BlockSize
、
第2引数はデータの大きさsizeof(BlockSize)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
Bps
を出力します。
このときfwrite
関数の
第1引数は&Bps
、
第2引数はデータの大きさsizeof(Bps)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
fwrite
関数の
第1引数はs_data
、
第2引数は1文字分の大きさsizeof(s_data[0])
、
第3引数は文字数strlen(s_data)
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
DataChunkSize
を出力します。
このときfwrite
関数の
第1引数は&DataChunkSize
、
第2引数はデータの大きさsizeof(DataChunkSize)
、
第3引数はデータの個数1
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
WaveData
の全要素を出力します。
このときfwrite
関数の
第1引数はWaveData
、
第2引数はデータの大きさsizeof(WaveData[0])
、
第3引数はデータの個数sizeof(WaveData)/sizeof(WaveData[0])
、
第4引数はfp
です。
念のためfwrite
関数の戻り値を用いて
書き込みバイト数を確認してください。
後はファイルをクローズして終了です。