SampleWave.c
// winmm.lib #define _USE_MATH_DEFINES #include <math.h> #include <stdio.h> #include <windows.h> #include <mmsystem.h> #define VOLUME 1024 #define SAMPLE_RATE 44100 #define TONE_MSEC 250 #define TONE_NUM 24 #define TONE_LEN (SAMPLE_RATE * TONE_MSEC / 1000) #define DATA_LEN (TONE_LEN * TONE_NUM) int main() { WAVEFORMATEX wfx; HWAVEOUT hwo; MMRESULT mmr; WAVEHDR wh; double dFreq; // 周波数 double dPhase; // 位相 double dDiff; // 差分 double dWave; short asData[DATA_LEN]; int aiScale[] = {3, 5, 7, 8, 10, 12, 14, 15}; // 音階 int iIndex; int iForm; int iScale; int i; // 波形データの作成 iIndex = 0; for (iForm = 0; iForm < 3; iForm++) { for (iScale = 0; iScale < 8; iScale++) { dFreq = 440.0 * pow(2.0, aiScale[iScale] / 12.0); dPhase = 0.0; dDiff = dFreq / SAMPLE_RATE; for (i = 0; i < TONE_LEN; i++) { switch (iForm) { case 0: // サイン波 dWave = sin(2 * M_PI * i * dFreq / SAMPLE_RATE); break; case 1: // 三角波 if (dPhase < 0.25) { dWave = dPhase * 4; } else if (dPhase < 0.75) { dWave = 1.0 - (dPhase - 0.25) * 4; } else { dWave = -1.0 + (dPhase - 0.75) * 4; } break; case 2: // 矩形波(duty比 0.5) if (dPhase < 0.5) { dWave = 1.0; } else { dWave = -1.0; } break; } asData[iIndex++] = (short)(VOLUME * dWave); dPhase += dDiff; if (1.0 <= dPhase) dPhase -= 1.0; } } } // Play wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 1; wfx.nSamplesPerSec = SAMPLE_RATE; wfx.nAvgBytesPerSec = SAMPLE_RATE * 2; wfx.nBlockAlign = 2; wfx.wBitsPerSample = 16; wfx.cbSize = 0; mmr = waveOutOpen(&hwo, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL); if (mmr != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutOpen\n"); return 1; } memset(&wh, 0, sizeof(WAVEHDR)); wh.lpData = (LPSTR)asData; wh.dwBufferLength = DATA_LEN * sizeof(short); mmr = waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutPrepareHeader\n"); return 1; } mmr = waveOutWrite(hwo, &wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutWrite\n"); return 1; } // Wait Sleep(TONE_MSEC * TONE_NUM); // Stop mmr = waveOutReset(hwo); if (mmr != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutReset\n"); return 1; } mmr = waveOutUnprepareHeader(hwo, &wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutUnprepareHeader\n"); return 1; } mmr = waveOutClose(hwo); if (mmr != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutClose\n"); return 1; } return 0; }