I'm trying to generate MIDI files in C but I'm having bit trouble with the header chunk of the file.
So the MIDI header is in form of:
chunk type-length-format-ntrks-division
The chunk type is the four ASCII characters 'MThd'; length is a 32-bit representation of the number 6 (high byte first). The rest are 16 bits.
So I created a Struct for the Header which is the following:
struct headerStruct {
char chunktype[4]; //MThd
long length; //32bit length
int format;//16bit format
int ntraks;//16bit number of tracks
int division;//16bit division
};
Then I'm creating the struct in the code:
struct headerStruct *mthd = malloc(sizeof(struct headerStruct));
strncpy(mthd->chunktype, "MThd",4);
mthd->length = 6;
mthd->format = 0;
mthd->ntraks = 1;
mthd->division = 96;
And then I write the file (also with additional stuff not presented here) with fwrite, I'll leave that part of the code out. But if I look at the binary/hex with xxd and compare it to a correct midi file created with let's say ableton I see that they are different and mine is incorrect.
Correct midi header in hex:
4d54 6864 0000 0006 0000 0001 0060
My incorrect midi header in hex:
4d54 6864 0000 0000 0600 0000 0000 0000 0000 0100 6000 0000
What causes this? Is it an endianness issue or am I using wrong data types. I'm on 64bit os X 10.10.5. Because if I understood correctly 16 bit parts in the header should be ints and the length(32bit) long and so on. If it is an endianness thing how can I correct this. I read some endianness topics here but didn't really understand them.
Here's a link to pdf for more information on MIDI: https://www.cs.cmu.edu/~music/cmsip/readings/Standard-MIDI-file-format-updated.pdf
MIDI files require that the values be written in big-endian byte order, aka "network order"; you may find htnol
(3) and htons
(3) to be useful:
#include <arpa/inet.h>
...
mthd->length = htonl(6);
mthd->ntraks = htons(1);
...