General Development

Parsing a Midi file – WilliamLow

WilliamLow
Member

Posts: 15
From: Ontario, Canada
Registered: 09-21-2005
Hi,

I was wondering if anyone has had any experience with parsing a midi file.

I haven't had any experience as to parsing a file, so I'm not exactly sure how you read into the file's contents. I've read about the contents of a midi file ( i.e. its header, the header chunk, and the track chunk ), but I'm having problems getting that information from a file using C.

Any help would be appreciated, thanks in advance.

Klumsy

Administrator

Posts: 1061
From: Port Angeles, WA, USA
Registered: 10-25-2001
what particular information do you want from the midi file, and how do you intend to use it?

------------------
Karl /GODCENTRIC
Visionary Media
the creative submitted to the divine.
Husband of my amazing wife Aleshia
Klumsy@xtra.co.nz

WilliamLow
Member

Posts: 15
From: Ontario, Canada
Registered: 09-21-2005
For now, I'd like to read in a midi file and print out its information such as format, and number of tracks.
HanClinto

Administrator

Posts: 1828
From: Indiana
Registered: 10-11-2004
this looks interesting...

------------------
http://www.includingjudas.com/christiangame.html

WilliamLow
Member

Posts: 15
From: Ontario, Canada
Registered: 09-21-2005
Thanks for the link, it's really helpful
Briant

Member

Posts: 742
From: Stony Plain, Alberta, Canada
Registered: 01-20-2001
Hi William, and welcome!

With MIDI or basically any other type of binary file, once you know the format it is relatively easy to write a program that reads and parses that data. "structs" are your friend!

For example, a MIDI file has two basic types of "chunks", a header chunk and at least one track chunk. Each chunk would require it's own struct to hold the info. You could define a header chunk like this:

struct MIDIHeader
{
DWORD fileid; // four bytes identifier "MThd"
DWORD size; // size of header, in 4 bytes (will always be 6)
WORD format; // the first 2 of the 6 bytes: 0 = single-track, 1 = multiple tracks synchronous, 2 = multiple tracks, asynchronous
WORD numtracks; // the second 2 bytes, the number of tracks
WORD dtime; // the last 2 bytes, the delta-time ticks per q-note
};

struct MIDITrack
{
DWORD trackid; // 4 bytes, "MTrk"
BYTE *data;
};

Then you could do the following (semi-pseudocode):

MIDIHeader header;
FILE *fp = fopen("file.mid", "rb");
fread(&header, sizeof(header), 1, fp);
int i;
for(i=0;i<header.numtracks;i++)
{
// read in track header
// read in bytes until hit the next track header
// create a new MIDITrack
// pTrack->trackid = track header read in
// pTrack->data = new BYTE [num data bytes read in]
// memcpy(pTrack->data, data bytes read in, num data bytes)
}
fclose(fp);

Once you have the whole file read in this way, then you have the task of going through the data for each track and parsing out the individual MIDI commands in the data. That's how I would do it, anyway.

Brian

------------------
Brian

WilliamLow
Member

Posts: 15
From: Ontario, Canada
Registered: 09-21-2005
Cool, thanks Brian. Your sample code simplified a lot of things for me.