GNMIDI

Table of Contents Keyword Index
gnscript midi modification syntax
Previous  Top  Next

gnmidiscript script language is an extension of gnscript with functions, constants, object types to analyse, modify, create MIDI files

This file describes the syntax elements and functions that are added for handling MIDI file access only. The basic script language elements are described in gnscript project.

CONSTANTS

defines following constants

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
version_multichannel = 0
version_singlechannel = 1
version_multitrack = 1
version_multisong = 2
COMBINE_NOTES = true
SPLIT_NOTES = false
drumchannel = 10
middlec = 60
meta_seqnumber
meta_text
meta_copyright
meta_trackname
meta_instrument
meta_lyric
meta_marker
meta_cuepoint
meta_programname
meta_devicename
meta_prefixchannel
meta_prefixport
meta_endtrack
meta_tempo
meta_smpte
meta_meter
meta_key
ctrl_highbank
ctrl_wheel
ctrl_breath
ctrl_foot
ctrl_portamentotime
ctrl_data
ctrl_volume
ctrl_balance
ctrl_expression
ctrl_effect1
ctrl_effect2
ctrl_slider1
ctrl_slider2
ctrl_slider3
ctrl_slider4
ctrl_lowbank
ctrl_lowdata
ctrl_hold
ctrl_portamento
ctrl_sustenuto
ctrl_soft
ctrl_legato
ctrl_hold2
ctrl_sound_variation
ctrl_resonance
ctrl_sound_release_time
ctrl_sound_attack_time
ctrl_xg_brightness
ctrl_xg_portamento
ctrl_reverb
ctrl_tremolo
ctrl_chorus
ctrl_xg_effect4
ctrl_phaser_level
ctrl_datainc
ctrl_datadec
ctrl_lownrpn
ctrl_highnrpn
ctrl_lowrpn
ctrl_highrpn
ctrl_allsoundoff
ctrl_allcontroloff
ctrl_localkeyboard
ctrl_allnotesoff
ctrl_omnioff
ctrl_omnion
ctrl_mono
ctrl_poly
pitch_center = 0
pitch_maxdown = -0x2000
pitch_maxup = 0x1fff
event_songpos
event_songselect
event_tunerequest
event_clock
event_start
event_continue
event_stop
event_activesense
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"
MIDI_COMPRESSION_NONE
MIDI_COMPRESSION_MEDIUM
MIDI_COMPRESSION_FULL
CHORDFORMAT_LYRIC = "LYRIC"
CHORDFORMAT_TEXT = "TEXT"
CHORDFORMAT_MARKER = "MARKER"
CHORDFORMAT_PSR = "PSR"
CHORDFORMAT_WORDBOX = "WORDBOX"
CHORDFORMAT_BIAB = "BIAB"

NEW OBJECT TYPES

MidiSong is a structure that keeps optional file name of a song and loaded song info

the structure contains only the fields (no remove, no insert):
filename a string
events a vector of MidiEvent objects

Hint: modifying tempo or tact inside for or foreach events loop is critical.
it causes that the times of all events are calculated again and resorts the order of events by time.
Use setautoupdatetimes() function to turn off/on this behaviour while working in the loop.

MidiEventList is a vector of MidiEvent objects.

It allows to insert, remove and modify elements.

MidiEvent

The MidiEvent structure object allows to get or modify information from different kind of event types. The MidiEvent object here allows to access every existing field from any of these types (no casting required but if getting a field that does not exist will result in a runtime error)

MidiEvent can have following structure keys that are strings

type (delivers null object for null Midi Event object)
program
programname
note
notename
text
key
polykey
sysex
meta

MidiEvent can have following structure keys that are numbers

track
channel
startunit
endunit
length
startms
endms
duration
hasstart
hasend
iscombined
firstunit
lastunit
firstms
lastms
unitsperbeat
version
trackcount
bpm
microsecondsperbeat
nomin
denom
texttype
pitchbend
aftertouch
polykey
polyvalue
key
metatype
realtimeevent
realtimeparam
velocity
velocityoff
controlnr
controlvalue
sysexdatalength
metadatalength

all fields (exept type) can be modified

hint: when setting startunit, endunit, starms, endms exception may occur if the new value causes end < start . Use setnotetimes or setnoteunits for setting both values at same time.

LIVE VARIABLES

live variables are global variables that are dynamic

midicompression

this live variable (long) gets or sets MIDI compression. Live variable means that when the program changes the value the variable also changes and same in other direction.

it must have the values of constants MIDI_COMPRESSION_NONE,MIDI_COMPRESSION_MEDIUM,MIDI_COMPRESSION_FULL

FUNCTIONS

newsong(version,resolution)
midiload(filename,combineoption)
midisave(&song,filename)
deleteevent(&song,index)
after deleting you should call song.compact() or check before accessing events (isnullevent() or event.type == "" or event.eventindex() == -1)
collectevents(&song,andfieldname,andoperator,andfieldpattern,...)
e.g. find all notes with channel == 10 requires triple parameters like collectevents("channel","==","10","type","=",EVENTTYPE_NOTE)
findfirstevent(&song,andfieldname,andoperator,andfieldpattern,...)
e.g. find first note in channel 10 requires triple parameters like collectevents("channel","==","10","type","=",EVENTTYPE_NOTE)
compact(&song)
eventindex(&event)
event2string(&event)
inserttempo(&song,index,startunit,microsecperbeat)
inserttact(&song,index,startunit,nomin,demon)
inserttext(&song,index,track,startunit,texttype,text)
insertprogram(&song,index,track,channel,startunit,programnumber)
insertcontrol(&song,index,track,channel,startunit,controlnumber,controlvalue)
insertnotestart(&song,index,track,channel,startunit,note,vel)
-- deprecated: better use insertnote(&song,index, notestructure)
insertnoteend(&song,index,track,channel,endunit,note,veloff,...)
-- deprecated: better use insertnote(&song,index, notestructure)
insertnote(&song,index,track,channel,startunit,endunit,note,vel)
-- deprecated: better use insertnote(&song,index, notestructure)
insertnote(&song,index,track,channel,startunit,endunit,note,vel,veloff)
-- deprecated: better use insertnote(&song,index, notestructure)
insertnote(&song,index, notestructure)
notestructure can be { track: tracknr, channel: channelnr, startunit: optionalstartunit, endunit: optionalendunit, note: notename, velocity : optionalvelocityon, velocityoff: optionalvelocityoff)
parsenotename(notename)
convert a note name to a note number 0-127 if note name is valid and known (else -1)
getnotename(notenumber)
convet a note number to note name
insertpitchbend(&song,index,track,channel,startunit,pitchbend)
insertaftertouch(&song,index,track,channel,startunit,aftertouch)
insertpolyaftertouch(&song,index,track,channel,startunit,polykey,polyvalue)
insertkey(&song,index,track,channel,startunit,key)
insertsysex(&song,index,track,startunit,sysex)
insertmeta(&song,index,track,startunit,metatype,meta)
insertrealtime(&song,index,track,startunit,realtimeevent,realtimeparam)
insertendtrack(&song,index,track,startunit)
insertmeasure(&song,barnr,newtactnom, newtactdemom)
insert a new empty measure with given tact e.g. 3/4
insertmeasure(&song,barnr,newtactnom, newtactdemom,barcount)
insert a some empty measures with given tact e.g. 3/4
moveevent(&event,newindex)
copyevent(&event,newindex)
copyevent(&event,&newsong,newindex)
duplicatechannel(&song,channel,newchannel,delayunits)
duplicate all events of a channel to a new channel with some units position difference
duplicatechannel(inputfilename,outputfilename,channel,newchannel,delayunits)
setnotetimes(&event,startms,endms)
setnoteunits(&event,startunit,endunit)
timeat(&song,unit)
unitat(&song,ms)
tempoat(&song,unit)
bpmat(&song,unit)
bpm2microsecperbeat(bpm)
microsecperbeat2bpm(microsecperbeat)
setautoupdatetimes(&song,autoupdatetimes)
getautoupdatetimes(&song)
updateeventtimes(&song)
updatetimetable(&song)
tactat(&song,unit)
tactlength(&song,nom,denom)
measurelength(&song,measurenr)
measureatunit(&song,unit)
posatunit(&song,unit)
unitatmeasure(&song,measurenr)
unitatmeasure(&song,measurenr,beatnr)
unitatmeasure(&song,measurenr,beatnr,tick)
midiposition(&song,positiontext)
supports time and unit and bar position e.g. 0:30 is 30 seconds after beginning of song,
error if invalid syntax,
result is midi unit for given song
barunits(&song)
lastunit(&song)
gettrackcount(&song)
getfirsttrackforchannel(&song, channel)
find a track number that already uses channel
getresolution(&song)
getversion(&song)
loadbestchords(&song)
loadchords(&song)
loadchords(&song,format)
removechords(&song)
removechords(&song,format)
ischordevent(event,onlysafetextchords)
identify chord event, for text onlysafetextchords decides if probably lyrics are probably not chords e.g. Am
isnullevent(event)
a song might contain null events where events have already been deleted
removefade(&song)
containsfadein(&song)
containsfadein(&song,&fadeinfo)
containsfadeout(&song)
containsfadeout(&song,&fadeinfo)
miditool(commandline)
e.g. midicat, midi1to0, miditrim, midi2txt, txt2midi, ...
initialisecontrol(&song,channel,controlnr)
inserts a control of given controlnr with default control value if there is no such control before first note in channel
initialiseprogram(&song,channel)
inserts a program change with default program value (0, grand piano) if there is no program change before first note in channel
initialisechannelsettings(&song, channel)
inserts channel setting commands with default values if such commands are missing before first note in channel

guesskey(midifilename)
returns number of # signs or b signs (signs >= 0 means # signs < 0 means b)
songkeyname(signs,minor)
e.g. signs == 0 returns song key "C"
keysigns(key)
returns number of # signs or b signs (information stored in song) (signs >= 0 means # signs < 0 means b)
keysigns(key,&minor)
returns signs and sets boolean variable minor (signs >= 0 means # signs < 0 means b)
couldbechordname(text)
e.g. Am, C, G7, Bb, D#,...
issafetextchordname(text)
e.g. "Am " is no safe chord
istextchord(text)
e.g. [Cm7]
ischordevent(event)
quantise(&song,posbase,lenbase)
e.g. quantise to base 1/16, all channels
quantise(&song,posbase,lenbase,channels)
e.g. quantise to base 1/16, channel list as string e.g. 1-9, 11-16
quantisebase(&song,notelen)
e.g. notelen 1/16
unescapetext(escapedtext)
when using commandline with macro %escapetext(text) then unescapetext(escapedtext) can be used for easier getting back original text
deletepauses(&song,fromunit,units)
deletepauses(&song,fromunit,units,deleteemptynotes)
deletepauses(&song,vectorunitranges)
unitrange is structure fromunit, units
deletepauses(&song,vectorunitranges,deleteemptynotes)
comparemidi(&midisong1, &midisong2)
comparemididetail(&midisong1, &midisong2)
comparemididetail(&midisong1, &midisong2, filename1)
comparemididetail(&midisong1, &midisong2, filename1, filename2)
equalevents(&event1, &event2)
equalevents(&event1, &event2,ignoretrackno)
equalevents(&event1, &event2,ignoretrackno,ignoretiming)
getmetatypename(metatypenumber)
returns the name of the metatype number e.g. 3 => "Trackname"
getmetatypenumber(metatypename)
returns the number of the meta type name e.g. "trackname" => 3
ischannelpolyphone(&song, channel, minnotesoverlapping)
finds a note that plays at same time with other notes
ischannelpolyphone(&song, channel)
finds a note that plays at same time with an other note (minnotesoverlapping=2)
__GNMIDISCRIPTVERSION__()
return version string e.g. 1.0
__USEGNMIDISCRIPTVERSION__(version)
error if version e.g. 1.0 is older than CURRENTGNMIDISCRIPTVERSION
setStatusbarText(shortmsg)
only usable when application has statusbar control
dumpevents(&song)
get all song data as text string
dumpevents(&song,firstindex,lastindex)
get some events of song between index firstindex and lastindex (inclusive) as text string
replaceprogrambank(&song, channels, oldprog, oldbankmsb, oldbanklsb, newprog, newbankmsb, newbanklsb)
find old program/bank in given channels of a song and replace it with a new program/bank
getprogrambankranges(&song,channel,track)
find areas with sound addresses in song at channel and track
getprogrambankranges(&song,channel)
find areas with sound addresses in song at channel
setprogrambank(&song, channel, track, startunit, endunit, prog, bankmsb, banklsb)
set a program/bank address in channel and track from position startunit till endunit
findmatchingsoundaddress(&song, channel, addresspattern)
find soundaddress in a channel of a song and return a vector of event indices (indexlist) for the program and bank events used,
addresspattern is a structure { program: 3, msbbank : 0, lsbbank: -1} where bank numbers -1 are matching any bank address
replacesoundaddress(&song, channel, addressreplace, &indexlist)
replace the found sound addresses in indexlist by a new sound address