| 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]
|