\ 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