The code below is supposed to generate a 4-seconds long wave file of a sinewave at 440 Hz frequency, 16 bits per sample and at 44100 Hz sampling rate.
The code compiles fine and I run it in Windows console with the command “wave.exe > sine440.wav”.
However, when I play the resulting file I hear a horrible amount of noise mixed with the sine tune. I’ve generated a wave file with those specifications in Audacity and compared the files: the filesizes and headers are identical. So, the problem is in my samples values.
If anyone could help me with this, I’d be very grateful.
#include<math.h>
#define SAMPLE_RATE 44100
#define BITS_PER_SAMPLE 16
#define TIME 4
#define FREQ 440
#define PI 3.14159
void putint(unsigned int x)
{
unsigned int y = x;
if(x <= 0xFFFF) {
putchar(x & 0x00FF);
x = x & 0xFF00;
x = x >> 8;
putchar(x);
}
else {
putchar(x & 0x000000FF);
x = x & 0x0000FF00;
x = x >> 8;
putchar(x);
x = y;
x = x & 0x00FF0000;
x = x >> 16;
putchar(x);
x = y;
x = x & 0xFF000000;
x = x >> 24;
putchar(x);
}
}
int main()
{
int datasize = SAMPLE_RATE * BITS_PER_SAMPLE * TIME / 8; // size of waveform data in bytes
int filesize = datasize + 44, i; // file size in bytes
short sample;
double angle = 0.0;
putchar('R'), putchar('I'), putchar('F'), putchar('F'); // 4 bytes - "RIFF"
putint(filesize - 8); // 4 bytes - size of waveform chunk
putchar('W'), putchar('A'), putchar('V'), putchar('E'); // 4 bytes - "WAVE"
putchar('f'), putchar('m'), putchar('t'), putchar(' '); // 4 bytes - "fmt "
putint(16), putint(0); // 4 bytes - size of format chunk(16 bytes)
putint(1); // 2 bytes - wf.wFormatTag = WAVE_FORMAT_PCM = 1
putint(1); // 2 bytes - wf.nChannels
putint(SAMPLE_RATE), putint(0); // 4 bytes - wf.nSamplesPerSec
putint(SAMPLE_RATE * BITS_PER_SAMPLE / 8); // 4 bytes - wf.nAvgBytesPerSec
putint(BITS_PER_SAMPLE/8); // 2 bytes - wf.nBlockAlign
putint(BITS_PER_SAMPLE); // 2 bytes - wf.wBitsPerSample
putchar('d'), putchar('a'), putchar('t'), putchar('a'); // 4 bytes - "data"
putint(datasize); // 4 bytes - size of waveform data
for(i = 0; i < datasize; i += 2)
{
sample = (short)(32767 * sin(angle));
putchar(sample & 0x00FF);
sample = sample & 0xFF00;
sample = sample >> 8;
putchar(sample);
angle += 2 * PI * FREQ / SAMPLE_RATE;
if(angle > 2 * PI)
angle -= 2 * PI;
}
return 0;
}