GNMIDI

Table of Contents Keyword Index
gnscript condition expressions syntax
Previous  Top  Next

Few GNMIDI operations use gnscript expressions to match the wanted MIDI events (for experts only).
The boolean expression should return 0 (or false) if the current event is not matching and nonzero (or 1 or true) if the event matches.
1 will match all MIDI events.
true will match all MIDI events.
0 (or false) will match no MIDI events.
The current MIDI event information is available as structure variable with name "ev".
The MIDI song information is available as structure with name "song".
The expression can be simple by comparing operators (==, !=, >=, >, <, <=) or
complex with logic operators (&&, ||) or
function calls (e.g. measureatunit(song,ev.startunit) <= 2) and even
calling own function definitions e.g. return ev.everyfifths(); function everyfifths(&ev) { return ev.eventindex() % 5 == 0;
};

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. ev.type == EVENTTYPE_CONTROL && ev.controlnr == ctrl_volume
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

functions (more can be found in gnscript package)
random(maxvalue)      a random value between 0 and maxvalue-1  
text.length()         number of characters in text  
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  
song.measureatunit(unit)    returns 1 for first measure  
song.lastunit()         returns last used midi unit in song  
song.gettrackcount()    returns number of tracks   
song.getresolution()    returns units per beat  
ev.eventindex()         index of the event inside the song  
ev.ischordevent()       returns true if event contains a known chord  
ev.event2string()      returns a text that contains event information  
 
 


Condition examples:
ev.aftertouch == 0
random(10000)==0
true
ev.type == EVENTTYPE_TEXT && ev.texttype == meta_trackname
measureatunit(song,ev.startunit) in  [2..3]
ev.startms > 0 && ev.startms <= 3000 
return ev.everyfifths(); function everyfifths(&ev) { return ev.eventindex() % 5 == 0; };