- Sep 19, 2000
- 10,284
- 138
- 106
Code:
#include <windows.h>
#include <cmath>
#include <cstdio>
void Message(LPCSTR msg);
#define PI 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651
BOOL PlayFreq(long FREQUENCY, long DurationMillisecs)
{
// taken from http://www.tmsoft.com/tutorial-sound.html
HWAVEOUT hWaveOut; // Handle to sound card output
WAVEFORMATEX WaveFormat; // The sound format
WAVEHDR WaveHeader; // WAVE header for our sound data
HANDLE Done; // Event Handle that tells us the sound has finished being played.
// This is a real efficient way to put the program to sleep
// while the sound card is processing the sound buffer
double x;
int i;
// ** Initialize the sound format we will request from sound card **
WaveFormat.wFormatTag = WAVE_FORMAT_PCM; // Uncompressed sound format
WaveFormat.nChannels = 1; // 1=Mono 2=Stereo
WaveFormat.wBitsPerSample = 8; // Bits per sample per channel
WaveFormat.nSamplesPerSec = 44100; //1000*(DurationMillisecs/1000); // Sample Per Second
WaveFormat.nBlockAlign = WaveFormat.wBitsPerSample / 8 * WaveFormat.nChannels;
WaveFormat.nAvgBytesPerSec = (WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign);
WaveFormat.cbSize = 0;
int BUFFERSIZE = (DurationMillisecs * WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign) / 1000; // 4k sound buffer
char* Data = new char[BUFFERSIZE]; // Sound data buffer
// ** Create our "Sound is Done" event **
Done = CreateEvent (0, FALSE, FALSE, 0);
// ** Open the audio device **
if (waveOutOpen(&hWaveOut,0,&WaveFormat,(DWORD) Done,0,CALLBACK_EVENT) != MMSYSERR_NOERROR)
{
MessageBox(0,"Sound card cannot be opened.", "error", 0);
return TRUE;
}
// ** Make the sound buffer **
for (i=0; i < BUFFERSIZE; i++)
{
// ** Generate the sound wave based on FREQUENCY define
// ** x will have a range of -1 to +1
x = sin(i * 2.0 * PI * FREQUENCY / WaveFormat.nSamplesPerSec) / 2;
long long val = ((1 << (WaveFormat.wBitsPerSample - 1)) - 1)*x+(1 << (WaveFormat.wBitsPerSample - 1));
//printf("%d\n", val);
//printf("%d\n", val);
// ** scale x to a range of 0-255 (signed char) for 8 bit sound reproduction **
for (int j = 0; j < WaveFormat.nBlockAlign; ++j)
{
Data[i + j] = ((unsigned char*)&val)[j];
}
i += WaveFormat.nBlockAlign - 1;
}
// ** Create the wave header for our sound buffer **
WaveHeader.lpData=Data;
WaveHeader.dwBufferLength=BUFFERSIZE;
WaveHeader.dwFlags=0;
WaveHeader.dwLoops=0;
// ** Prepare the header for playback on sound card **
if (waveOutPrepareHeader(hWaveOut,&WaveHeader,sizeof(WaveHeader)) != MMSYSERR_NOERROR)
{
Message("Error preparing Header!");
return TRUE;
}
// ** Play the sound! **
ResetEvent(Done); // Reset our Event so it is non-signaled, it will be signaled again with buffer finished
if (waveOutWrite(hWaveOut,&WaveHeader,sizeof(WaveHeader)) != MMSYSERR_NOERROR)
{
Message("Error writing to sound card!");
return TRUE;
}
// ** Wait until sound finishes playing
if (WaitForSingleObject(Done,INFINITE) != WAIT_OBJECT_0)
{
Message("Error waiting for sound to finish");
return TRUE;
}
// ** Unprepare our wav header **
if (waveOutUnprepareHeader(hWaveOut,&WaveHeader,sizeof(WaveHeader)) != MMSYSERR_NOERROR)
{
Message("Error unpreparing header!");
return TRUE;
}
// ** close the wav device **
if (waveOutClose(hWaveOut) != MMSYSERR_NOERROR)
{
Message("Sound card cannot be closed!");
return TRUE;
}
// ** Release our event handle **
CloseHandle(Done);
delete[] Data;
return FALSE;
}
void Message(LPCSTR msg)
{
MessageBox(0, msg, " ",0);
}
void sing()
{
double aCoff[] = {310.26875,-39.47032537521871,9.798126630798038,
13.27051785371783,-16.96040764008566,-8.906423734050552,-
37.73534821290271,7.801101044011428,-7.55374999999998,-
21.58412966106785,-26.72665337680714,12.13025974357324,-
4.939592359914349,-24.97963523747909,-22.5211250410882,
61.73863536651369,58.0
};
double bCoff[] = {0,38.24090914589485,50.57997447236831,14.18197189328155,
35.3284701257369,9.032153654031216,24.38626527586978,1.899775329574208
,15.44625000000001,9.682803946630628,14.05242300568981,
18.2559896635539,-1.256529874263107,19.8910892770428,73.63113220218833
,66.50921913718983,0
};
for (int j = 0; j < 24; ++j)
{
double sum = 0;
for (int i = 0; i < 17; ++i)
{
sum += aCoff[i] * cos (2 * i * j * PI / 32) + bCoff[i] * sin (2 * i * j * PI / 32);
}
if (j % 4 == 3)
PlayFreq(sum, 1000);
else
{
PlayFreq(sum, 500);
PlayFreq(sum, 500);
}
}
}
int main()
{
while(true)
{
sing();
Sleep(1000);
}
}
This hunk of code does something pretty clever. Can you figure out what the exact output is without compiling and running it? (If you do compile it, you'll need to link against the winmm library. Barring that, you need to replace PlayFreq() with your favorite Beep() alternative.)
The code is in C++, though, I don't think I did anything C++y in it. so a good C compiler should be able to handle it.
Lets see how clever ya all are :awe: (this is what happens when you have too much spare time)