As an amateur programmer using Delphi 10.2 I am "working" on a program to clarify the many different scales (dromoi) of greek music.
From a tabulature file I have created a midi-file.
Starting with some basis bytes including header, track, meta-events for key- and time-signature, I build the melody from my tabulature-file (notes + duration).
I would like to be able to change instrument in the midi-file. I have read that this is done by a "Program Change" midi-event coded by Cx + instrument hex value (where x is channel. So what I did was to put these two bytes C0 18 in the end of my basisbytes (after the meta-events) to change to a nylon string guitar.
Unfortunately this does not work. Where do I place the to Program Change bytes? Are they not correct? (I guess that the default channel is zero).
You don't say if you did this, so I must ask.
Every midi event must be preceeded by timing data. The Note On/Off events need this, but you must do the same for any controllers, and a Program Change event will be just the same. So, the C0, 18 may be correct, but it needs timing data first. If this is at the start of the midi file, then 00 (zero) may be valid for timing, in which case 0, C0, 18 may be correct.
However, you are also dependant on the '18' byte being sent somewhere (i.e. a sound module) that will interpret the data as the correct instrument. Hex 18 could well be Guitar using a GM soundset.
If you attach the midi file we could check it for you.
Geoff
If everything worked correctly before you tried to add the Program Change bytes, try checking the following:
• Did you include a delta time before the Program Change bytes?
• Did you adjust the length value in the MTrk header to match the new length of the track in bytes?
[quotePost id=15354]Where do I place the [] Program Change bytes? [...] (I guess that the default channel is zero).[/quotePost] You put the Program Change before the notes you want it to affect. A Program Change will only affect notes that use the same channel. (A Program Change with a status byte of Cx will only affect Notes with status bytes of 9x or 8x if the x value matches.) Hex 0 is Channel 1 and so on up to hex F is Channel 16.
You are rigth both of you. I forgot the '00' before 'C018'. My 'Program Change' line is placed correctly just befor the melody is played.
But trying to figure out how the MIDI file is structured, and get som expirience by trial and error, is funny but also hard with a steep learning curve.
Being a digital interpreter it is not surpricing that MIDI system want its files composed in correct order. Sometimes I get a little dizzy.
I guess that was why the zeros disappeared.
Thank you for your help! I will return soon I guess 😉