Generating WAV files
May 3, 2020 at 11:52 am
(This post was last modified: May 3, 2020 at 11:52 am by FlatAssembler.)
Hey, guys!
So, recently, I've made a simple program that converts notes stored in a text file into waveforms. However, now it can't produce WAV files, only raw data, and you need to use ffmpeg or some similar tool to convert them to WAV files. I've tried to write a program in C that produces actual WAV files, however, the players complain its header is corrupt. Can you guess what's actually going on?
I've also posted this question on the Audacity forum, however I haven't got a response.
So, recently, I've made a simple program that converts notes stored in a text file into waveforms. However, now it can't produce WAV files, only raw data, and you need to use ffmpeg or some similar tool to convert them to WAV files. I've tried to write a program in C that produces actual WAV files, however, the players complain its header is corrupt. Can you guess what's actually going on?
Code:
#include <stdint.h>
#include <stdio.h>
#include <math.h>
int main() {
FILE *wav=fopen("example.wav","wb");
fprintf(wav,"RIFF");
const int sampleRate=8192;
int32_t ChunkSize=36+8*sampleRate*2;
fwrite(&ChunkSize,4,1,wav);
fprintf(wav,"WAVEfmt");
int32_t Subchunk1Size=16; //PCM header is always 16 bytes
fwrite(&Subchunk1Size,4,1,wav);
int16_t AudioFormat=1; //PCM
fwrite(&AudioFormat,2,1,wav);
int16_t NumChannels=1; //MONO audio.
fwrite(&NumChannels,2,1,wav);
int32_t SampleRate=sampleRate;
fwrite(&SampleRate,4,1,wav);
int32_t ByteRate=2*sampleRate;
fwrite(&ByteRate,4,1,wav);
int16_t BlockAlign=2;
fwrite(&BlockAlign,2,1,wav);
int16_t BitsPerSample=16;
fwrite(&BitsPerSample,2,1,wav);
fprintf(wav,"data");
int32_t Subchunk2Size=ChunkSize-36;
for (int i=0; i<8*sampleRate; i++) {
float currentFrequency;
if (i<=sampleRate)
currentFrequency=262; //The C tone is 262Hz.
else if (i>sampleRate && i<=2*sampleRate)
currentFrequency=294; //The D tone is 294Hz.
else if (i>2*sampleRate && i<=3*sampleRate)
currentFrequency=330; //The E tone is 330Hz.
else if (i>3*sampleRate && i<=4*sampleRate)
currentFrequency=349; //The F tone.
else if (i>4*sampleRate && i<=5*sampleRate)
currentFrequency=391; //The G tone.
else if (i>5*sampleRate && i<=6*sampleRate)
currentFrequency=440; //The A tone.
else if (i>6*sampleRate && i<=7*sampleRate)
currentFrequency=494; //The H sound.
else
currentFrequency=523; //The Tenor C.
float baseFrequency=sin(2*M_PI*currentFrequency*i/sampleRate)*16384;
float secondHarmony=sin(2*M_PI*2*currentFrequency*i/sampleRate)*4096;
float thirdHarmony=sin(2*M_PI*3*currentFrequency*i/sampleRate)*41024;
float currentAmplitude=baseFrequency+secondHarmony+thirdHarmony*exp(-(float)(i%sampleRate+2000)/2000);
int16_t numberToBeWritten=currentAmplitude;
fwrite(&numberToBeWritten,2,1,wav);
}
fclose(wav);
}