GNMIDI

Table of Contents Keyword Index
gnscript event modification expression syntax
Previous  Top  Next

Few GNMIDI operations use gnscript expressions to modify MIDI events (for experts only).
The current event can be modified or removed by one or more commands and conditionally.

gnscript language
https://www.gnmidi.com/gnscript.htm is a demo script interpreter with many script examples for learning programming. It is easier to learn programming by examples than by syntax.
There you can find the complete syntax of the script language.
Hint: gnscript language self does not contain MIDI support. GNMIDI and GNMIDI user tools use gnscript and a MIDI extension that supports MIDI file operations (e.g. variables song, ev, functions like midiload, midisave ...).

variables
song is a structure song information
            song.filename     a string
            song.events       a vector of MidiEvent objects

ev is a structure of event informations
ev.type can be
               EVENTTYPE_NOTE
               EVENTTYPE_PROGRAM
               EVENTTYPE_CONTROL
               EVENTTYPE_HEADER
               EVENTTYPE_TEMPO
               EVENTTYPE_TACT
               EVENTTYPE_TEXT
               EVENTTYPE_PITCHBEND
               EVENTTYPE_AFTERTOUCH
               EVENTTYPE_POLYAFTERTOUCH
               EVENTTYPE_KEY
               EVENTTYPE_SYSEX
               EVENTTYPE_META
               EVENTTYPE_REALTIME
               EVENTTYPE_ENDTRACK

depending on the event type events have different attributes
          ev.track      track number (1,...)
          ev.channel    channel number (0 for no channel, 1-16)
          ev.startunit  MIDI unit where event started (0 is song start)
          ev.endunit    event EVENTTYPE_NOTE contains MIDI unit where note event finished  (endunit must be greater or equal startunit)
          ev.length     event EVENTTYPE_NOTE contains note length in MIDI units (can also be 0)
          ev.startms    start time in milliseconds where event started (0 is song start)
          ev.endms      event EVENTTYPE_NOTE contains end time in milliseconds where note event finished
          ev.duration   event EVENTTYPE_NOTE contains note duration in milliseconds
          ev.velocity         event EVENTTYPE_NOTE contains note on velocity (1-127)
          ev.velocityoff     event EVENTTYPE_NOTE contains note off velocity (0-127)
          ev.hasstart   can be 0 when note on/off are not combined
          ev.hasend     can be 0 when note on/off are not combined
          ev.iscombined  1 when note on and off are combined to a pair in the ev structure
          ev.unitsperbeat   event EVENTTYPE_HEADER contains MIDI resolution as units per beat
          ev.version    event EVENTTYPE_HEADER contains MIDI version 0, 1, 2
          ev.trackcount   event EVENTTYPE_HEADER contains number of MIDI tracks
          ev.bpm         event EVENTTYPE_TEMPO contains beats per minute tempo number
          ev.microsecondsperbeat    event EVENTTYPE_TEMPO contains microseconds per beat  tempo number
          ev.nomin       event EVENTTYPE_TACT contains nominator of tact (e.g. 3 of 3/4)
          ev.denom       event EVENTTYPE_TACT contains denominator of tact (e.g. 4 of 3/4)
          ev.texttype    event EVENTTYPE_TEXT contains text type number
                meta_text
                meta_copyright
                meta_trackname
                meta_instrument
                meta_lyric
                meta_marker
                meta_cuepoint
                meta_programname
                meta_devicename
          
          ev.program     event EVENTTYPE_PROGRAM contains program number (1,...)
          ev.programname   event EVENTTYPE_PROGRAM contains GM program name (1,...)
          ev.note        event EVENTTYPE_NOTE contains note number (0-127)
          ev.notename    event EVENTTYPE_NOTE contains note name
          ev.controlnr   event EVENTTYPE_CONTROL contains control number (0-127)
                   ev.ctrl_highbank
                   ev.ctrl_wheel
                   ev.ctrl_breath
                   ev.ctrl_foot
                   ev.ctrl_portamentotime
                   ev.ctrl_data
                   ev.ctrl_volume
                   ev.ctrl_balance
                   ev.ctrl_expression
                   ev.ctrl_effect1
                   ev.ctrl_effect2
                   ev.ctrl_slider1
                   ev.ctrl_slider2
                   ev.ctrl_slider3
                   ev.ctrl_slider4
                   ev.ctrl_lowbank
                   ev.ctrl_lowdata
                   ev.ctrl_hold
                   ev.ctrl_portamento
                   ev.ctrl_sustenuto
                   ev.ctrl_soft
                   ev.ctrl_legato
                   ev.ctrl_hold2
                   ev.ctrl_sound_variation
                   ev.ctrl_resonance
                   ev.ctrl_sound_release_time
                   ev.ctrl_sound_attack_time
                   ev.ctrl_xg_brightness
                   ev.ctrl_xg_portamento
                   ev.ctrl_reverb
                   ev.ctrl_tremolo
                   ev.ctrl_chorus
                   ev.ctrl_xg_effect4
                   ev.ctrl_phaser_level
                   ev.ctrl_datainc
                   ev.ctrl_datadec
                   ev.ctrl_lownrpn
                   ev.ctrl_highnrpn
                   ev.ctrl_lowrpn
                   ev.ctrl_highrpn
                   ev.ctrl_allsoundoff
                   ev.ctrl_allcontroloff
                   ev.ctrl_localkeyboard
                   ev.ctrl_allnotesoff
                   ev.ctrl_omnioff
                   ev.ctrl_omnion
                   ev.ctrl_mono
                   ev.ctrl_poly
          ev.controlvalue  event EVENTTYPE_CONTROL contains control value (0-127)
          ev.text        event EVENTTYPE_TEXT contains text
          ev.key         
          ev.pitchbend        event EVENTTYPE_PITCHBEND contains pitchbend number 0 is no pitchbend 
                  pitch_center = 0
                  pitch_maxdown = -0x2000
                  pitch_maxup = 0x1fff
          
          ev.aftertouch       event EVENTTYPE_AFTERTOUCH contains aftertouch value
          ev.polykey          event EVENTTYPE_POLYAFTERTOUCH contains polyaftertouch key
          ev.polyvalue        event EVENTTYPE_POLYAFTERTOUCH contains polyaftertouch value
          ev.key              event EVENTTYPE_KEY contains key
          ev.metatype         event EVENTTYPE_META contains meta type value
                meta_seqnumber
                meta_prefixchannel
                meta_prefixport
                meta_endtrack
                meta_tempo
                meta_smpte
                meta_meter
                meta_key
          ev.meta            event EVENTTYPE_META contains meta data as hexadecimal string (values 00 - 7F)
          ev.metadatalength  event EVENTTYPE_META contains length of meta data in bytes
          ev.realtimeevent    event EVENTTYPE_REALTIME contains real time event number
                event_songpos
                event_songselect
                event_tunerequest
                event_clock
                event_start
                event_continue
                event_stop
                event_activesense
          ev.realtimeparam    event EVENTTYPE_REALTIME contains real time event parameter value
          ev.sysex       event EVENTTYPE_SYSEX contains sysex data as hexadecimal string (values 00 - 7F or F7)
                sysex_GMReset = "7E 7F 09 01 F7"
                sysex_GMExit = "7E 7F 09 02 F7"
                sysex_GM2Reset = "7E 7F 09 03 F7"
                sysex_GSReset = "41 10 42 12 40 00 7F 00 41 F7"
                sysex_GSExit = "41 10 42 12 40 00 7F 7F 42 F7"
                sysex_XGReset = "43 10 4C 00 00 7E 00 F7"
          ev.sysexdatalength   event EVENTTYPE_SYSEX contains sysex data length in bytes

Hint: constants listed above should be used e.g. if (ev.type == EVENTTYPE_CONTROL && ev.controlnr == ctrl_volume) ev.controlvalue = 127;
Important: many of those event parameters can only be accessed when the current MIDI command has a compatible event type e.g. ev.velocity is only available for notes ev.type == EVENTTYPE_NOTE and else the script aborts with an error. Therefore restrict in the condition the command type e.g. ev.type == EVENTTYPE_NOTE && ev.velocity >= 80

assignment operators
      =    assignment of a value e.g. ev.controlvalue = 127
      +=   increment by value   e.g. if (ev.controlvalue + 10 <= 127) ev.controlvalue += 10;
      +=   appending a string   e.g. ev.text += "\n";
      -=   decrement by value   
      *=   multiplication by value e.g. if (ev.type == EVENTTYPE_TEMPO) ev.bpm *= 2;
      /=   division by value



Functions (more can be found in gnscript package)
random(maxvalue)      a random value between 0 and maxvalue-1 e.g. ev.controlvalue += random(5);
replace(text, pattern, against)         replace all occurrences of pattern inside text by against e.g. text.replace('(c)', 'copyright');
text.index(subtext)   first position of subtext inside text or -1 if not found
text.toupper()        change all characters a-z to A-Z
text.tolower()        change all characters A-Z to a-z
text.mid(pos, len)    get part of text beginning at index pos and maximum length len
text.left(len)        get part of text from beginning with maximum length len
match(text,regex, options)     match text against regular expression
substitute(text, regex, against,options)   replace parts of text matching a regular expression regex by against e.g. text.substitute('hel.*o', 'HELLO', 'gi');
round(value)
song.deleteevent(ev.eventindex())    deletes event ev





Modification examples:
if (ev.type == EVENTTYPE_TEXT) ev.text = ev.text.toupper();
if (ev.type == EVENTTYPE_SYSEX) song.deleteevent(ev.eventindex());
if (ev.type == EVENTTYPE_CONTROL && ev.controlnr == ctrl_volume) ev.controlvalue = max(127, ev.controlvalue + random(10));
if (ev.type == EVENTTYPE_TEXT && ev.texttype == meta_trackname) ev.text = ev.text.replace(" ", "-");