HiveBrain v1.2.0
Get Started
← Back to all entries
patterncModerate

Writing computer generated music to a .wav file in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
generatedfilewavwritingcomputermusic

Problem

See the next iteration.

I wrote this simple C program for writing computer generated music to a WAV file over three years ago. I refactored it a little, but it does not look good to me. Any suggestions?

```
#include
#include
#include

/
Magic file format strings.
/
const char fChunkID[] = {'R', 'I', 'F', 'F'};
const char fFormat[] = {'W', 'A', 'V', 'E'};
const char fSubchunk1ID[] = {'f', 'm', 't', ' '};
const char fSubchunk2ID[] = {'d', 'a', 't', 'a'};

/**
WriteWavePCM() configuration:
- 2 channels,
- frequency 44100 Hz.
**/
const unsigned short N_CHANNELS = 2;
const unsigned int SAMPLE_RATE = 44100;
const unsigned short BITS_PER_BYTE = 8;

bool WriteWavePCM(short sound, size_t pairAmount, char fileName){
const static unsigned int fSubchunk1Size = 16;
const static unsigned short fAudioFormat = 1;
const static unsigned short fBitsPerSample = 16;

unsigned int fByteRate = SAMPLE_RATE N_CHANNELS
fBitsPerSample / BITS_PER_BYTE;

unsigned short fBlockAlign = N_CHANNELS * fBitsPerSample / BITS_PER_BYTE;
unsigned int fSubchunk2Size;
unsigned int fChunkSize;

FILE* fout;
size_t ws;

if (!sound || !fileName || !(fout = fopen( fileName, "w" ))) return false;

fSubchunk2Size = pairAmount N_CHANNELS fBitsPerSample / BITS_PER_BYTE;
fChunkSize = 36 + fSubchunk2Size;

// Writing the RIFF header:
fwrite(&fChunkID, 1, sizeof(fChunkID), fout);
fwrite(&fChunkSize, sizeof(fChunkSize), 1, fout);
fwrite(&fFormat, 1, sizeof(fFormat), fout);

// "fmt" chunk:
fwrite(&fSubchunk1ID, 1, sizeof(fSubchunk1ID), fout);
fwrite(&fSubchunk1Size, sizeof(fSubchunk1Size), 1, fout);
fwrite(&fAudioFormat, sizeof(fAudioFormat), 1, fout);
fwrite(&N_CHANNELS, sizeof(N_CHANNELS), 1,

Solution

Endianness

Your program works on little endian machines only. If you care for it to work on any machine, you would need to fix up all of the fwrite() calls to output specifically in little endian format.
Use struct for header

I would suggest creating a struct for the file header. That way, you could fill in all the fields (in an endian correct manner) and then do one single fwrite(). From the code it looks like you can combine all the fields into a single header, but if it makes more sense you could have multiple headers (RIFF header, format header, data header, etc).

Context

StackExchange Code Review Q#105272, answer score: 17

Revisions (0)

No revisions yet.