// (c) Günter Nagler 2025 GNMIDI script // // this script contains functions for copying a part of a midi file to an other position // do not use it for copying setup measure at beginning of song (this part should only be once in a midi file) // do not copy to a position before setup measure (near begin of song) if it contains MIDI reset initialisations // call function copyunits instead if you want to copy an units range part function copyunits(fromunit, tillunit, insertatunit) { if (tillunit <= fromunit) throwexception("error: tillunit must be greater than fromunit"); var copiedunits = tillunit - fromunit; var moverangelistunits = insertatunit - fromunit; var movelaterunits = +copiedunits; var rangelist = song.collectevents("startunit", ">=", fromunit, "startunit", "<", tillunit); var laterlist = song.collectevents("startunit", ">=", tillunit); foreach (var ev in laterlist) { if (ev.type == EVENTTYPE_HEADER) continue; if (ev.hasend) ev.setnoteunits(ev.startunit + movelaterunits, ev.endunit + movelaterunits); else ev.startunit += movelaterunits; } var duplicatelist; foreach (var ev in rangelist) { if (ev.type == EVENTTYPE_HEADER) continue; if (ev.type == EVENTTYPE_TEXT) println("orig: ",ev.event2string()); var dupev = ev.copyevent(song, song.events.size()); if (dupev.hasend) dupev.setnoteunits(ev.startunit+moverangelistunits, ev.endunit + moverangelistunits); else dupev.startunit += moverangelistunits; if (dupev.type == EVENTTYPE_TEXT) println("new: ",dupev.event2string()); dupev.copyevent(song,song.events.size()); } } function copymeasures(fromnr, count, insertbeforenr) // do not use fromnr value 1 { if (count <= 0) throwexception("error: invalid measure count used"); if (fromnr <= 0) throwexception("error: invalid fromnr (used must be 1 or higher)"); if (insertbeforenr <= 0) throwexception("error: invalid insertbeforenr (used must be 1 or higher)"); var fromunit = song.unitatmeasure(fromnr); var tillunit = song.unitatmeasure(fromnr + count); var insertatunit = song.unitatmeasure(insertbeforenr); copyunits(fromunit, tillunit, insertatunit); } var copyfrommeasurenr = 9; // change this to a value greater than 1 var copymeasurecount = 3; // change this to a value greater than 0 var copytobeforemeasurenr = 12; // change this to a value greater than 1 copymeasures(copyfrommeasurenr, copymeasurecount, copytobeforemeasurenr);
// (c) Günter Nagler 2025 GNMIDI script // the script calculates song duration and writes file name and duration into GNMIDI logfile if duration is longer than value of longerthanseconds variable // it does not produce a midi file output var longerthanseconds = 3 * 60; // replace 3 against a minutes number or 3 * 60 against a seconds number var durms = song.timeat(song.lastunit()); if (durms > longerthanseconds*1000) logmessage(input, " is longer: ", time2shorttext(seconds2time(durms/1000))); // result is in GNMIDI log file lasttoolstate = "IGNORE";// do not produce output files
// (c) Günter Nagler 2025 GNMIDI script // // change tempo within a given range dynamically between firstbpm and lastbpm // inserts tempo changes every stepunit (default: measure) if necessary var firstunit = 0; var lastunit = song.lastunit(); var firstbpm = 120; var lastbpm = 40; var stepunit = song.getresolution() * 4; // bpm values must be in a correct range if (firstbpm < 40) firstbpm = 40; if (firstbpm > 300) firstbpm = 300; if (lastbpm < 40) lastbpm = 40; if (lastbpm > 300) lastbpm = 300; var oldtempoevents = song.collectevents("type", "=", EVENTTYPE_TEMPO); foreach (var ev in oldtempoevents) { song.deleteevent(ev); } var bpmatunit; var curbpm = -1; for (var unit = 0; unit < lastunit; unit+= stepunit) { // interpolate tempo //(bpmatunit - firstbpm) / (lastbpm - firstbpm) = unit / lastunit; bpmatunit = round(((lastbpm - firstbpm) * unit) / lastunit) + firstbpm; if (curbpm == bpmatunit) continue; // do not insert twice song.inserttempo(1,unit,bpm2microsecperbeat(bpmatunit)); curbpm = bpmatunit; }