WAVE音声に雑音を付加し,保存する例題です.雑音はrand()関数により発生しており,大きさは0〜10の値で付加しています.
コンパイル例:
Gami[84]% gcc -o rw_wave rw_wave.cpp -lwinmm |
//----------------------------------------------------------------- // rw_wave.cpp: // WAVE ファイルの読込み/書込み //----------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> //----------------------------------------------------------------- // for VC++ //#include <windows.h> //#include <mmsystem.h> //#pragma comment(lib,"winmm.lib") //----------------------------------------------------------------- #ifndef WIN32 // for wave format // included from mmsystem.h typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef struct tWAVEFORMATEX { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; WORD wBitsPerSample; WORD cbSize; } WAVEFORMATEX; #define MAKEFOURCC(c0,c1,c2,c3) ((DWORD)(BYTE)(c0) | \ ((DWORD)(BYTE)(c1)<<8) | \ ((DWORD)(BYTE)(c2)<<16) | \ ((DWORD)(BYTE)(c3)<<24)) #define mmioFOURCC(c0,c1,c2,c3) MAKEFOURCC(c0,c1,c2,c3) #endif //----------------------------------------------------------------- typedef struct { DWORD fileID,fileSize; DWORD fmtID,fmt_type,fmtSize; WAVEFORMATEX wfx; DWORD dataID,dataSize; } WAVE_HEADER; static char chunk_id[12][5] = { // chunk types "data","fact","cue ","plst","list","adtl", "labl","note","ltxt","smpl","inst","\0"}; //----------------------------------------------------------------- void err_exit(char* str); void read_waveheader(FILE** fp,WAVE_HEADER* whdr); void rw_wave(FILE** fp,WAVE_HEADER whdr,char* ofile); void disp_waveheader(char* ifile,WAVE_HEADER whdr); //----------------------------------------------------------------- int main(int argc,char* argv[]) { FILE* fp; char *ifile; WAVE_HEADER whdr; // ファイル名 if(argc >= 2) ifile = argv[1]; else err_exit("Insufficient argument.\n"); // 読込み開始 fp = fopen(ifile,"rb"); if(fp==NULL) err_exit("input file cannot open.\n"); // ヘッダ情報の読み込み read_waveheader(&fp,&whdr); disp_waveheader(ifile,whdr); // 再生開始 rw_wave(&fp,whdr,"output.wav"); // 後片付け fclose(fp); return 0; } void err_exit(char* str) { fprintf(stderr,str); exit(0); } void read_waveheader(FILE** fp,WAVE_HEADER* whdr) { int i,find,idck=1; DWORD drTmp; char tag[4]; // file head fread(&whdr->fileID ,sizeof(DWORD),1,*fp); fread(&whdr->fileSize,sizeof(DWORD),1,*fp); // fmt head fread(&whdr->fmtID ,sizeof(DWORD),1,*fp); fread(&whdr->fmt_type,sizeof(DWORD),1,*fp); fread(&whdr->fmtSize ,sizeof(DWORD),1,*fp); fread(&whdr->wfx ,sizeof(WAVEFORMATEX)-sizeof(WORD),1,*fp); // check chunk info. whdr->dataID = 0; whdr->dataSize = 0; whdr->wfx.cbSize = 0; // check other format fseek(*fp,-2,SEEK_CUR); while(idck){ if(ftell(*fp) > whdr->fileSize) break; fread(tag,sizeof(char),4,*fp); find = 0; for(i=0;;i++){ if(chunk_id[i][0] == '\0') break; if(!strncmp(tag,"data",4)){ whdr->dataID = mmioFOURCC('d','a','t','a'); fread(&whdr->dataSize,sizeof(DWORD),1,*fp); find = 1; idck = 0; break; } else { if(!strncmp(tag,chunk_id[i],4)){ find = 0; fread(tag,sizeof(char),4,*fp); drTmp = mmioFOURCC(tag[0],tag[1],tag[2],tag[3]); fseek(*fp,ftell(*fp)+drTmp,SEEK_SET); break; } } } if(!find) fseek(*fp,ftell(*fp)-(sizeof(DWORD)-1),SEEK_SET); } } void rw_wave(FILE** fpIn,WAVE_HEADER whdr,char* ofile) { int i; // 入力用 WAVEFORMATEX* f = &whdr.wfx; DWORD rc,fmtLen,i_flame,n_flame; DWORD block_size = (f->nChannels*f->nSamplesPerSec*f->wBitsPerSample/8/ f->nBlockAlign) * f->nBlockAlign; BYTE *wav; // 出力用 FILE *fpOut; DWORD wc,cbsize,wave_fsize,dwTmp; //-------------------------------------------------- // 再生用WAVEフォーマットの設定 //-------------------------------------------------- fmtLen = sizeof(DWORD)*7+sizeof(WAVEFORMATEX)-sizeof(WORD); wav = (char*)malloc(block_size); //-------------------------------------------------- // 出力用WAVEファイル //-------------------------------------------------- if((fpOut=fopen(ofile,"wb")) == NULL){ fprintf(stderr,"\ncan not output wave!\n"); return; } //-------------------------------------------------- // ヘッダ部の出力 //-------------------------------------------------- cbsize = sizeof(WAVEFORMATEX)-sizeof(WORD); dwTmp = mmioFOURCC('R','I','F','F'); fwrite(&dwTmp,1,sizeof(DWORD),fpOut); dwTmp = whdr.dataSize + sizeof(char)*12+sizeof(DWORD)*2+cbsize; fwrite(&dwTmp,1,sizeof(DWORD),fpOut); dwTmp = mmioFOURCC('W','A','V','E'); fwrite(&dwTmp,1,sizeof(DWORD),fpOut); dwTmp = mmioFOURCC('f','m','t',' '); fwrite(&dwTmp,1,sizeof(DWORD),fpOut); fwrite(&cbsize,1,sizeof(DWORD),fpOut); fwrite((void*)f,1,cbsize,fpOut); dwTmp = mmioFOURCC('d','a','t','a'); fwrite(&dwTmp,1,sizeof(DWORD),fpOut); dwTmp = whdr.dataSize; fwrite(&dwTmp,1,sizeof(DWORD),fpOut); //-------------------------------------------------- // 読込み //-------------------------------------------------- i_flame = 0; n_flame = whdr.dataSize/block_size; printf("\n**data sec = %ld [sec]\n",n_flame); fprintf(stdout,"Frame: %4d/%4d",i_flame,n_flame); fflush(stdout); srand(time(NULL)); while(1){ // WAVE音声の読込み rc = fread(wav,1,block_size,*fpIn); // 雑音の付加 for(i=0;i<rc;i++){ wav[i] += rand()%10; } // 出力 wc = fwrite(wav,1,rc,fpOut); fprintf(stdout,"\rFrame: %4d/%4d",++i_flame,n_flame); fflush(stdout); if(rc != block_size) break; } fputs("\n",stdout); fflush(stdout); // 後片付け free(wav); fclose(fpOut); } //----------------------------------------------------------------- // WAVE format の表示 //----------------------------------------------------------------- void disp_waveheader(char* ifile,WAVE_HEADER whdr) { char tag[5]; tag[4] = 0; printf("FILE: %s\n",ifile); printf("**FILE HEAD\n"); memcpy(tag,&whdr.fileID,sizeof(DWORD)); printf(" FILE ID: %s\n",tag); printf(" FILE SIZE: %ld[Byte]\n",whdr.fileSize); printf("**WAVE FORMAT\n"); memcpy(tag,&whdr.fmtID,sizeof(DWORD)); printf(" FORMAT ID: %s\n",tag); memcpy(tag,&whdr.fmt_type,sizeof(DWORD)); printf("FORMAT TYPE: %s\n",tag); printf("FORMAT SIZE: %ld\n",whdr.fmtSize); printf("**WAVE INFO.\n"); printf(" WAVE TAG: %d\n",whdr.wfx.wFormatTag); printf(" CHANNEL: %d\n",whdr.wfx.nChannels); printf(" SAMPLE/SEC: %ld\n",whdr.wfx.nSamplesPerSec); printf("BYTE/SAMPLE*CHANNEL: %d\n",whdr.wfx.nBlockAlign); printf(" BIT/SAMPLE: %d\n",whdr.wfx.wBitsPerSample); if(whdr.wfx.cbSize){ printf("EXTRA FORMAT SIZE: %d\n",whdr.wfx.cbSize); } printf("**WAVE DATA INFO.\n"); if(whdr.dataID){ memcpy(tag,&whdr.dataID,sizeof(DWORD)); printf(" DATA ID: %s\n",tag); } else { printf(" DATA ID: null\n"); } printf(" DATA SIZE: %ld[Byte]\n",whdr.dataSize); } |