#include #include "wave.h" /**************** staticに関する補足説明 ********************* (1)「関数がstatic宣言されている」 関数がstatic宣言されると,この関数はこのファイルの中でしか使え なくなる。 このファイルの関数群のうち,外部に公開されている関数と,外部に 公開している関数に分けることが出来る。 公開されている関数のプロトタイプはwave.hに記述されている。 公開されていない関数は,外部からは見えないので,別のソースファ イルを作る上で,関数名の衝突に気をつけることが無くなるメリット がある。 このような効果を関数の隠蔽という。 (2)「関数の外部に置かれたグローバル変数がstatic宣言されている」 関数の外部に置かれたグローバル変数がstatic宣言されると,この変 数はこのファイルの中でしか使えなくなる。 このような効果を変数の隠蔽という。 例 static FILE *fpi; 通常のCプログラミングではfpiはファイル操作の時に必ず用いるが,プロ グラムの大きな流れを考える上では邪魔なものである。ファイルを開いて から閉じるまではこの変数は絶えず参照されるが,毎回これへの参照をプ ログラムに記述させないですむように隠蔽する。 static pcmheader_t pcmheaderi waveファイルのヘッダ部も,毎回プログラミングするのは大変である。 これも隠蔽して,自動で処理させるのがよい。 新たなプログラミングの際は,waveファイルのヘッダ部操作は気にかけず にすむようになっている。 *************************************************************/ typedef struct { char str_riff[4]; unsigned long int fsize_8;/*ファイルサイズ-8 [byte]*/ char str_wave[4]; char str_fmt[4]; unsigned long int info_block_size;/*format〜num_bits_sampleの部分の合計サイズ[byte]*/ unsigned short int wave_format;/*フォーマットID リニアPCM:1*/ unsigned short int number_of_channels;/*チャネル数 nc モノラル:1 ステレオ:2*/ unsigned long int sampling_frequency;/*サンプリング周波数fs [Hz] */ unsigned long int rate;/*平均データ速度r=fs*sb [byte/s]*/ unsigned short int blocksize;/*ブロックサイズsb=(nc*INT(nb/8))[byte/sample time]*/ unsigned short int num_bits_sample;/*1サンプル当たりのビット数nb [bit]*/ char str_data[4]; unsigned long int binarydatasize;/*バイナリデータのサイズ[byte]*/ } pcmheader_t;/*ヘッダ構造体の定義*/ static FILE *fpi; static pcmheader_t pcmheaderi={ {'R','I','F','F'}, 0L, {'W','A','V','E'}, {'f','m','t',' '}, 16L, 0, 0, 0L, 0L, 0, 0, {'d','a','t','a'}, 0L }; static void getString4(char *buff) { fread(buff,1,4,fpi); } static short int getShortInt(void) { unsigned char buff[2]; short int x=0; fread(buff,1,2,fpi); x=(short int)buff[0]+(((short int)buff[1])<<8); return x; } static unsigned long int getLongInt(void) { unsigned char buff[4]; unsigned long int x=0; fread(buff,1,4,fpi); x=(unsigned long int)buff[0]+(((unsigned long int)buff[1])<<8)+(((unsigned long int)buff[2])<<16)+(((unsigned long int)buff[3])<<24); return x; } static int missmatch4char(char s1[],char s2[]) /*4バイトが不一致なら1 一致なら0*/ { int i; for (i=0;i<4;i++) { if (s1[i]!=s2[i]) return 1; } return 0; } static WaveConstant_t getPCMHeader(void) { WaveConstant_t ret={0L,0,0L,0}; char buff[8]; unsigned long int li; unsigned long int extrasize; unsigned long int i; getString4(buff); if (missmatch4char(buff,pcmheaderi.str_riff)) return ret; pcmheaderi.fsize_8=getLongInt(); getString4(buff); if (missmatch4char(buff,pcmheaderi.str_wave)) return ret; getString4(buff); if (missmatch4char(buff,pcmheaderi.str_fmt)) return ret; li=getLongInt(); extrasize=li-pcmheaderi.info_block_size; pcmheaderi.wave_format=getShortInt(); if (pcmheaderi.wave_format!=1) return ret; pcmheaderi.number_of_channels=getShortInt(); pcmheaderi.sampling_frequency=getLongInt(); pcmheaderi.rate=getLongInt(); pcmheaderi.blocksize=getShortInt(); pcmheaderi.num_bits_sample=getShortInt(); for (i=0;i>=8; buff[1]=x&0xff; fwrite(buff,1,2,fpo); } static void putLongInt(unsigned long int x) { unsigned char buff[4]; buff[0]=(unsigned char)(x&0xff); x>>=8; buff[1]=(unsigned char)(x&0xff); x>>=8; buff[2]=(unsigned char)(x&0xff); x>>=8; buff[3]=(unsigned char)(x&0xff); fwrite(buff,1,4,fpo); } static void putPCMHeader(WaveConstant_t *wc) { pcmheadero.sampling_frequency=wc->SamplingFrequency; pcmheadero.num_bits_sample=wc->BitsPerSample; pcmheadero.number_of_channels=wc->NumberOfChannels; pcmheadero.blocksize=pcmheadero.num_bits_sample/8*wc->NumberOfChannels; pcmheadero.binarydatasize=pcmheadero.blocksize*wc->NumberOfSamples; pcmheadero.fsize_8=sizeof(pcmheader_t)+pcmheadero.binarydatasize-8; pcmheadero.rate=pcmheadero.sampling_frequency*pcmheadero.blocksize; putString4(pcmheadero.str_riff); putLongInt(pcmheadero.fsize_8); #ifdef WAVE_OUTPUT_DEBUG printf("fsize_8=%ld\n",pcmheadero.fsize_8); printf("info_block_size=%ld\n",pcmheadero.info_block_size); printf("wave_format=%d\n",pcmheadero.wave_format); printf("number_of_channels=%d\n",pcmheadero.number_of_channels); printf("sampling_frequency=%ld\n",pcmheadero.sampling_frequency); printf("rate=%ld\n",pcmheadero.rate); printf("blocksize=%d\n",pcmheadero.blocksize); printf("num_bits_sample=%d\n",pcmheadero.num_bits_sample); printf("binarydatasize=%ld\n",pcmheadero.binarydatasize); #endif putString4(pcmheadero.str_wave); putString4(pcmheadero.str_fmt); putLongInt(pcmheadero.info_block_size); putShortInt(pcmheadero.wave_format); putShortInt(pcmheadero.number_of_channels); putLongInt(pcmheadero.sampling_frequency); putLongInt(pcmheadero.rate); putShortInt(pcmheadero.blocksize); putShortInt(pcmheadero.num_bits_sample); putString4(pcmheadero.str_data); putLongInt(pcmheadero.binarydatasize); } int openOutputWaveFile(char *fname,WaveConstant_t *WaveConstant) /*0:fault*/ { fpo=fopen(fname,"wb"); if (fpo==NULL) return 0; putPCMHeader(WaveConstant); return 1; } void putSingleCHSampleData(short int SampleData) { unsigned char uc; if (pcmheadero.num_bits_sample==8) { uc=(unsigned char)(((SampleData>>8)&0xff)^0x80); fputc(uc,fpo); } else { putShortInt(SampleData); } } void putSingleCHSampleDataBlock(short int SampleData[], int number) { int i; for (i=0;i