JMSL Tutorial: Instruments and Interpreters
You may worry that JMSL's Instrument and Interpreter approach is so open
ended that you have to build everything from scratch. Not so. For example,
JMSL already includes MidiInstrument than excels at sending Midi notes out
to your favorite Midi device. The best API for doing this is Grame's MidiShare, since it supports
time-stamped MIDI output at the note level. Since MidiShare uses a native library,
we cannot demonstrate MidiShare in these Applets.
Instead, here we will send MIDI
using JMSL's MidiIO_JavaSound MusicDevice. Sun's JavaSound MIDI package provides MIDI output,
does not support MIDI input, and at this time, does not support timestamped output,
so timing will be no more accurate than Java Thread scheduling (fast tight melodies will probably sound ragged).
The melody played here is a little more "floating" so the timing issue is not so apparent.
Applet Source
A few words on MidiInstrument...
MidiInstrument is an Instrument subclass that uses a standard MidiInterpreter
to play Midi note data stored in a MusicShape.
MidiInstrument assumes shape data looks like this: - dimension 0 = duration
- dimension 1 = pitch
- dimension 2 = velocity
- dimension 3 = sustain time
MusicShape data that plays a staccato chromatic melody would look like this,
for example:
dur pitch vel sustain
1.0 65.0 120.0 0.25
1.0 66.0 120.0 0.25
1.0 67.0 120.0 0.25
1.0 68.0 120.0 0.25
Overlapping pitches could be achieved like this:
dur pitch vel sustain
1.0 65.0 120.0 1.5
1.0 66.0 120.0 1.5
1.0 67.0 120.0 1.5
1.0 68.0 120.0 1.5
A big fat 4-note chord held for 10 seconds would look like this:
dur pitch vel sustain
0.0 65.0 120.0 10.0
0.0 66.0 120.0 10.0
0.0 67.0 120.0 10.0
1.0 68.0 120.0 10.0
Any MusicShape that conforms to this dimension definition can setInstrument(new
MidiInstrument()) and send Midi notes.
Of course, you can create data on-the-fly instead of first building a MusicShape.
Use MidiInstrument's noteOnFor() method to do this. For example, the following
line of code could be put into a repeat() method of a MusiciJob which had
a MidiInstrument.
...
// Bang a Midi note using noteOnFor(double playTime, double timeStretch, int pitch, int vel, double holdtime)
((MidiInstrument)getInstrument()).noteOnFor(playTime, 1.0, JMSLRandom.choose(50,74), JMSLRandom.choose(40,128), 0.5 + JMSLRandom.choose(3.0));
...
Next, we will see how to create a custom Instrument that plays a simple
JSyn circuit. You will need the JSyn plug-in, available at www.softsynth.com.
(C) 1997 Phil Burk and Nick Didkovsky, All Rights Reserved
JMSL is based upon HMSL (C) Phil Burk, Larry Polansky and David Rosenboom.