Skip to main content

User's manual

Connect MIDI-keyboards

Midi-keyboards must have MIDI connectivity. Please check information about MIDI on Internet ( e.g.  this page ). 

Plug the keyboard on your computer. Start Expresseur. 

The Midi-In keyboards must be enabled with the menu "Setting/Midi...".

To unvalidate definitively a Midi-in, edit the file expresseur.lua in the software directory, and add the Midi-in name in the list of non-valid Midi-in devices.


Connect MIDI-Audio-Expander devices

Midi-audio-expander devices translates MIDI to audio sounds. 

Advantage : no latency, no CPU flooding, no noise, no complex computer tuning. It's perfect for users who do not want to manage computer tuning, or with "small-CPU" computer. It suppresses all risks about latency (delay between the press of a touch and the sound-rendering). 

Example of cheap and efficient Midi-audio-expander : the X3MB from Serdashop

Plug the Midi-audio-expander on your computer, using MIDI cable or USB. The Midi-audio-expander will be automatically recognized by Expresseur on start-up.

In the menu mixer of the Expresseur, link tracks to the Midi-audio-expander. The mixer will propose the list of instruments available for this Midi-audio-expander.

The list of instruments available in the Midi-audio-expander is in the directory "ExpresseurV3/instruments". The syntax of this file is described later.


Connect a Virtual Instrument (VI)

A Virtual Instrument ( VI  ) is a file to render an instrument sound from MIDI-out events.

Expresseur can load two kind of VI :

  • SF2 soundfont ( .sf2 extension )
  • VSTi software ( .dll extension, limited to 64bits, without Graphic-User-Interface rendering ) 

Risk  : latency tuning is critical (delay between the press of a touch and the sound-rendering). As CPU and card-sound are not dedicated to this usage, latency must be decreased, keeping quality of sound. Bad tuning can generate random noise, latency, CPU flooding, ... It often needs "high-CPU" capacity. A MIDI-audio-expander device is easier to use (cf. previous chapter).

Example of nice VI : pianoteq for fantastic piano rendering (and harpsichord, ... )

The VI files, and its list of instruments ( .txt extension ) are in the directory "ExpresseurV3/instruments".

In the menu mixer of the Expresseur, link tracks to the VI you want.

The list of instruments available in the VI is in the directory "ExpresseurV3/instruments". The syntax of this file is described later.

The VI is plugged in the default audio output, selected in the menu Setting/Audio.

The VI can be plugged in another audio-output, adding "@x" at the end of the file name. For example : "guitar@SD-50.sf2" plugs this sound-font on audio-output SD-50. The list of audio-outputs are visible in the menu Setting/Audio.

A lot of VI are available on Internet. The Expresseur package contains these SF2 sound-fonts :


Connect Midi-Electronic-Piano

An electronic MIDI piano contains three components in an "all-in-one" box :

  • a Midi-keyboard
  • a Midi-audio-expander to convert Midi to audio
  • an audio-amplifier with loud-speaker

Advantage : no latency, no CPU flooding, no noise, no complex computer tuning. It's perfect for users who do not want to manage computer tuning, or with "small-CPU" computer. It suppresses all risks about latency (delay between the press of a touch and the sound-rendering). 

Connecting a Midi piano to Expresseur ( via Midi interface, or USB ), will connect the Midi-keyboard as input, and the Midi-audio-expander as output. Refer to the previous sections for more information.

Expresseur sends a "local-off" command to the piano. This command disconnects the keyboard from the internal Midi-audio-expander. Be sure that your piano supports local-off !


Trouble-shooting

  • Score cursor is fixed : load the setting/midi-preset/full-keyboard. Test CTRL-O. Test any MIDI-key.
  • No sound : open the mixer. Select the right output interface for each voice.
  • latency :
    • avoid software expander like SF2, VST (difficult to tune). Prefer a hardware expander (eg Buran )
    • speakers : forget bluetooth. Even analog line-in can have latency (Boser Revolver Oglo-Loops, .. ) 
    • silent notes : on monophonic instruments, uncheck "extended channel" in the mixer

Modify the instruments


Expresseur has his own syntax to describe quickly a MIDI-instrument : its a free-text name, followed by MIDI-commands between parentheses.

Example :

  • piano on MIDI program 0 :  piano(P0)
  • a guitar on program 5, on right-pan ( control 10 ), with Midi-volume 80 ( control 7 ) : guitar_right(P5,C10/1,C7/80)
  • a program 5 on a bank MSB 1 : mysound(P1/5)
  • a program 5 on bank MSB 1 ,and bank LSB 4 : myothersound(P1/4/5)

The syntax does not accept white-spaces.

This syntax is used in :

  • The list of instruments available in the directory "ExpresseurV3/ressources". When Expresseur detects a new Virtual-Instrument (SF2, VSTi) in this directory, Expresseur extracts the list of instruments form the file (SF2 MIDI-programs, VSTi MIDI-programs or VSTi-Programs). The list is written in a text file, in the same directory, one instrument per line, with txt extension, and same name than the VI. This list can be modified (without useless instruments, or with your own instruments, adding controls, ..)
  • When a USB-Midi-Audio-Expander is connected, it is possible to create a list of instruments available for this device, making a text file with the same name than the device, extension txt, in the directory "ExpresseurV3/ressources", with one instrument per line.
  • The default list is the General-Midi ( "gm.txt" ), available in the directory "ExpresseurV3/ressources". This list is used for non USB MIDI-audio-expander. Add your own settings to adapt to your device.
  • The tuning of instrument "on the fly" within a score, with the ornament "instrument" ( cf section above for more detail ).

The SF2-expander embedded in Expresseur understands this MIDI-messages :

  • note-on / note-off
  • pitch-bend
  • program
  • channel-pressure
  • Control
    • 0 : bank selector
    • 1 : modulation
    • 5 : portamento time
    • 7 : volume
    • 10 : pan
    • 11 : expression
    • 64 : sustain
    • 65 : portamento
    • 71 : resonance level (0-127, 0=-64, 64=normal, 127=+63)
    • 72 : release time (0-127, 0=-64, 64=normal, 127=+63)
    • 73 : attack time (0-127, 0=-64, 64=normal, 127=+63)
    • 74  : cutoff level (0-127, 0=-64, 64=normal, 127=+63)
    • 84 : Set the portamento start key. the next note starts at this key (MIDI controller 84)
    • 91 : reverberation
    • 93 : chorus
    • 120 : sound-off
    • 121 : reset controllers
    • 123 : note-off
    • 126 : Set poly/mono mode
    • 100 : rpn msb
    • 101 : rpn lsb
    • 6 : rpn-msb = 0 : rpn-lsb :
      • 0 : Set pitch wheel range in semitones
      • 1 : finetune in cents (0-16383, 0=-100, 8192=normal, 16383=+100)
      • 2 : coarse tune in semitones (0-127, 0=-64, 64=normal, 127=+63)

The instruments are played on the MIDI channel selected in the mixer. If option "extended channel" is selected, the intruments use more than one MIDI-channel to play the notes, allowing overlap of a same pitch on the same MIDI channel. Uncheck "extended channel" if the MIDI expanders are monophonic on all channels for a same pitch (organ, ... )

Configure the MIDI triggers

Default MIDI settings are available in menu setting/MIDI-presets.

The list of triggers can be exported(imported) in(from) a file, using the menu "setting/export(import) settings". It is possible to select the settings which are exported (mixer, triggers, .. ), and to set a description of theses settings in a multi-line text. When placed in Mydocuments/ExpresseurV3/ressources directory, this setting appers in the list of menu setting/MIDI-presets

The menu "setting/MIDI-settings" open a dialog box to edit all the triggers.

The Midi-event are the best option to trigger an action. Any device ( pedal, keyboard, tablet-midi, ad-hoc device ) can be used for this purpose.

ALT+PC-key can be linked to the MIDI-shortcut.

The triggers can be sorted. When a trigger is detected in the list ( top to bottom ) , the detection process can be stopped or can be continued ( to have more than one action for one event ).

When editing a trigger, all the valid midi-in devices are opened (cf. LUA scrip expresseur.lua function MidiInIsValid). Any key-in on these devices are displayed in the window. Double-click on a MIDI-event loads the tuning in the shortcut. The MIDI-events which can be used are :

  • noteon & off : both events trigger the shortcut.
  • noteon : only noteon triggers the event
  • control : any value of the control trigger the event
  • program

A parameter can be passed to the LUA function, associated to the trigger.

The list of actions which can be attached to the triggers is described in the LUA-script expresseur.lua ( menu setting/LUA files), in the directory of the software, in the table "actions" :

  • name  : displayed in the list of actions ( and menu if there is a shortcut)
  • help : displayed in the menu (and toolbar , if there is an icone)
  • icone : to display he action in the toolbar. The icone, format bmp 16x16, is stored in the directory "lua"
  • shortcut ( CTRL+HOME,CTRL+A, .. ) : to add the actions in the menu "actions" of the GUI
  • callFunction : the LUA function to call when the shortcut is trigerred.  ( "CallScore" and "CallChord" are called in priority if exists, according to the mode used in the GUI ) . These LUA functions have these parameters :
    • time : float
    • uid : unique id of the shortcut ( composed of the shortcut number, the device, the channel, and the pitch )
    • channel MIDI[1..16]
    • msg-type [1..16]
    • pitch MIDI [1..127] ; pitch of the note , or control-number, or program number
    • velocity [0..127] :  velocity of the note-on ( 0==note-off ) , or control-value
    • parameter  : as set in the menu edit/shortcut
    • indexKey[1..n] : index of the picth within the range of the selector. 1 means the minimum of the range
    • medianeKey[-n/2..0..n/2] : index of the pitch within the the range of the selector. 0 means the middle of the range
    • whiteIndex : idem indexKey, but taking in account only "white keys"
    • whiteMediane : idem medianeKey, but taking in account only "white keys"
    • black[0,1] : 0 means white key. 1 means black key.

List of default actions available in expresseur.lua defined in table "actions":

  • global / all note off : send all note off to all audio expanders. Parameter : "noteoff" (midi noteoff), "soundoff" (audio off) , "controler" (reset controller), all (midi, audio,controler)
  • global / playnote : "Midi-Thru", replay the Midi-In note (or Control) on a track. Parameter : <track number>
  • global / main volume : set the main volume of the midi mixer. Parameter : <volume> (if <volume> not specified, use the velocity of the trigger) 
  • global / track volume : set the track volume of the midi mixer. Parameter : <volume> <track nr> (if <volume> not specified, use the velocity of the trigger)
  • global / lua value  : set the lua value. Parameter : <lua name> <value> (if <value> not specified, use the velocity of the trigger)
  • global / next file : go the next file of the list. Parameter <increment> ( if <increment> not specified : move to next file )
  • move / previous move : go to the previous move
  • move / first part : go to the beginning. Parameter "smooth" in improvisation mode : wiil move at the end of current part.
  • movre / previous part : go to the previous part. Parameter "smooth" in improvisation mode :will move at the end of current part.
  • move / next part : go to the next part. Parameter "smooth" in improvisation mode : will move at the end of current part.
  • move / previous measure : go to the previous measure. 
  • move / next measure : go to the next measure
  • move / previous chord : go to the previous chord
  • move / next chord : go to the next chord
  • move / repeat part : repat the part.  Parameter "smooth" in improvisation mode : will move at the end of current part
  • score / play : play the score chord. Parameter "legato" to play always legato, discarding note-off events. Parameter "arpeggiate=x" to arpegiate automatically with x milliseconds between notes (in addition to lua value score_delay )
  • chord / change chord : go to next chord. Parameter : "off" to change on note-off (for anticipation). 
  • chord / play scale : play the scale. Parameter : "chord", "penta"
  • chord / play chord : play the chord. Parameter : "up" "down" to select the way to arpegiatte
  • chord / play background : play the background
  • chord / play bass : play the bass . Parameter : "walking" to play a a walking bass
  • chord / pedal : set the pedal of the track. Parameter : <track name> ; "off", "legato" (all withe notes are legato), "pedal" (pedal during chord) 
  • chord / octave : set the octave of the track. Parameter <track name> ; <octave_shift>
  • chord / shift path : set the shift to select the next chord. Parameter <track name> ; <octave_shift

 

Configure the PC-key shortcuts

In addition to the "ALT+PCKey"  described in the previous chapter , One-key shortcuts are pre-defined, as visible in the pictures above. 

You must use menu "setting/One-key config" to setup the keyboard disposal of the 4 lines of 10 keys (with green border on the picture above). For example in US keyboard :  1234567890 qwertyuiop asdfghjkl; zxcvbnm,./






One-key shortcuts for score-play 


  • Forte Meso-forte Piano Tacet : 8 tracks mixer. Values can be set in menu "Edit/Expression". A zero-value for Tacet set the track as "not played" (it re-calculates the score).
  • Goto : open the dialog-box to go to a measure nr, or a mark (with optinal repetition).
  • Off :  sound off the output
  • Ass , Ass : select assisted mode to play Expresseur score, or non-assisted mode to play real notes from the MIDI keyboard
  • +# , -b : transpose up-down the output
  • Play/view : open the dialog-box to select which track to play and/or view
  • Play legato : play the score always legato. No sensitivity, except the one tuned in the ornementations (accents, nuances, ..)
  • Arrows : move cursor within the score, note by note  or measure by measure
  • Page-down (or Tab ), Page-up ( or Back-Space ) : move to next/previous mark
  • Home ( or Escape ) : goto beginning of score
  • Return : return to the last move (useful to repeat and repeat a section )

One-key shortcuts for improvisation : 


    • I .. VII : select a degree with its standard harmony. eg in C : C, Dm, Em, F, G, Am, Bm.b5
    • add7 : select a degree with its standard harmony plus a 7enth
    • # , b : up or down semi-tone the chord
    • M , m : Major or minor the chord
    • #5 , b5 : up or down the fith
    • M7, 7 : Major-7enth, or 7enth
    • chord , penta : select the scale to improvise 
    • leg , leg : automatic or manual legato of notes in the scale
    • Off :  sound off the output
    • Ass , Ass : select assisted mode to play Expresseur impro, or non-assisted mode to play real notes from the MIDI keyboar
    • +# , -b : transpose up-down the output
    • next chord & play : go to the next chord, and play the chord
    • move smooth : to change the section smoothly (on next chord)

Additional parameters between the GUI and LUA

In the LUA script, there are plenty of options to drive the logic. Please contact frevolle@gmail.com to discover, understand, complete these features. 

In expresseur.lua (name can be changed in the GUI):

  • the Mixer can be changed/displayed in the menu "Edit/mixer", and the LUA script. These values canbe controlled by a MIDI-Ctrl event, adding a trigger in the "setting/MIDI-settings", with the action "mixer", and the parameter equal to the number of the track.
  • the LUA-table "values[valuename]" can be changed/displayed in the menu "Edit/LUA values", and the LUA script. These values canbe controlled by a MIDI-Ctrl event, adding a trigger in the "setting/MIDI-settings", with the action "LUA values", and the parameter equal to the name of this LUA-value.
  • the LUA-table "tracks[trackname]" is built by the LUA, and completed by  GUI ( according to current score ). The GUI completes the column of the LUA table
  • info.status : text to be dispayed in the statusbar#2 of GUI ( start text with 1 for statubar#1 )
  • info.action : action in the GUI
    • !text : messagebox in the GUI
    • @position : goto a position in the score. if position is empty, open the dialogbox
    • =view/play : view/play tracks in a score. If empty, open the dialogbox
    • + (-) : next (previous) file in the list
    • 0 (#) : first (last) file in the list
  • function onStart(parameter) : started when the script ends its loading. Default parameters (settings /LUA file) :
    • --preopen_midiout : preopen all midiouts to avoid flooding later
    • -u user-lua : to open a LUA script file in ressource direcory, to manage any MIDI-catching, ...
  • function onStop() : started before to stop the script.
  • table midiinOpen : to open specific midi-in devices
  • table actions  is used to build the toolbar in the Expresseur GUI (for those who have icons), and to propose actions available in the triggers of "setting/MIDI-settings"
  • midiInIsValid  (MidiOutIsValid) : to make a midi-In (out) valid or not. Must be completed to restrict the Midi-In interfaces opened by default. Use patterns in this lists in luauser.lua :
    • valid_midiout
    • invalid_midiout
    • valid_midiin
    • invalid_midinin

 This expresseur.lua loads and used three  lua scripts :

  • luascore.lua : to receive the compiled score from the GUI, and to interpret instrumentist action from Midi-In triggers, set in menu "setting/Midi-settings"
  • luachord.lua : to receive the text chord-grid from the GUI, and to interpret instrumentist action from Midi-In triggers, set in menu "setting/Midi-settings". This script uses texttochord.lua to interpret a chord (eg "G7/D", ... ), and to build the associated scales (chord, pentatonic, bass...).

Parameters to tune a MusicXML score

To start with a new score, open the MusicXML file. Information about the score ( ornaments, structure, ...)  is pushed in a text file, the "parameters-file", visible in the left part of the screen. 

The parameters-file has the same name as the MusicXml file, but with a "txt" extension.

It is possible to have different parameters-files, which use one musicXML file, to be able to have different interpretations.


For regular use, reopen the text parameters-file ( not the musicXML file ). It will load the attached musicXML file.

If the structure of the musicXML file has too many changes ( parts, .. ), re-open the musicXML file itself as the first time. 

 

To make a musicXML easier to play with Expresseur, it can be useful to first simplify the original score before to exprt it in musicXML format. All ornaments end sequences can be added later in the text parameter-file :

  • Simplify superposition of complex rythm.
  • Suppress "silent noteoff" : a note which starts in a chord and ends "alone". Align end of such note with the start of another note.
  • Suppress non "rythm-tie" : a "rythm-tie" links two same notes to change global duration.
  • Suppress "decorations" which can complexify the Expresseur-compilation : staccato, legato, pedal, nuances, crescendo, trill, .... These decorations can be added later in the Expresseur parameter-file, section  Ornaments
  • Replace complex coda/repat signs with simple double-bar. The sequence can be added later in the Expresseur parameter-file, section Play-Marks.

The parameter-file contains these sections :

  • "MUSICXML : file name" : the musicXML score to load
  • "TITLE : title of the score" : set the title of the score
  • "SET MARKS": to plug milestones in the score. 
    • one line per mark
    • the measure number, ":", the name of the mark. eg "18:Coda" means a label Coda on measure 18
  • "PLAY MARKS" : to reorganize the score, using the marks.
    • one line per mark. The "mark" must be defined in the previous section "Marks"
  • "PARTS" : to describe the parts 
    • mandatory, constant  "part_name:" as described in the MusicXML file.
    • mandatory "visible" or "not visible" : to set this track as visible or not, in the Expresseur score.
    •  mandatory "/played" or "/not played" : to set this track as played or not, in the Expresseur score.
    • optional ",alias=long_name/short_name" : to change the name of the track in the Expresseur score. The long name is displayed on first staff. Short name is displayed on next staves. The long name is used in the mixer : this is a convenient way to reuse settings ( instruments, MIID-device in the mixer )
  • "ORNAMENTS": to add ornaments ( mordents, dynamics, instruments, .. )
    • One line per ornament
    • position ":" ornament. eg : "2.1:mordent" means a mordant on second measure, first beat.
    • Syntax of the position :
      • optional  "!"  : at the beginning, it means an absolute measure-nr. : the measure_nr displayed on the Expresseur score, taking care of the repetitions described in "played marks" section.
      • mandatory  "measure_nr.beat_nr" : measure_nr and beat_nr, starting at 1. eg : "3.2" means third measure, second beat. The measure number is the original measure_nr, as defined in the original MusicXML score, without the compilation of repetitions defined in the section "play marks". To use the measure_nr visible in the Expresseur score , use prefix "!".
      • optional ".quarter_division" : number of quarter_divisions in the beat.  The quarter division is always defined as an ornament. eg : if quarter_division=2 ( a half-quarter ), "3.2.2" means third measure, second beat, plus 2 half-quarters.
      • optional ".chord_order" : to reach one note in a chord ( starting on one, the lowest pitch of the staff(s) )
      • optional "*repetition" : restrict the ornament on the repetition, according to the section "played marks". By default, the ornament is applied on all repetitions. eg : "3.2*2" means third measure, second beat, second time only. Note : not compliant with prefix "!" for absolute measure nr.
      • optional "<" : puts the ornament before the position. eg "3.2<:mordent" puts the mordent grace notes before the second beat. By default the ornament is placed on the beat.
      • option "@track_name" : restrict the ornament to a specific track (as listed in section "parts" ). By default, the ornament is applied to all tracks. It is possible to use only the first part of the track name. eg "@P1" is enough to tag the track "P1_myslongpianoname". To restrict to a staff in a track add ".#staff" (eg 1st staff os a piano track :@P1.1 )
    • Syntax of the ornament :
      • mandatory "ornament_name"
      • optional "=value"
    • List of ornament_names :
      • divisions_per_quarter=number : mandatory value as integer. Mandatory in the musicXml file structure. It is used to set a precise position of an ornament in a beat.
      • random_delay=milliseconds : make rando delay on the notes
      • dynamic=1..127 : dynamic of the velocity input. 127 = full dynamic. 1 : no dynamic
      • pedal_bar=1..127 : automatic pedal on each bar ( midi-control 64 )
      • pedal=0..127 : activate the pedal ( or zero to stop the pedal )
      • lua=command parameters : activate lua function in the sript luascore.lua. The Command is applied by default to all tracks, but can be restricted to one track usint @Px in the position. Commands set by default :
        • trackvolume volume : set track volume in the mixer
        • mainvolume volume : set main volume in the mixer
        • chord chordname : set a chord to use in the improvisation mode. eg "lua=chord G7"
        • instrument setting: to set an instrument, using the Expresseur syntax. eg "lua=instrument pianoleft(P0,C10/1)"
        • note pitch velocity : snd a noteOn (or noteOff if velocity == 0 )
        • control number value : send a control-change
        • program number [MSB LSB] : send a program [with optional MSB LSB]
        • sysex xx yy zz ... : send the sysex in HEX format
        • tune frequency : to tune the midi-out. eg "lua=tune 415" (if understood by the MIDI-expander ...)
        • bendrange 1..12 : to set the bendrange in half-tone. eg "lua=bendrange 2"
        • gm 0..2 : set GM mode on MIDI expander. eg "lua=gm 2" (if understood by the MIDI-expander ...)
        • scale equal|arabian|just pitch : set the scale. eg. "lua=scale just G" (if understood by the MIDI-expander ...)
      • text=value : add a comment in the Expresseur score
      • pianissimo: set the nuance pp (dynamic of nuane can be adjusted in the "Expression" menu)
      • piano : set the nuance p
      • mesopiano : set the nuance mp
      • mesoforte : set the nuance mf
      • forte : set the nuance f
      • fortissimo : set the nuance ff
      • crescendo|diminuendo : apply a crescendo|diminuendo between two nuances (eg piano=>forte)
      • tenuto : force the legato with next note
      • staccato : reduce the duration of the note. by default half of the duration. An optional value can set 1/3 or 2/3 reduction. eg. "staccato=1/3"
      • accent=-50..50 : apply an accent on the note. Can be negative or positive. eg "accent=20"
      • grace : add a grace note. By default diatonic upper. options :
        • =inverted : diatonic lower. eg "grace=inverted"
        • =pitches : list of pitches to add. eg "grace=C4/E4,G4" adds chord C4/E4 and G4
      • mordent : add a mordent. Option "=inverted". eg "mordent=inverted"
      • turn : add a turn. Option "=inverted".
      • trill : add four trills. Option "=nb_trills". Note : the trill is applied as grace notes. For complex trill, please expand it in the musicxml score, as normal notes ( too complex and not standard definitions ). eg "trill=8"
      • btrill : baroque trill, same as trill, but starting on the upper diatonic pitch.
      • arpeggiate : arpeggiate a chord. by default from lower to upper. Option "value=down". eg "arpeggiate=down"
      • transpose=-24..24 : transpose in half-tone. eg "transpose=-12" transpose one octave lower
      • delay=milliseconds : delay the note. eg "delay=500" delays the note half a second 
      • before : set the note before the others.
      • after : set the note after the others

List of ornaments recognized from the musicXML file :

  • staccato
  • tenuto
  • accent
  • grace
  • nuances
  • mordent
  • trill
  • arpegiatte
  • Rehearsal marks
  • lyrics
  • silent notes ( cross-head )



 

Example of Marks in parameter_file :


SET MARKS :
1:Anachrouse
2:A
4:A1
5:B

PLAY MARKS :
Anachrouse
A
A1
A
B

Improvisation with chords

Syntax for static list of chords ( like a standard song )


Load a text file, which contains a list of chords.

To follow the chords on a score, load a PNG image file containing the score,  with the same name than the text file.

Free text line can be added between the chords, with a dash at the beginning of the line, to avoid compilation of such free-text.

Recognized chords and keywords are in blue.

"Sections" can be declared. A section has these parameters :

  1. mandatory name : reused in the part
  2. optional tone : useful for improvisation in pentatonic scales.

The "sections" are used in "parts"  to reorganize quickly the score. A part has two parameters :

  1. name : alphanumeric characters 
  2. optional loop : it loops inifnitely on this chain.

Example to play in tone C, looping on parts AAB, with a coda which can be smoothly trigerred ( by a key , .. )

section(A,C)
   C      G
-- free text

section(B)
C F G
section(coda)
C G C
part(infinite,loop)
A  A B
part(finish)
coda


Syntax for improvised chords

Rather than using a fixed list of chords, you can describe paths between chords, allowing the musician to improvise the chords during the performance.


The paths are described with a list of nodes

The syntax of a node is  : my_label = chord > next_label_1 , next_label_2 , next_label_3 ...


  • my_label : it is a free text name for the current node 
  • chord : it is the chord to use for the improvisation on this current node (cf. syntax of chords hereafter )
  • next_label_... : is is the list of next label-nodes available from this current node. The selection is done by a MIDI-trigger which calls "chord/shift_label" method : first key of the range selects first label, second key selects the second label, ... 


It is possible to link each node on a graphic bitmap aside the technical list of nodes. It allows to follow the labels and the paths with a smart graphical representation (instead of the technical list of nodes)


Syntax of chords

  • Three Notations of pitches are accepted.  eg G == Sol == V ( on tone C )
    • Latin : do re mi fa sol la si do
    • US :  C D E F G A B 
    • numeric :  I II III IV V VI VII
  •   Modifications accepted are listed here after. The exact definitions is in script "texttochord.lua".
    Eg : G.7, G.-, G.sus4, F#.dim, ..
    A point between modifcators is highly recommended to make the syntax more clear : eg Ab.b5 , Fm.M7
    • sus2
    • sus  == sus4 
    • m == -
    • 7 == m7
    • M7 == maj7
    • b5
    • #5
    • 5
    • 64
    • 46
    • 6
    • 9
    • #9
    • b9
    • 11
    • #11
    • b11
    • 13
    • #13
    • b13
    • ad+9
    • ad+#9
    • ad+b9
    • ad+11
    • ad+#11
    • ad+b11
    • ad+13
    • ad+#13
    • ad+b13
    • o == mb56
    • 0 (zero ) == mb57
    • /bass  eg C/G
    • (x) : without this degree x in the scale
    • #x : scale modifier
    • bx 
    • "[scale/root]". "/root" is optional ( by default the tone ). Scale can be :
      • ionien == modei
      • dorien == modeii
      • phrygien == modeiii
      • lydien == modeiv
      • mixolydien == modev
      • eolien == modevi
      • locrien == modevii
      • minor melodic == modemi == mineur melodique
      • dorien b9 == modemii
      • lydien augmented == modemiii == lydien augmente
      • lydien b7 == modemiv ==  bartok == vaschaspati
      • mixolydien b13  == modemv
      • locrien #9 == modemvi == eolien b5
      • altered == modemvii == altere == super locrien
      • minor harmonic = modehi == mineur harmonique
      • locrien natural == modehii == locrien naturel
      • ionien augmented == modehiii = ionien augmente
      • dorien #11 == modehiv
      • phrygien #3 == modehv
      • lydien #9 = modehvi
      • diminished diatonic == modehvii == diminue diatonique
      • balkan
      • andalou
      • tzigane
      • oriental
      • diminished == diminue == tondemiton == tonehaltone == bertha
      • halftonetone == demitonton
      • tone == ton
    •  =tone : set the tone . eg "G=C" , set the tone to C
    • NC : no chord
    • % : repeat chord
    • @pitch : center the scale around this pitch. eg "G.7@G5" : chord G7, with the center on pitch G5
    • prefix "!" : chord does not influence the mode. But mode can influence the 3rd and 5h chord if not specified
    • prefix ":" chord influences the mode ( by default )
    • mode prefix "_" : mode for this chord and the next ones ( by default )
    • mode prefix "." : mode for this chord only

 The LUA script "texttochord.lua" precalculates these scales. Each pitch ( except the bass ) is decorated with the next pitches of the chord. In addition, the list of alterations ( the "black keys" ) are calculated. These scales are triggered i the menu "setting/MIDI-settings"

  • bass : a walking bass , taking in account the next chord. First pitch is the bass itself ( or the 5th if chord is repeated ).
  • chord : the pitches of the chord. 
  • pentatonic : the pitches of the pentatonic scale. 
  • diatonic : the pitches of the scale itself. 

LUA scripts in Expresseur 

Expresseur uses LUA to script the music logic. LUA is simple but powerfull script language. It has a very efficient pre-compiled engine.

The LUA gives the possibility to add-change easily the music logic.


Example:

  • Adapt the behavior to specific MIDI instruments
  • Use other sound generator ( e.g. play sound wav files )
  •  Extend to other modules ( e.g. MIDI to vibrations, MIDI to screen-animation, .. )


The Graphic User Interface ( GUI ) uses by default these LUA scripts :

  • expresseur.lua : contains the midi-in callbacks functions, and the end-user logic. This filename can be set in the GUI
  • These LUA modules are automatically loaded by the GUI, as global module
    • luachord.lua : contains the functions to interpret a text file with chords, which uses
      • texttochord.lua : contains the function which translate a string in a structure ( chord/scale )
    • luascore.lua : contains the functions to interpret a score structure, pushed by the GUI
    • luabass.lua : to drive midi-outputs


To develop new behavior with LUA, it is possible to edit the LUA scripts in any text editor. But it is recommended to use IDE to test before to implement ( e.g. zerobrane )

The global API-LUA Expresseur package can be used without the GUI. The expresscmd.exe is delivered as an example, to build a command-line tool.


LUA script with expressmd

"expresscmd" is a tinny command line tool,  already available in the package. You have just to script your music logic, using LUA language.


This tinny "expresscmd"  does this :

  • load your LUA script ( by default "expresscmd.lua" )
  • include the following library :
    • basslua : to capture midi-event, and trigger your LUA script on midi-events
    • luabass : to generate midi-out ( on SF2, VSTi, Midi-devices, wav files )
    • luachord : to interprete a text score ( like in the Graphic User Interface )
    • luascore : to interpret  a pre-compiled musicxml score
  • Wait for optional commands on the standard input ( an LUA-function in your script with optional parameters )


Recommendation :

  • Copy the whole expresseur package in "my_project" directory ( eg in your documents repository )
  • In "my_project", copy "lua/expresscmd.lua" in "lua/myscript.lua"
  • Script your music-logic in "lua/myscript.lua"
  • In a terminal, change working-directory to "my_project" directory
  • run "expresscmd myscript.lua"
  • For intensive usage, you can save time using LUA-IDE ( eg zerobrane ) 


LUA API for developers

Structure of the LUA script

The LUA script loaded by basslua ( using the API, expresscmd, or the GUI ) must have :

  • a function onStart(), with optional parameters. It is called after the initialisation of the script
  • a function onStop() : before to stop this script
  • a table midiinOpen={} to specify midi-in devices to open ( list of midi-in device number )
  • optional functions, with optional parameters, to be called from expresscmd command line
  • optional functions to catch events form MIDI-inputs :
    • onMidi(device,t,type,channel,data1,data2) : return an optional MIDI message for the next functions
    • onNoteOff(device,t,channel,pitch,velocity)
    • onNoteOn(device,t,channel,pitch,velocity)
    • onControl(device,t,channel,control_nr,control_value)
    • onProgram(device,t,channel,program_nr)
    • onChannelPressure(device,t,channel,value)
    • onPitchBend(device,t,channel,value)
    • onSystemCommon(device,t,b1,b2,b3)
    • onSyssx(device,t,hexadecimal_string)
    • onActive(device,t)
    • onClock(device,t)
    • onTimer(t)  : cascaded periodical trigger :(GUI => basslua => luabass)


Midi-out note-on conflict management

To manage conflict of same pitch on same channel, the API uses the "extended midi-channel". One midi-channel can be "linked" to additional channel on the same device, to play multi note-on on same pitch/channel.


LuaBass API

An LUA script can use the functions of  luabass C-module ( loaded by default in global _G ) :


  • midi device section
    • inGetMidiList
      • return: table of midi-in device
    • inGetMidiName
      • parameter #1 : [1..]  nr
      • return : name of the midi-in  device
    • outGetMidiList
      • return: table of midi-out device
    • outGetMidiName
      • parameter #1 :  [1..]  nr
      • return : name of the midi-out  device
  • track section
    • outTrackOpenMidi : open the track on a midi out
      • parameter #1 : integer track nr
      •  parameter #2 : integer midi channel
      • parameter #3 : string setting instrument initial ( eg mypiano(P0/C10/2)
      • parameter #4 : midi out device
      • parameter #5 : optional number of additional physical MIDI channels attached to this MIDI channel ( default 0 )
      • parameter #6 : optional track name for information
      • parameter #7 : optional localoff. Default true
    •  outTrackOpenVi : open the track on a Virtual-Instrument ( midi-SF2 or VSTI )
      • parameter #1 : integer track nr
      • parameter #2 : integer midi channel
      • parameter #3 : string initial
      • parameter #4 : SF2/VSTI filename, with its .sf2/.dll extension. If file-name ends with @x : x is the parameter#7
      • parameter #5 : optional , integer, number of additional physical MIDI channels attached to this MIDI channel ( default 0 )
      • parameter #6 : optional integer, Vi font volume 0..64..127
      • parameter #7 : optional integer, audio ( ASIO for PC ) device nr. Default g_default_audio_device, or as defined in parameter #4
    • outTracksClose : close all the tracks
    • outTrackMute : It's different than an audio volume on the channel using note ctrl7 !!
      • parameter #1 : mute = 0, unmute = 1, toggle = 2
      • parameter #2 : optional nrTrack ( default 1 )
    • outSetTrackVolume : set track volume. Different than an audio volume on the channel using note ctrl-7 !!
      • parameter #1 : volume 0..64(neutral)..127
      • parameter #2 : optional nrTrack ( default 1 )
    • outGetVolumeTrack
      • parameter #1 : optional nr track ( default 1 )
      • return current volume
    • outSetTrackInstrument :  set instrument for a track .
      • parameter #1 : string which describe the instrument required. eg "pianoleft(P0,C10/1)"
      • parameter #2 : optional nrTrack ( default 1 )
    • outSetVolume : set global volume, over all tracks
      • parameter #1 : 1..127
    • ouGetVolume : get the global volume
      • return the global volume 1..127 
  • chord section : to manage a table of pitches as an object
    • outSetChordCompensation
      • parameter #1 : [0..32]  compensation of the mitigate different number of notes in chords
    • outSetRandomDelay
      • parameter #1 : [0..256] random delay in ms
    • outSetRandomVelocity
      • parameter #1 : [0..50 ] random velocity
    • outChordSet :  set the chord to play with outChordOn
      • parameter #1 : unique_id . With -1 : return a unique-id
      • parameter #2 : transpose
      • parameter #3 : [0..] delay in ms between notes
      • parameter #4 : ([0..50..100]) % dvelocity between notes ( 50 all equal, 25 divide by two for next note )
      • parameter #5 & #6 : start# and end# of pitches ( 1 & -1 : all pitches , -1 & 1 : all in reverse order )
      • parameter #7.. : list of pitch
      • return the unique_id
    • outChordOn : play a chord prepared by chordset
      • parameter #1 : unique_id ( set in outChordSet )
      • parameter #2 : velocity
      • parameter #3 : optional integer delay dt in ms before to send the msg
      • parameter #4 : optional nrTrack ( default 0 )
    • outChordOff : stop a chord played with chordon
      • parameter #1 : unique_id ( set in outChordSet )
      • parameter #2 : optional velocity, default 0
      • parameter #3 : optional integer delay dt in ms before to send the msg
  • Midi-event section
    • outNoteOn
      • parameter #1 : pitch 1..127
      • parameter #2 : optional velocity ( default 64 )
      • parameter #3 : optional unique id. ( to manage concurrential note-on note-off ). Default 0 .With -1 : a unique_id is returned
      • parameter #4 : optional integer delay dt in ms before to send the msg
      • parameter #5 : optional nrTrack ( default 1 )
      • return the unique id
    • outNoteOff
      • parameter #1 : pitch 1..127 ( if parameter "unique id " is defined, this parameter can be = 0 )
      • parameter #2 : optional velocity, default 0
      • parameter #3 : optional unique id ( to manage concurrential note-on note-off )
      • parameter #4 : optional integer delay dt in ms before to send the msg
      • parameter #5 : optional nrTrack ( default 1 )
    • outPressure
      • parameter #1 : pitch
      • parameter #2 : pressure
      • parameter #3 : optional integer delay dt in ms before to send the msg
      • parameter #4 : optional nrTrack ( default 1 )
    • outControl
      • parameter #1 : nr control
      • parameter #2 : data
      • parameter #3 : optional integer delay dt in ms before to send the msg
      • parameter #4 : optional nrTrack ( default 1 )
    • outProgram
      • parameter #1 : nr program
      • parameter #2 : optional integer delay dt in ms before to send the msg
      • parameter #3 : optional nrTrack ( default 1 )
      • parameter #4 : optional bank msb
      • parameter #5 : optional bank lsb
    • outPitchbend
      • parameter #1 : value -8192 ..0..8192
      • parameter #2 : optional integer delay dt in ms before to send the msg
      • parameter #3 : optional nrTrack ( default 1 )
    • outChannelPressure
      • parameter #1 : value
      • parameter #2 : optional integer delay dt in ms before to send the msg
      • parameter #3 : optional nrTrack ( default 1 )
    • outTune
      • parameter #1 : optional, float, A4 Frequency Hz ( default 440 Hz )
      • parameter #2 : optional nrTrack ( default 1 )
    • outBendRange
      • parameter #1 : semitone , integer , ( default 1 )
      • parameter #2 : optional nrTrack ( default 1 )
    • outClock
      • parameter #1 : optional delay dt in ms before to send the msg
      • parameter #2 : optional integer track ( default 1 )
    • outSystem
      • parameter #1 : byte 1
      • parameter #2 : byte 2
      • parameter #3 : byte 3
      • parameter #4 : optional delay dt in ms before to send the msg
      • parameter #5 : optional integer track ( default 1 )
    • outSysex
      • parameter #1 : text hexa message sysex ( eg ""F0 7E 7F 09 01 F7" )
      • parameter #2 : optional integer track ( default 0 )
  • Audio section
    • audioClose : close all the audio streams
    • getAudioList
      • return the list of audio devices
    • getAudioName
      • parameter #1 : nr device
      • return the name of the audio device
    • audioAsioSet : open the setting of the ASIO device  ( PC only )
      • parameter #1 : nr device
      • return : buffer length
    • audioAsioBuflenSet : set audio buffer settings ( to be called before any use of audio ( vi, wav ... )
      • parameter #1 : Buffer length in samples ( 0 :use the prefereed one )
    • audioDefaultDevice : set audio default device ( to be called before any use of audio ( vi, wav ... )
      • parameter #1 : audio_device 1..
    • outSoundPlay
      • parameter #1 : audio file name, with its extension ( end of name can be "@audio_device", to plug this sond in the non-default audio-output )
      • parameter #2 : optional volume 0..64..127
      • parameter #3 : optional pan 0..64..127
      • parameter #4 : optional integer, audio ( ASIO for PC ) device nr, default g_default_audio_device
      • return : ref for further manipulation
    • outSoundControl
      • parameter #1 : reference to audio ( returned by sound_play )
      • parameter #2 : optional volume 0..64..127
      • parameter #3 : optional pan 0..64..127
      • parameter #4 : control the sound : 0=pause, 1=restart, 2=stop
  • Virtual Instrument section ( VI )
    • outListProgramVi : create text files, with instruments available in the VI. The text file has the same name than the VI, but with txt etxension
      • parameter #1 : VI file name, with its .sf2 or .dll extension
    • viVolume : set the volume of a midi Virtual Instrument
      • parameter #1 : VI track ( returned by vi_open )
      • parameter #2 : volume 0..64..127
  • post-Midi-out section
    • onMidiOut : set a LUA script for each midiout msg. This script contains optional functions :
      • onNoteOn(track,pitch,velocity) : process midiout noteon
      • onNoteOff(track,pitch,velocity) : process midiout noteoff
      • onProgram(track,program) : process midiout program
      • onControl(track,control,value) : process midiout control
      • onPitchbend(track,value) : process midiout pitchbend
      • onChannelPressure(track,value) : process midiout channel pressure
      • onKeyPressure(track,pitch, value) : process midiout key pressure
      • onClock(track) : process midiout clock
      • onTimer(t) : cascaded regular timer
    • These functions return a list of zero or many MIDI/DMX messages, which replace the original MIDI message captured :
      •   One MIDI message is a list of 4 values :
        • integer trackNr 1..16
        • integer value1 0..127 ( pitch for note, programNr, controlNr, LSB for pitchbend )
        • integer value2 0.127 ( velocity for note, controlValue, MSB for pitchbend , 0 for program, )
        •  "NoteOn",  "noteOff", "keyPressure", "Control", "Program", "channelPressure",  "pitchBend"
      • One DMX message to set all channels is a list of 2 values :
        •  string of DMX values separated with "/", using table.concat'(mydmxv,"/"); e.g.: "1/2/3/4/5/6/7/8"
        •  "DMXall"
      • One DMX message to set one channel is a list of 3 values :
        • integer channel 0..255
        • integer value 0..255
        •  "DMX"
  • DMX section
    • outOpenDmx : open dmx com port
      • parameter #1 : comport ( 0..DMX_V_MAX )
      • parameter #2 :  nb channel ( 1..DMX_CH_MAX )
      • retun : true if open, else return false
    • outSetDmx : set dmx configuration
      • parameter #1 : tenuto value in the time (0..256). 256==direct 0,  0==no decrease, default 256
      • optional parameter #2 : ramping value in the time (0..256). 256==direct value,  0==slow ramping, default 256
      • optional parameter #3 : string of hook track nr, comma separated , default : no change
      • optional parameter #4 : string of mapping MIDI-pitch (comma separated) to DMX-channel, default : no change
    • outDmx : set dmx value with ramping and tenuto
      • parameter #1 : channel (0..255)
      • parameter #2 : dmx value (0..255)
    • outDmxall : send directly dmx values
      • parameters #1..512 : dmx values (0..255)
    • outGetDmxList : list serial devices
      • return the serial devices in an array
    • outGetDmxCount
      • return the number of serial device
    • outGetDmxName
      • parameter #1 : device nr
      • return the name of the serial device