/ Examples / MIDI File

Right-click to copy examples to your workspace


Wherein we present an example of Hz support for performing MIDI files.

Right-click to copy examples to your workspace

Here's a simple driver script to perform a MIDI file on a single instrument node (here FluidSynth). Of note is the configuration object which is pass to the Perform method. The programMapper field supports a callback function that allows your code to assign a MIDI program number to each track in the file.

let thisDir = path.dirname(this.GetFilePath());

// select one of our example files by setting the array index to 0, 1 or 2.
let f = ["bwv772.mid", "bach_846.mid", "lotus.midi"][2];
let uri = path.join(thisDir, f);

// instantiate a MidiFile object.
let midiFile = new MidiFile();
// asyncrhonously load th file
let err = await midiFile.Load(uri);
if(err) return;

// start up audio engine with a FluidSynth since it supports
// General MIDI voice assignments.
let scene = await Ascene.BeginFiber(this);
let fluid = scene.NewAnode("FluidSynth");
let gain = scene.NewAnode("Hz.Mix", {cfg:"stereo", preset:{Gain:-8}});
let dac = scene.GetDAC();
scene.Chain(fluid, gain, dac);
await scene.Sync();
// fluid.Show();
gain.Show();

// establish midi file configurations
// nb: we can also perform a single track
let cfg =
{
    speed: 1,   
    setTempo: "once", // "once" | "never" | "always" (busted for bach)
    programChange: "allow",
    programMapper: function(oldProg, trk)
    {
        if(f.startsWith("lotus"))
        {
            let newProg = oldProg;
            console.log(`prog ${trk} ${oldProg} -> ${newProg}`);
            return newProg;
        }
        else
        if(f.startsWith("bach"))
        {
            let newProg = 24 + trk;
            console.log(`prog ${trk} ${oldProg} -> ${newProg}`);
            return newProg;
        }
        else
            return oldProg;
    },
    dumpTrack: null, // -1 means all
    dumpJoin: true
};
if(cfg.dumpTrack != null)
    midiFile.Dump(cfg);

// This is where it all happens -------------------------------------
console.log(`${f} has ${midiFile.GetNumTracks()} tracks, format ${midiFile.GetFormat()}`);
for await (const val of midiFile.Perform(fluid, .5, cfg))
{
    yield;
}

Resources

Pianoroll Music

Adl-Piano-MIDI (github)

home .. topics .. interface .. reference .. examples .. tipjar