HMSL, the Hierarchical Music Specification Language
(Note: the original document from 1994 is here.)
HMSL is a programming language for experimental music composition and performance. It is an object oriented set of extensions to the Forth language that was designed for Macintosh and Amiga computers in the 1980's. HMSL includes tools for exploring algorithmic composition, intelligent real time instrument design, MIDI control and response, and musical cognition and perception. HMSL was developed by Phil Burk, Larry Polansky and David Rosenboom at the Mills College Center for Contemporary Music and is distributed by Frog Peak Music. Development has been continuous since 1980. HMSL iwas widely used by experimental composers working at Universities and privately.
HMSL includes:
- compositional classes that support hierarchical event scheduling,
- user interface classes portable between Mac and Amiga,
- complete MIDI toolbox including MIDI File support,
- a powerful text based score entry system,
- tools for algorithmic composition and real time interaction,
- numerous examples and tutorials.
- Driving the Seattle Bell Garden using optically coupled solenoids while displaying animated video messages. (David Mahler and Phil Burk)
- Using Chaotic attractors to control pitches generated by real time synthesis software on an AudioMedia 56000 DSP card. (Darren Gibbs)
- Explore alternative tunings using an FB-01 and MIDI System Exclusive Messages. (John Chalmers)
- Generate pitches in a contracting tuning space controlled by a singer. (Larry Polansky)
- Use a lottery system run on multi-computer network to control timbres generated by Amiga hardware. (Nick Didkovsky)
An example hierarchy might look like the following:
TOP_COLLECTION PLAYER_1 PLAYER_2 JOB_CHAOS ANOTHER_COLLECTION STRUCTURE_MARKOV PLAYER_FAST PLAYER_SLOW PLAYER_MIXED JOB_PULSEThe TOP_COLLECTION could be a parallel collection which means it plays all of its components in parallel. Thus PLAYER_1 PLAYER_2 JOB_CHAOS and ANOTHER_COLLECTION would start together. If you wanted to stagger their starting times you could specify a "start.delay" for any object. PLAYER_1 could play one or more shapes which could consist of a melody or sysex info or other custom defined data. JOB_CHAOS will execute a user function at a specified interval and might, for example, use a chaotic attractor to generate notes. ANOTHER_COLLECTION is a collection in a collection and demonstrates that the hierarchy can be arbitrarily deep. ANOTHER_COLLECTION is sequential which means it will execute its components one after the other. STRUCTURE_MARKOV is a special class of collection that uses MARKOV chains to determine which of its components to execute next. This hierarchy is held together with a message passing scheme that coordinates the timing and execution of the entire system.
Here are some example calls that might relate to this example hierarchy:
\ Set repeat count for PLAYER_1 10 PUT.REPEAT: PLAYER_1 \ Define a function to be called whenever PLAYER_1 repeats \ That will stop PLAYER_FAST if it is playing \ with a probability of 1 in 5. : MAYBE.STOP.FAST ( player -- , called by player ) drop \ in this case we don't need this parameter 5 choose \ pick random number 0,1,2,3,4 0= \ is it zero, 1 chance in 5 IF stop: player_fast \ send stop message THEN ; \ 'C gets the address of a function 'C MAYBE.STOP.FAST PUT.REPEAT.FUNCTION: PLAYER_1
Thus a hierarchy can contain a mixture of data and user defined functions whose execution can be scheduled in a complex and dynamic way. This allows for some very unusual compositions.
HMSL has a complete MIDI toolbox that includes all common MIDI commands as well as system exclusive commands. The MIDI parser allows you to map incoming MIDI messages to arbitrary functions. MIDIFiles are supported so you can generate musical material for use with other programs, eg. sequencers and notation programs. You can also import material from sequencers and manipulate it.
The Amiga version provides a toolbox for local sound generation, sample playback, and alternate tunings based on ratios or precalculated periods.
HMSL includes a library of classes for building interactive graphical environments. You can make a screen with faders, command buttons, etc. You could use this to create patch editors or interactive performance systems.
A Score Entry System allows you to describe music in a somewhat familiar form. Here are some examples using the SES:
\ Define a simple melody as a motif. : MOTIF1 ( -- , this is a comment ) C3 D G E4 A3 G ; \ Play that motif as quarter notes then sixteenths PLAYNOW 1/4 motif1 1/16 motif1 \ Play random notes in one octave range \ in parallel with an accelerando : DOIT par{ 16 0 \ set up loop DO 12 choose \ random over 1 octave 60 + \ above middle C note \ play it LOOP }par{ 1/2 \ half notes \ accelerate using floating point \ by a factor of 1.2 every 3 half notes 1.2 3 2 faccel{ D E F# _pp A B \ softly _ff C E \ loud }faccel \ stop accelerating 1/6 C D E C D E \ triplets }par ;
In the above example you can see how we mix normal Forth operations like DO LOOP with SES commands. We can also use conditionals like IF and THEN or any other Forth command. The output of the SES can be played directly or sent to a SHAPE or a MIDIFile.
The Amiga version of HMSL was based on JForth from Delta Research. The Macintosh version included its own Forth with an integrated text editor. Both of those old Forths had kernels specific to the 68000 microprocessor. The current version of HMSL is based on a portable 'C' based Forth called pForth.
Use of HMSL requires software programming skills. An extensive manual, tutorial, and many sample pieces are included, however, to help people get started. HMSL comes with source code.
HMSL was originally distributed by Frog Peak Music. The current source code is available on GitHub.