##
JMSL Tutorial: MusicShape

In this tutorial, we introduce MusicShape: JMSL's principle data-storing
class. MusicShape is a Composable, so it can be put in a JMSL hierarchy
and launched. It plays its data on a schedule when launched.
A MusicShape has a fixed number of dimensions, and a flexible number
of elements. It can be thought of as a table of numerical data, whose number
of rows (elements) can vary. The number of columns (dimensions) stays fixed,
however.

The following data might represent a melody, where dimension 0 (first
column) holds duration, dimension 1 (second column) holds pitch, and dimension
2 (third column) holds Midi velocity.

0) 1) 2)

0) 1.0 65.0 120.0
1) 1.0 68.0 110.0
2) 1.0 72.0 100.0
3) 1.0 60.0 90.0
4) 1.0 63.0 80.0

Elements and dimensions are numbered beginning with zero, so the 5 elements
shown above are numbered 0..4, and dimensions are numbered 0..2
**IMPORTANT**: The numeric data in a MusicShape is abstract
and is only given meaning by its Instrument! MusicShape schedules
its elements one at a time, handing each to its Instrument's play() method.
Instrument.play() interprets the data passed in, and returns an updated
playTime to MusicShape. MusicShape waits until the updated playtime,
and proceeds to the next element. .In this way, MusicShape completely relies
on its Instrument to provide timing and interpretation. This separation
of data and intepretation is a very important musical design pattern.

Aside: Notice that even though Midi notes and velocities are whole numbers,
MusicShape stores them as double precision floating point values (Java's
*double*). All data stored in a MusicShape is double precision floating
point data. It can always be cast as an integer later when interpreted.

(C) 1997 Phil Burk and Nick Didkovsky, All Rights Reserved
JMSL is based upon HMSL (C) Phil Burk, Larry Polansky and David Rosenboom.