// MakeSineWaveFile // 正弦波を生成する // Make16BitStereo()はLがSin(wt)、RがCos(wt) // 引数 // filiename, freq[Hz], time[sec] #include "stdafx.h" #include #include #define _USE_MATH_DEFINES // for C++ M_XXXを有効にする #include // #include typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; typedef struct { char sRiff[4]; // 'RIFF'の4文字 DWORD nFileSize; // 総ファイルサイズ-8(byte) char sWave[4]; // 'WAVE'の4文字 char sFmt[4]; // 'fmt 'の4文字 フォーマットチャンク DWORD nFmtSize; // フォーマットサイズ デフォルト値16。リニアPCM ならば 16 WORD wFormatTag; // フォーマットコード 非圧縮のPCMフォーマットは1 WORD nChannels; // チャンネル数 モノラルは1、ステレオは2 DWORD nSamplesPerSec; // サンプリングレート 44.1kHzの場合なら44100 DWORD nAvgBytesPerSec; // バイト/秒 1秒間の録音に必要なバイト数 WORD nBlockAlign; // ブロック境界 ステレオ16bitなら、16bit*2 = 32bit = 4byte WORD wBitsPerSample; // ビット/サンプル 1サンプルに必要なビット数 char sData[4]; // 'data'の4文字 フォーマットチャンク DWORD nDataSize; // 波形データのバイト数 } WAVHEADER; #define SRATE 44100 // 44.1 KHz // 16bit Stereo // L: Sin(wt) // R: Cos(wt) int Make16BitStereo(int argc, char* argv[]) { FILE *fpWav; BYTE *bWave; if (argc != 4) { printf("\n\n\tMakeSinWavFile filiename freq[Hz] time[sec]\n\n"); return(1); } WAVHEADER wh = { { 'R', 'I', 'F', 'F' }, // 'RIFF'の4文字 0, // 総ファイルサイズ-8(byte) { 'W', 'A', 'V', 'E' }, // WAVEヘッダ { 'f', 'm', 't', ' ' }, // 'fmt 'の4文字 フォーマットチャンク 16, // フォーマットサイズ デフォルト値16。リニアPCM ならば 16 1, // フォーマットコード 非圧縮のPCMフォーマットは1 2, // チャンネル数 モノラルは1、ステレオは2 SRATE, // サンプリングレート 44.1kHzの場合なら44100 SRATE * 4, // バイト/秒 1秒間の録音に必要なバイト数。44.1kHz 16bitステレオならば 44100×2×2=176400 4, // ブロックサイズ (Byte/sample×チャンネル数)。16bit ステレオ ならば 2×2 = 4 16, // ビット/サンプル 1サンプルに必要なビット数。WAV フォーマットでは 8bit か 16bit。16bit ならば 16 { 'd', 'a', 't', 'a' }, // 'data'の4文字 フォーマットチャンク 0 // 波形データのバイト数 }; double freq = atof((const char*)argv[2]); // 周波数 int nSamples = (int)(atof((const char*)argv[3]) * SRATE); // サンプル数 errno_t err = fopen_s(&fpWav, (const char*)argv[1], "wb"); if (err != NULL) { printf("ファイル '%s' が書き込みオープンできません", argv[1]); return(1); } // 16bit Stereo long nLength = nSamples * 4; // 16bit StereoなのでnSamplesの4倍 bWave = (BYTE*)malloc(nLength); double angle = 0.0; for (long n = 0; n < nLength; n += 4) { // 16bit StereoなのでnSamplesの4倍 int ch1 = (int)(0x7fff * sin(angle)); int ch2 = (int)(0x7fff * cos(angle)); bWave[n] = (BYTE)(ch1 & 0x00ff); // 下位バイト 正弦波 bWave[n + 1] = (BYTE)((ch1 & 0xff00) >> 8); // 上位バイト 正弦波 bWave[n + 2] = (BYTE)(ch2 & 0x00ff); // 下位バイト 正弦波 bWave[n + 3] = (BYTE)((ch2 & 0xff00) >> 8); // 上位バイト 正弦波 //printf("%d, %d, %d, %d\n", n, ch1, bWave[n], bWave[n + 1]); angle = angle + 2 * M_PI * freq / SRATE; if (angle > 2 * M_PI) angle = angle - 2 * M_PI; } wh.nFileSize = 36 + nLength; // 先頭の8バイトは含まない値 wh.nDataSize = nLength; fwrite(&wh, sizeof(wh), 1, fpWav); fwrite(bWave, sizeof(BYTE), nLength, fpWav); fclose(fpWav); free(bWave); return 0; } int _tmain(int argc, char* argv[]) { return Make16BitStereo(argc, argv); }