\ vl_sysex \ \ basic (but very useful) system exclusive commands for the yamaha vl70m. \ \ code: Han-earl Park \ copyright 2004 buster & friends' C-ALTO Labs \ (Valencia, October 1998 - \ (Southampton, January 2001 - \ \ MOD: HeP 10/29/98 Started project. \ MOD: HeP 11/09/98 Some confusion over the sysex chart (thank you yamaha): \ Whaddahell's the difference between common part, element, \ custom voice and internal voice parameters? \ current ctrl# assignment based on p.34 of the chart. \ MOD: HeP 11/11/98 Well, pitch bend range setting works after the fix... \ (At least yamaha had the good sense to add the ability \ to "browse" sysex commands from the device's display) \ Still need to rewrite the other stuff: See p.37 of chart. \ MOD: HeP 11/12/98 All the stuff works! \ MOD: HeP 11/13/98 Added controller range stuff. \ MOD: HeP 01/26/99 System exclusive audio effects control. \ MOD: HeP 01/27/99 Get rid of the error checking in the sysex words, these \ will be the responsibility of the high level code, the \ instrument and device classes etc. \ Since it isn't used, get rid of vl_device_id and the \ half hearted attempt at vl.request.param \ MOD: HeP 07/08/99 Change stack diagram for VL.SET.PARAM sysex address \ 'hi mid lo' to 'lo mid hi' to avaoid excessive stack \ manipulation. \ MOD: HeP 10/01/99 Use generic midi.bend.range from the file midi_plus \ in place of the vl70m specific vl.set.bend.range. \ Still retain vl.set.bend.range as depricated code. \ MOD: HeP 01/26/00 Move device id# code to the midi_plus file. \ MOD: HeP 01/23/01 Implement device id# in VL.SET.PARAM. \ MOD: HeP 08-04-04 Add VL.TUNE.SCALE{ ... }VL.TUNE.SCALE. \ MOD: HeP 09-16-04 Add vl70m_model_id. include? task-midi_plus myt:midi_plus anew task-vl_sysex $ 57 constant vl70m_model_id : VL.START.SYSEX ( -- ) midi.start.sysex $ 43 midi.xmit ; : VL.END.SYSEX ( -- ) midi.end.sysex ; : VL.SET.PARAM ( data1...dataN N lo mid hi -- , change parameter ) vl.start.sysex \ $ 10 midi_device_id OR midi.data.xmit \ vl70m_model_id midi.data.xmit \ midi.data.xmit \ send hi address midi.data.xmit \ send mid... midi.data.xmit \ send lo \ 0 DO midi.data.xmit LOOP vl.end.sysex ; \ pitch bend range \ \ note: bend range is set to between -12 and +12 semitones, and the polarity \ can be reversed (i.e. negative values have reverse behaviour). : VL.SET.BEND.RANGE ( n -- , set pitch bend range to +/- n semitones ) $ 40 + $ 01 \ number of data packets $ 23 $ 00 $ 08 \ lo mid hi address vl.set.param ; \ midi controller numbers : VL.SET.CTRL# ( c# addr -- , assign midi controller to parameter ) $ 01 \ number of data packets swap $ 00 $ 20 \ lo mid hi address: see p.37 of sysex chart vl.set.param ; : VL.SET.PRESSURE.CTRL# ( c# -- ) $ 0b vl.set.ctrl# ; : VL.SET.GROWL.CTRL# ( c# -- ) $ 29 vl.set.ctrl# ; : VL.SET.THROAT.CTRL# ( c# -- ) $ 2d vl.set.ctrl# ; : VL.SET.SCREAM.CTRL# ( c# -- ) $ 21 vl.set.ctrl# ; : VL.SET.EMBOUCHURE.CTRL# ( c# -- ) $ 17 vl.set.ctrl# ; : VL.SET.TONGUING.CTRL# ( c# -- ) $ 1d vl.set.ctrl# ; : VL.SET.DAMPING.CTRL# ( c# -- ) $ 35 vl.set.ctrl# ; : VL.SET.ABSORPTION.CTRL# ( c# -- ) $ 39 vl.set.ctrl# ; \ controller depth \ \ note: controller range is between -127 and +127, where negative values \ have reverse polarity. : VL.SET.CTRL.RANGE ( n addr -- , set controller range ) >r dup -7 ashift $ 02 \ number of data packets r> $ 00 $ 20 \ lo mid hi address: see p.37 of sysex chart vl.set.param ; : VL.SET.PRESSURE.RANGE ( n -- ) $ 0c vl.set.ctrl.range ; : VL.SET.GROWL.range ( n -- ) $ 2a vl.set.ctrl.range ; : VL.SET.THROAT.RANGE ( n -- ) $ 2e vl.set.ctrl.range ; : VL.SET.SCREAM.RANGE ( n -- ) $ 22 vl.set.ctrl.range ; : VL.SET.EMBOUCHURE.RANGE ( n -- ) $ 18 vl.set.ctrl.range ; : VL.SET.TONGUING.RANGE ( n -- ) $ 1e vl.set.ctrl.range ; : VL.SET.DAMPING.RANGE ( n -- ) $ 36 vl.set.ctrl.range ; : VL.SET.ABSORPTION.RANGE ( n -- ) $ 3a vl.set.ctrl.range ; \ scale tuning \ \ the tuning range of each scale degree is between -64 and 63 cents, where \ the cent value is a deviation from the 12 tone equal tempered scale. \ Yamaha also restricts us to the west european standard of 12 degrees to \ an octave scale. \ \ note that the $ 00 in the third line of (vl.set.tune) is really in the \ form of $ 0p where p is the part number. The part number, however, is \ ignored. see p.29 of sysex chart. : (VL.SET.TUNE) ( data addr -- , set the tuning of a scale degree ) $ 01 \ number of data packets swap $ 00 $ 08 \ lo mid hi address see p.33 of sysex chart vl.set.param ; \ the word below takes scale degrees as numbers starting from zero \ (c = 0, c# = 1, d = 2, d# = 3, e = 4 ... b = 11). While the tuning is in \ the range of -64 to +63 cents. : VL.SET.TUNE ( cent note -- , shift the tuning of the note ) swap $ 40 + \ data range of $ 00 to $ 7f swap $ 41 + \ addr between $ 00 and $ 4c (vl.set.tune) ; \ this word accepts 12 cent values corresponding to 12 tones from C to B. : VL.SET.TUNE.SCALE ( c c# d...b -- , tune 12 degrees of the scale ) 12 0 DO $ 40 + \ data range of $ 00 to $ 7f $ 4c i - \ addr between $ 00 and $ 4c (vl.set.tune) LOOP ; \ usage of the following: vl.tune.scale{ c c# d...b }vl.tune.scale variable vl-tune-scale{}-depth : VL.TUNE.SCALE{ ( -- , start specification of scale ) vl-tune-scale{}-depth @ -1 = IF depth vl-tune-scale{}-depth ! ELSE true abort" Consecutive calls to vl.tune.scale{ without a }vl.tune.scale. You cannot nest vl.tune.scale{...}vl.tune.scale" THEN ; : }VL.TUNE.SCALE ( c c# d...b -- , tune 12 degrees of the scale ) depth vl-tune-scale{}-depth @ - \ -1 vl-tune-scale{}-depth ! \ reset to prevent nesting \ 12 = IF VL.SET.TUNE.SCALE ELSE true abort" Incorrect number of items passed to }vl.tune.scale." THEN ; \ audio effects \ \ effect type selection \ these words take a basic effect type and a number indicating the \ specific effects algorithm. see pp. 14 - 16 of sysex chart. : VL.SET.REV.TYPE ( type alg -- , select the reverb algorithm ) $ 02 \ number of data packets $ 00 $ 01 $ 02 \ lo mid hi addr see. p.35 of sysex chart. vl.set.param ; : VL.SET.CHO.TYPE ( type alg -- , ...chorus type ) $ 02 $ 10 $ 01 $ 02 vl.set.param ; : VL.SET.VAR.TYPE ( type alg -- , ...type of "variation" effect ) $ 02 $ 40 $ 01 $ 02 vl.set.param ; : VL.SET.DIST.TYPE ( type alg -- , ...type of distortion or eq ) $ 02 $ 00 $ 00 $ 03 vl.set.param ; \ effect type dependent parameters \ \ note that the vl70m's audio effects parameters (from 0 to 15) are \ dependent on the effects algorithm being used. Yamaha doesn't make \ life any easier by spliting the parameter addresses between 0 to 9 \ and 10 to 15, thus the complexity of the code. : VL.SET.REV ( n p# -- , set value of reverb parameter ) dup $ 0b < IF $ 02 ELSE $ 06 THEN + \ lo sysex address $ 01 \ number of data packets swap $ 01 $ 02 \ lo mid hi addr vl.set.param ; : VL.SET.CHO ( n p# -- ) dup $ 0b < IF $ 22 ELSE $ 26 THEN + $ 01 swap $ 01 $ 02 vl.set.param ; : VL.SET.VAR ( n p# -- ) dup $ 0b < IF 2* $ 42 + \ lo sysex address >r dup -7 ashift \ split data $ 02 \ two data packets ELSE $ 66 + \ lo sysex address >r $ 01 \ single data packet THEN r> $ 01 $ 02 \ lo mid hi addr vl.set.param ; : VL.SET.DIST ( n p# -- ) dup $ 0b < IF $ 02 ELSE $ 16 THEN + $ 01 swap $ 00 $ 03 vl.set.param ; \ general effects parameters : VL.SET.REV.RETURN ( n -- ) $ 01 \ number of data packets $ 0c $ 01 $ 02 \ lo mid hi addr vl.set.param ; : VL.SET.REV.PAN ( n -- ) $ 01 $ 0d $ 01 $ 02 vl.set.param ; : VL.SET.CHO.RETURN ( n -- ) $ 01 $ 2c $ 01 $ 02 vl.set.param ; : VL.SET.CHO.PAN ( n -- ) $ 01 $ 2d $ 01 $ 02 vl.set.param ; : VL.SET.CHO->REV ( n -- ) $ 01 $ 2e $ 01 $ 02 vl.set.param ; : VL.SET.VAR.RETURN ( n -- ) $ 01 $ 56 $ 01 $ 02 vl.set.param ; : VL.SET.VAR.PAN ( n -- ) $ 01 $ 57 $ 01 $ 02 vl.set.param ; : VL.SET.VAR->REV ( n -- ) $ 01 $ 58 $ 01 $ 02 vl.set.param ; : VL.SET.VAR->CHO ( n -- ) $ 01 $ 59 $ 01 $ 02 vl.set.param ; \ initialize : VL.SYSEX.INIT ( -- ) -1 vl-tune-scale{}-depth ! ; : SYS.INIT ( -- ) sys.init vl.sysex.init ; vl.sysex.init