Correct use of "miditones" utility?

Status
Not open for further replies.

h4yn0nnym0u5e

Well-known member
Hi folks

I'm trying to use the latest version of the executable from https://github.com/LenShustek/miditones to process a 10-track MIDI file to a C source. I believe I have it such that each track outputs a monophonic part on a different channel (1-9 and 11, skipping 10 just in case it decides to interpret it as drums). The original MIDI has 3x violins, 3x viola, 3x celli and continuo - I've changed the patches so that they're all different, though. However, what I get out is 3 voices on channel 1, 3 on channel 2, 3 on 3 and one on 4, which is the same as in the original, though even that has the voices on separate MIDI channels.

The command I'm using is miditones -s2 -t=16 -v ..\brandenburg-3

I believe the -s2 should "try to keep each track to its own tone generator" (from the readme), which I understood to mean each MIDI channel is effectively preserved in the output.

Anyone got any clue as to what I've done wrong here? I'm assuming it's me, it usually is :eek:

The MIDI file I started out from is https://www.8notes.com/school/midi/orchestra/bach_brandenburg_concerto_3_1st_bwv_1041_ORCH.mid, if anyone wants to give it a go. The first few lines of output are:
Code:
// Playtune bytestream for file "..\brandenburg-3.mid" created by MIDITONES V2.2 on Wed May  5 19:36:14 2021
// command line: miditones -s2 -t=16 -v ..\brandenburg-3 
const unsigned char PROGMEM score [] = {
// Brandenburg Concerto No.3
9,29, 0x90,67,81, 0x90,67,81, 0x90,67,81, 0x91,55,81, 0x91,55,81, 0x91,55,81, 0x92,43,81, 0x92,43,81, 
0x92,43,81, 0x93,31,81, 0,166, 0x90,66,76, 0x90,66,76, 0x90,66,76, 0,167, 0x90,67,81, 0x90,67,81, 0x90,67,81, 
0x91,59,83, 0x91,59,83, 0x91,59,83, 0x92,43,81, 0x92,43,81, 0x92,43,81, 0x93,31,81, 1,77, 0x90,62,70, 
0x90,62,70, 0x90,62,70, 0x90,62,81, 0x90,62,81, 0x90,62,81, 0x92,55,86, 0x92,55,86, 0x92,55,86, 0x93,43,82, 
0x81, 0,167, 0x90,60,68, 0x90,60,68, 0x90,60,68, 0,167, 0x90,62,72, 0x90,62,72, 0x90,62,72, 0x90,59,76, 
0x90,59,76, 0x90,59,76, 0x92,55,84, 0x92,55,84, 0x92,55,84, 0x93,43,81, 1,77, 0x91,67,84, 0x91,67,84, 
0x91,67,84, 0x92,55,70, 0x92,55,70, 0x92,55,70, 0x93,43,70, 0x93,43,70, 0x93,43,70, 0x93,31,70, 0x80, 0x82,
The identical note-on commands are correct, as the various instruments start out in unison, it's just that they should be on different channels, not all 0x90, for example. And I think the lack of note-off commands is because there isn't time: I can fix that by adding a -releasetime option to the command line.

Cheers

Jonathan
 
I've been meddling with the miditones code trying to get the "-s2" option to work the way we both think it should and I think I've got it working. If you can compile your own version of miditones, change the find_idle_tgen function to this:
Code:
// find an idle tone generator we can use
int find_idle_tgen(struct noteinfo *np)   // returns -1 if there isn't one
{
    struct tonegen_status *tg;
    int tgnum;
    bool foundgen = false;

//PAH
    if (!foundgen && strategy2) { // try to use the generator corresponding to the track number
        tg = &tonegen[np->track-1];
        if (!tg->playing) {
            tgnum = np->track-1;
            foundgen = true;
        }
    }
//PAH
if(!foundgen) 
    for (tgnum = 0; tgnum < num_tonegens; ++tgnum) { // first, is this note already playing on this channel?
        tg = &tonegen[tgnum];
        if (tg->playing
                && tg->note.note == np->note && tg->note.channel == np->channel) {
            // this must be the start of the sustain phase of a playing note
            ++playnotes_without_stopnotes;
            if (loggen) fprintf(logfile, "      *** playnote without stopnote, tgen %d, %s\n",
                                    tgnum, describe(np));
            foundgen = true;
            break;
        }
    }

    if (!foundgen && strategy2) { // try to use the same tone generator that this track used last time
        struct track_status *trk = &track[np->track];
        tg = &tonegen[trk->preferred_tonegen];
        if (!tg->playing) {
            tgnum = trk->preferred_tonegen;
            foundgen = true;
        }
    }
    
    if (!foundgen)    // if not, then try for a free tone generator that had been playing the same instrument we need
        for (tgnum = 0; tgnum < num_tonegens; ++tgnum) {
            tg = &tonegen[tgnum];
            if (!tg->playing && tg->note.instrument == np->instrument) {
                foundgen = true;
                break;
            }
        }
    if (!foundgen)    // if not, then try for any free tone generator
        for (tgnum = 0; tgnum < num_tonegens; ++tgnum) {
            tg = &tonegen[tgnum];
            if (!tg->playing) {
                foundgen = true;
                break;
            }
        }
    if (foundgen) return tgnum;
    return -1;
}

It first tries to allocate track 'n' to tone generator 'n-1'. If that fails it will try the existing allocation method.
I'm not sure that it avoids that drum channel (10), but we can tackle that next if this fix mostly works.

With this modification, the beginning of the resulting Bach file is this:
Code:
9,29, 0x90,67,81, 0x91,67,81, 0x92,67,81, 0x93,55,81, 0x94,55,81, 0x95,55,81, 0x96,43,81, 0x97,43,81, 
0x98,43,81, 0x99,31,81, 0,166, 0x90,66,76, 0x91,66,76, 0x92,66,76, 0,167, 0x90,67,81, 0x91,67,81, 0x92,67,81, 
0x93,59,83, 0x94,59,83, 0x95,59,83, 0x96,43,81, 0x97,43,81, 0x98,43,81, 0x99,31,81, 0x86, 0x87, 1,77, 0x90,62,70, 
0x91,62,70, 0x92,62,70, 0x93,62,81, 0x94,62,81, 0x95,62,81, 0x96,55,86, 0x97,55,86, 0x98,55,86, 0x99,43,82,

Pete
 
Thanks for that, Pete. I don't have the tools to compile it, unfortunately :(

I worked on it a bit more after posting, concluded there was a bug, and raised an issue with Len on github. He's fixed the issue to some extent, but I think it's revealed another minor problem in that a simultaneous note on and off on a channel (which occurs very often in this file) makes it appear the channel is still playing at note-on channel allocation time, so if there's a spare channel then the note on can still get bumped. -releasetime doesn't fix it. For now I've made every note 13ms shorter in the MIDI file, which seems to give me a clean-enough result.

Cheers

Jonathan
 
Hi Pete

Gave it a quick try, and unfortunately yours goes AWOL on the very next line :eek: Your output:
Code:
// Playtune bytestream for file "bach_brandenburg_concerto_3_1st_bwv_1041_ORCH.mid" created by MIDITONES V2.2 on Thu May 06 21:52:50 2021
// command line: pete-miditones -t=16 -s2 -v bach_brandenburg_concerto_3_1st_bwv_1041_ORCH 
const unsigned char PROGMEM score [] = {
// Brandenburg Concerto No.3
9,29, 0x90,67,81, 0x91,67,81, 0x92,67,81, 0x93,55,81, 0x94,55,81, 0x95,55,81, 0x96,43,81, 0x97,43,81, 
0x98,43,81, 0x99,31,81, 0,166, 0x90,66,76, 0x91,66,76, 0x92,66,76, 0,167, 0x90,67,81, 0x91,67,81, 0x92,67,81, 
0x93,59,83, 0x94,59,83, 0x95,59,83, 0x96,43,81, 0x97,43,81, 0x98,43,81, 0x99,31,81, 0x86, 0x87, 1,77, 0x90,62,70, 
0x91,62,70, 0x92,62,70, 0x93,62,81, 0x94,62,81, 0x95,62,81, 0x96,55,86, 0x97,55,86, 0x98,55,86, 0x99,43,82, 
0,167, 0x90,60,68, 0x91,60,68, 0x92,60,68, 0,167, 0x90,62,72, 0x91,62,72, 0x92,62,72, [B][COLOR="#FF0000"]0x90,59,76, 0x90,59,76, 
0x90,59,76,[/COLOR][/B] 0x96,55,84, 0x97,55,84, 0x98,55,84, 0x99,43,81, 0x81, 0x82, 0x86, 0x87, 1,77, 0x91,67,84, 0x91,67,84,

Len's modified output:
Code:
// Playtune bytestream for file "bach_brandenburg_concerto_3_1st_bwv_1041_ORCH.mid" created by MIDITONES V2.4 on Thu May  6 21:53:18 2021
// command line: len-miditones -t=16 -s2 -v bach_brandenburg_concerto_3_1st_bwv_1041_ORCH 
const unsigned char PROGMEM score [] = {
// Brandenburg Concerto No.3
9,29, 0x90,67,81, 0x91,67,81, 0x92,67,81, 0x93,55,81, 0x94,55,81, 0x95,55,81, 0x96,43,81, 0x97,43,81, 
0x98,43,81, 0x99,31,81, 0,166, 0x90,66,76, 0x91,66,76, 0x92,66,76, 0,167, 0x90,67,81, 0x91,67,81, 0x92,67,81, 
0x93,59,83, 0x94,59,83, 0x95,59,83, 0x96,43,81, 0x97,43,81, 0x98,43,81, 0x99,31,81, 0x86, 0x87, 1,77, 0x90,62,70, 
0x91,62,70, 0x92,62,70, 0x93,62,81, 0x94,62,81, 0x95,62,81, 0x96,55,86, 0x97,55,86, 0x98,55,86, 0x99,43,82, 
0,167, 0x90,60,68, 0x91,60,68, 0x92,60,68, 0,167, 0x90,62,72, 0x91,62,72, 0x92,62,72, [B][COLOR="#007F00"]0x90,59,76, 0x91,59,76, 
0x92,59,76,[/COLOR][/B] 0x96,55,84, 0x97,55,84, 0x98,55,84, 0x99,43,81, 0x86, 0x87, 1,77, 0x93,67,84, 0x94,67,84, 0x95,67,84,

Thanks so much for giving it a go, and feel free to carry on if you want to...

Cheers

Jonathan
 
One final item to note... Len discovered that the original MIDI file isn’t as clean as it looks. The note ends jitter a tiny bit, about 3ms, and if they go long then the allocation algorithm uses an unexpected channel. -release time=5 should fix this.
 
Status
Not open for further replies.
Back
Top