|  |     I pulled this off rec.music.synth today...
    
    
    	- Rick
    
    
Newsgroups: rec.music.synth
Path: decwrl!sun!pitstop!sundc!seismo!uunet!mnetor!utzoo!utgpu!jarvis.csri.toronto.edu!csri.toronto.edu!ghfeil
Subject: Midi Switching System  (long)
Posted: 25 Feb 88 19:24:58 GMT
Organization: University of Toronto, CSRI
 
=========
 
   About 6 months ago, a survey was presented in the International Midi 
Association Bulletin on the types of computers owned/used by its members.
The survey indicated that the Commodore-64 was the most commonly owned
computer, although not the most commonly 'wished-for' computer. This prompted
me to consider presenting a music program I have written for the Commodore-64
to you people on the net. The program, called "Midi Switching System",
is a combination midi switcher/sequencer/composer.  For any old C-64 hackers, 
it derives from an earlier program that used just the 64's internal sound chip 
(SID). I used that program to create a short demo called "Synth Sample" which 
received a quite wide distribution, so you may have seen it.
 
Midi Switching System (MSS) has 4 major objectives:
 
1) Act as a general switch for Midi information, with routing capabilities
   for both "programmed" (sequenced) and "real-time" (what you play) Midi 
   data.
 
2) Act as a flexible sequencer with music represented using a 'music 
   language' similar to a simple computer language. This allows a very
   compact representation, as the natural repetition and patterns in music 
   (esp. rock and pop) can be taken advantage of using 'loops' and 
   'subroutines'.  Various options should be available in entering music,
   from writing the notes one by one to recording them in real-time. 
   Music, whether recorded in real-time or not, should be easy to edit in 
   detail afterwards. The editing functions available should cover the 
   complete range of musical things you might want to do (eg. transposition, 
   quantization, time inversion, pitch inversion etc) as well as standard
   editing functions (global search/replace etc).
 
3) Enable the performer(s) to interact in real time with the programmed
   portions of the music. This concept is realized in practice by allowing
   the keys on the control keyboard to represent arbitrary actions, not
   just notes to be played.
 
4) Provide for the efficient manipulation of control wheels (pitch, mod, 
   continuous controllers etc). By efficient I mean not recording every 
   controller position update like many sequencers do, but rather being able 
   to specify how the controller should be manipulated over time, 
   eg. "slide mod wheel from 0 to full over a time period of one second".
 
 
The conceptual organization is of 16 tracks of music, where the first 12
may be programmed (sequenced) or 'real-time' or both, while the last 4
(13-16) can only be real-time tracks. For each track there is an associated
mapping onto Midi channels. This mapping is quite general. 
For example, suppose we are considering track 1, which has a short simple 
melody programmed into it, say E,D,C,E,C. This would look something like 
this in the statements of the music language, assuming we are using octave 
four and all quarter notes:
 
	P E,4;Q        * P stands for PLAY, Q is a quarter note
	P D,4;Q
	P C,4;Q        * C,4 = middle C, Midi note 60
	P E,4;Q
	P C,4;Q
 
(Note that you are not limited to one-note-at-a-time, eg to play a C-major 
 chord you would use:
	P C,4;Q
	+P E,4;Q
	+P G,4;Q
 In general it is possible to represent multiple lines of music in a
 single track, although it's smarter to use separate tracks, as things 
 can get a bit unreadable. 
 It is also possible to do 'real-time record' where you play a passage
 on the keyboard and it gets converted into the required format, so that
 you usually don't need to physically type what you see above.)
 
So far this will not make a sound, because there is no indication of which
Midi channel should be used, that is, no output mapping has been defined.
The simplest case is mapping onto a single Midi channel, eg. chan. 8. 
This would be done by preceding the above with:
	#1 TO 8 
 
Or you could map to more than one channel, so each channel receives a copy
of the same Midi data (say you have three synthesizers and you want to 
layer sounds):
	#1 TO 8+9+14
 
An arbitrary transposition can be applied to any specific channel(s), 
eg. the synth at chan 9 should play an octave lower:
	#1 TO 8 + 9/-12 + 14
 
It is also possible to specify Midi filtering on a per-output-channel basis.
 
MSS is designed to support synths that can run in Midi mono mode, 
ie. multi-timbral synthesizers whose individual voices are assigned their
own individual Midi channels. This is done to provide precise Midi control 
over each voice.  An output mapping can give a list of Midi channels in 
which case MSS will do polyphonic voice assignment among the channels 
(Least-Recently-Used  algorithm, others available as well). 
For example, my Sequential Circuits Sixtrak can be set up so each of its
six multi-timbral voices responds to one of Midi channels 1 through 6.
Then the following mapping will use voices 4, 5 and 6 like a 3-voice
polyphonic synth:
	#1 TO 4,5,6
 
Now it is already possible to do 'keyboard layering', eg. 
	#1 TO 1,2,3         * map to channels 1,2,3
	S 88                * set 'piano' patch in voices 1,2, and 3
	#1 TO 4,5,6         * map to channels 4,5,6
	S 31		    * set 'string' patch in 4,5,6
	#1 TO 1,2,3 + 4,5,6 * do polyphonic voice assignment in 
                              channel groups 1,2,3 and 4,5,6 simultaneously.
	
Above, the 'S' command is a program change, which is sent to all channels
in the current output mapping.
 
 
To incorporate 'real-time' Midi info, an input mapping is defined. The
physical input is just a Midi-in port, but this is considered to be 
logically separated by Midi channel and within Midi channel by keyboard
ranges. An example is necessary:
 
Suppose we want to take all notes in octaves 2 and 3 from a Midi source
that transmits on channel 13 (a keyboard controller, say) and map them to
some other keyboard(s). The input mapping would look like this:
	#16 REALTIME 13;C,2;B,3
 
This means "map real-time input from Midi channel 13, using only notes in 
the range C-2 to B-3, to track 16". Then an output mapping could be 
defined for track 16 just as above.  You can see that with this arrangement 
it is possible to map arbitrary sections of the keyboard (as small as a 
single note) of one or more controllers (could be a dedicated controller 
or just a regular Midi-equipped synth, say, with 'local control' turned 
off) to arbitrary Midi channels and channel groups corresponding to your 
synthesizers and rack-mount voicing boxes, drumboxes, whatever.
Furthermore, all of the mappings can be changed dynamically in real-time.
 
The music representation language is designed to be flexible. It supports
symbols and macros so that you can effectively define 'new' commands.
For example, suppose you wanted to control a Midi drum machine that had
assigned the note C-4 (middle C) to its snare drum sound. Instead of using
	P C,4;Q
 
to sound the snare, you could define a symbol
	&SNARE='P C,4'
 
and then sound the snare drum using
	&SNARE;Q
 
--which is certainly a lot more readable. The same could be done for
Midi-controlled effects boxes, mixers, lighting controllers etc.
 
 
In order to satisfy the goal of flexible, efficient control of Midi 
parameters, MSS uses the concept of the LFO (low-frequency-oscillator).
MSS LFOs are actually general modulators that combine properties of 
simple envelope generators and 'standard' low frequency oscillators, 
and can be applied to any of the following:
 -pitch bender (Midi pitch controller)
 -mod wheel
 -aftertouch
 -key velocity
 -tempo
 -any Midi continuous controller or switch
 
Five parameters are given when setting up an LFO:
 1) Its initial value or starting point.
 2) Its target value or destination point.
 3) The time to slide from the initial value to the target value.
 4) The time to slide from the target value back to the initial value.
 5) A control parameter which selects special options:
     NOGATE  -Don't restart each time a new note is played.
     ONESHOT -Run for only one cycle.
     TOGGLE  -Switch abruptly between initial and target values instead 
              of sliding (like a square waveform for an LFO).
 
An LFO normally cycles continuously between its initial and target values,
and is either gated or not.  It can stop after one cycle (ONESHOT), like 
an A/D envelope generator, or even after one half-cycle, if one of the 
slide times is omitted.  For example, to slide the mod wheel from 0 to 
full deflection (127) in one second, one would use
	W MOD;0,127;1SE
 
To add a bit of vibrato to a sound, you could 'jiggle' the pitch bender
by small amounts using an LFO as follows:
	B .1,-.1;10HZ,10HZ
 
Above HZ is just a way to specify inverse seconds. One could say .1SE as 
well. One advantage of MSS LFOs is that cycle times can be specified very 
precisely, in absolute time as shown or in terms of note lengths.  An LFO 
can run exactly synchronized to the music to create powerful effects. 
 
 
Another important concept embodied in Midi Switching System arose from
the fact that I hate worrying about pushing buttons other than keys on
my keyboards during a song. This is probably because the patch change 
buttons on my Sixtrak often bounce or fail to react, which can lead to
selecting the wrong patch or missing the first few notes of the next bar.
To solve this problem MSS allows you to use keyboard keys for more than 
just playing a note. You can 
 
1) Transpose a melodic pattern playing in some other track in real time.
   I call this 'keyed sequencing' because you change the key of a 
   currently playing sequence. eg. for funk bass lines, you can create
   a sequence consisting of some syncopated pattern made up of one note
   in different octaves. Then transpose that sequence under real-time
   control to 'play' it. 
 
2) Select among a list of alternative actions based on what key you press.
   For example, suppose in a song you don't use the bottom few notes of
   the keyboard. Then you can define them to cause certain actions:
	C  --> action #1
	C# --> action #2
	D  --> action #3
 
   The indicated action may be arranged to take place immediately or at
   the beginning of the next bar, section etc. This can be used to 
   get around one of the nagging drawbacks of typical sequencers, that
   the length and order of the parts in a sequence (song) is fixed. You could
   program three parts for a song, say, 'verse', 'chorus', and 'bridge',
   and then use the first three keys of the keyboard to select what part
   to play next.
   
In addition to having the flow of music controlled by external events, it
can also be controlled by simple computations or a random number generator, 
eg. "randomly select one of four possible actions", 
 or "play a random note in the third octave".
 
 
Well, I hope this quite verbose description gives you some idea of what my
Midi Switching System is about. Only a general overview has been given
here.  I wrote MSS for my own use and incorporated all the features I want 
out of a music system. Unfortunately, as a result it may lack features others 
would consider important. Maybe 'user feedback' can change this.
 
Some of the drawbacks of Midi Switching System include:
 
-runs only on Commodore-64.
-no CMN (conventional music notation) interface, no fancy graphics,
 and essentially line-oriented editing.
-not especially 'user-friendly', although there is an online help system
 that contains over 85K of documentation in the form of a reference manual.
-no way (yet) to synch to an external clock. MSS provides the master clock
 using either Midi clock messages, a TTL clock pulse output or both.
-designed for use with a simple, dumb Midi interface, ie. one in, one out,
 no buffering.
-no easy provision (yet) for handling different types of Midi interfaces.
 This is mainly because I own only one interface and have no specs for any
 other common Commodore-64 interfaces, but this will change as soon as any
 people who express interest describe their interface to me (simply amounts
 to saying where the 6850's registers are mapped in memory, unless the 
 interface doesn't use a 6850 or is more complicated).  
 
 
Anyone who is interested can send me email at the address below. I am
willing to distribute the program for the cost of mailing and a blank
diskette.
 
Georg.
-- 
 
[email protected]
    
 |