Subject: MANX Documentation
Revision: 0.31
Date: Feb 23, 2010
Changed: February 26, 2010. Corrections in certain chords by AN
Changed: January 1, 1998. Removed Windows 3.1 specifics, html version
Changed: March 17, Marcel Hendrix incorporated AN's remarks
Author: Marcel Hendrix

MANX, a Forth Package to formulate music


MANX was originally called FORMULA (FORth MUsic LAnguage), but I found out that the name was already in use by a commercial Forth music package.

MANX started its life in 1993 as support software for the Metallophone Project of the Dutch Forth Users Group. The metallophone project -- two relay-driven xylophones controlled by a computer programmed in Forth -- was a big promotional success at a local computer fair. The host computer interpreted specially formatted text files filled with score information. Appropriate output commands actuated relays to generate the wanted notes.

In the months after the fair MANX development continued. The current release 1.0 is not exclusively for metallophones anymore. The program is able to read and write standard MIDI (Musical Instruments Digital Interface) files, with special instrument drivers taking care of I/O details. At this moment MANX has drivers for metallophones, the PC speaker, and GM (General MIDI) synthesizers or soundcards that support MIDI.

The user interface of MANX is the regular Forth environment, enhanced with a number of special purpose music language words. This music language aims to be complete in the sense that a user should be able to translate anything written down in conventional scores to MANX commands. But of course there is more, much, much more. A short list of features:

In the next three chapters we will present a general overview of MANX's MIDI layer, of MANX itself, and of aspects concerning the writing of new device drivers. The MANX language is exactly defined on a word for word basis in the *.DOC files in the distribution package. But in the true Forth spirit we will advise you that when in doubt, read the code ...

MANX is written for a 32-bit ANS Forth, but in version 1.0 a lot of non-standard extensions are used. Therefore it is advised to use iForth 1.0 for DOS, Windows NT or Linux (all require an IBM-PC compatible with '386+'387 or better and at least 4 Mbytes of RAM).

Future versions of MANX may become standard ANS Forth with clearly bordered hardware dependencies. MANX is ported to non-IBM computers.

Reading, Writing and Interpreting MIDI files

The routines in MIDIRW.FRT are able to analyze the contents of standard MIDI files version 1.0 (1988). A 'decompilation' of the information is written to the terminal or to an ASCII text file.

MIDI files can also be played back on the available sound hardware, given a suitable driver. MIDIRW comes with drivers for the PC-speaker, for a network of metallophones, and for a GM (General MIDI) synthesizer. As most PC soundcards have MIDI drivers, a soundcard can also be used as an output device. Note that some cards come with a Windows MIDI driver and do not support MS-DOS. In that case you need to use iForth for Windows NT or Linux.

The most important application of MIDIRW is to support MANX. In this capacity, MIDIRW allows MANX to write full-featured MIDI type 1 (multiple track) files. There are no restrictions.

1. Analyzing MIDI files

The MIDI specification allows text records to be inserted in the file. These records are very helpful in identifying the intentions of the musician. The word .TRACKS ( "name" -- ) extracts these records and writes them to the terminal. Below is a dump of the output generated by .TRACKS militair.mid

[Sequence / track name] Militaire
:      0  [Text] Schubert, Trois Marches Militaires, no. 1. Transcription: A. Nijhof, 7 nov 93
:      0  [Text] Copyright (C) 1994
:      0  [Text] MANX Midi Productions
:      0  [Text] All Rights Reserved
:      0  [Sequence / track name] Player0
:      0  [Sequence / track name] Player1
:      0  [Sequence / track name] Player2
:      0  [Sequence / track name] Percussion
:      0  [Sequence / track name] Player3
:      0  [Sequence / track name] Player4
:      0  [Sequence / track name] Player5
:      0  [Sequence / track name] Player6
:      0   ok
It is seen that militair.mid contains 8 tracks.

A far more detailed report is generated by entering: DUMP-MIDI ( "input" "output" -- ). Below is an excerpt of the file d.txt, a file generated by entering DUMP-MIDI drums3.mid d.txt :

Chunk type: MThd
Length: 6 bytes.
Header format: 1, multiple tracks vertical.
Number of tracks: 9 
Division: relative; 576 PPQN

Track #0 

Chunk type: MTrk
Length: 134 bytes.
:      0  [Sequence / track name] Drums3
:      0  [Text] Just some drum patterns part III
:      0  [Text] Copyright (C) 1994
:      0  [Text] MANX Midi Productions
:      0  [Text] All Rights Reserved
:      0  [Time signature] 4 /4 24 MIDI messages per metronome beat, 8 /32 notes per quarter note.
:      0  [tempo] 266666 microseconds per quarter note.
:      0  [End of Track]

Track #1 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player0
:      0  channel 0 [control change] msb main volume := 127 
:      0  channel 0 [control change] msb pan := 34 
:      0  channel 0 [control change] external effects depth := 63 
:      0  channel 0 [control change] chorus depth := 0 
:      0  channel 0 [control change] msb (Roland) bank select := 0 
:      0  channel 0 [program change] Rhodes-Piano 
:      0  channel 0 [control change] modus, reset all controls := 0 
:      0  channel 0 [pitchbend] value  0 
:      0  channel 0 [control change] msb modulation := 0 
:      0  [End of Track]

Track #2 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player1
:      0  channel 1 [control change] msb main volume := 127 
:      0  channel 1 [control change] msb pan := 94 
:      0  channel 1 [control change] external effects depth := 63 
:      0  channel 1 [control change] chorus depth := 0 
:      0  channel 1 [control change] msb (Roland) bank select := 0 
:      0  channel 1 [program change] Rhodes-Piano 
:      0  channel 1 [control change] modus, reset all controls := 0 
:      0  channel 1 [pitchbend] value  0 
:      0  channel 1 [control change] msb modulation := 0 
:      0  [End of Track]

Track #3 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player2
:      0  channel 2 [control change] msb main volume := 127 
:      0  channel 2 [control change] msb pan := 63 
:      0  channel 2 [control change] external effects depth := 63 
:      0  channel 2 [control change] chorus depth := 0 
:      0  channel 2 [control change] msb (Roland) bank select := 0 
:      0  channel 2 [program change] Rhodes-Piano 
:      0  channel 2 [control change] modus, reset all controls := 0 
:      0  channel 2 [pitchbend] value  0 
:      0  channel 2 [control change] msb modulation := 0 
:      0  [End of Track]

Track #4 

Chunk type: MTrk
Length: 2124 bytes.
:      0  [Sequence / track name] Percussion
:      0  channel 9 [control change] msb main volume := 127 
:      0  channel 9 [control change] msb pan := 63 
:      0  channel 9 [control change] external effects depth := 63 
:      0  channel 9 [control change] chorus depth := 0 
:      0  channel 9 [control change] msb (Roland) bank select := 0 
:      0  channel 9 [program change] Acoustic-Grand-Piano 
:      0  channel 9 [control change] modus, reset all controls := 0 
:      0  channel 9 [pitchbend] value  0 
:      0  channel 9 [control change] msb modulation := 0 
:      1  channel 9 [control change] external effects depth := 63 
:      0  channel 9 [program change] Hammond-Organ 
:      0  [tempo] 266666 microseconds per quarter note.
:   2304  channel 9 [note on]  Bass-Drum-1 velocity 127 
:      0  channel 9 [note on]  Closed-Hi-Hat velocity 127 
:      0  channel 9 [note on]  Ride-Cymbal-2 velocity 127 
:    504  channel 9 [note off] Bass-Drum-1 velocity 127 
:      0  channel 9 [note off] Closed-Hi-Hat velocity 127 
:      0  channel 9 [note off] Ride-Cymbal-2 velocity 127 
:     72  channel 9 [note on]  Closed-Hi-Hat velocity 127 
:      0  channel 9 [note on]  Ride-Cymbal-2 velocity 127 

   [ etcetera, for a long long time ... ]

:      9  channel 9 [note on]  Closed-Hi-Hat velocity 127 
:     63  channel 9 [note off] Closed-Hi-Hat velocity 127 
:      9  channel 9 [note on]  Closed-Hi-Hat velocity 127 
:     63  channel 9 [note off] Closed-Hi-Hat velocity 127 
:      0  [End of Track]

Track #5 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player3
:      0  channel 3 [control change] msb main volume := 127 
:      0  channel 3 [control change] msb pan := 63 
:      0  channel 3 [control change] external effects depth := 63 
:      0  channel 3 [control change] chorus depth := 0 
:      0  channel 3 [control change] msb (Roland) bank select := 0 
:      0  channel 3 [program change] Rhodes-Piano 
:      0  channel 3 [control change] modus, reset all controls := 0 
:      0  channel 3 [pitchbend] value  0 
:      0  channel 3 [control change] msb modulation := 0 
:      0  [End of Track]

Track #6 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player4
:      0  channel 4 [control change] msb main volume := 127 
:      0  channel 4 [control change] msb pan := 63 
:      0  channel 4 [control change] external effects depth := 63 
:      0  channel 4 [control change] chorus depth := 0 
:      0  channel 4 [control change] msb (Roland) bank select := 0 
:      0  channel 4 [program change] Rhodes-Piano 
:      0  channel 4 [control change] modus, reset all controls := 0 
:      0  channel 4 [pitchbend] value  0 
:      0  channel 4 [control change] msb modulation := 0 
:      0  [End of Track]

Track #7 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player5
:      0  channel 5 [control change] msb main volume := 127 
:      0  channel 5 [control change] msb pan := 63 
:      0  channel 5 [control change] external effects depth := 63 
:      0  channel 5 [control change] chorus depth := 0 
:      0  channel 5 [control change] msb (Roland) bank select := 0 
:      0  channel 5 [program change] Rhodes-Piano 
:      0  channel 5 [control change] modus, reset all controls := 0 
:      0  channel 5 [pitchbend] value  0 
:      0  channel 5 [control change] msb modulation := 0 
:      0  [End of Track]

Track #8 

Chunk type: MTrk
Length: 50 bytes.
:      0  [Sequence / track name] Player6
:      0  channel 6 [control change] msb main volume := 127 
:      0  channel 6 [control change] msb pan := 63 
:      0  channel 6 [control change] external effects depth := 63 
:      0  channel 6 [control change] chorus depth := 0 
:      0  channel 6 [control change] msb (Roland) bank select := 0 
:      0  channel 6 [program change] Rhodes-Piano 
:      0  channel 6 [control change] modus, reset all controls := 0 
:      0  channel 6 [pitchbend] value  0 
:      0  channel 6 [control change] msb modulation := 0 
:      0  [End of Track]
The experimental word .TRACK-SCORE ( u "inputfile" --- ) tries to translate the MIDI note events in track u of inputfile to a set of MANX commands. It is only moderately successful as the following dump shows:

	FORTH> 1 .TRACK-SCORE ziep.mid

	1153 \2304 rest /8 d3  /8 d3  
	/4 g3 /16 g3  432 \2304 rest   /8 g3  /8 a3  
	/16 b3 432 \2304 rest  /4 g3 
	/8 a3 /8 a3  72 \2304 a3  216 \2304 rest  72 \2304 a3  216 \2304 rest 
	/8 b3 /8 a3 
	/4 g3 
For reference, here is the original score, ZIEP.SCO :
	Player0 PART

	| 3 /4 MEASURE  Legato Mezzo-Forte Whistle reprogram
			50 pan  50 portatime  
			true portamento
			/2 rest  /8 d3 d3
	|            	/4 g3 [.] [>] g3  /8 g3 a3
	| 2 /4 MEASURE  /4 [.] [>] b3 g3
	| 3 /4 MEASURE  /8 a3 a3  [>] [.] a3 [.] a3  b3 a3
	|  		false portamento
			/4 [>] g3 /2 rest 

2. Playing back MIDI files

MIDI files are played back a track at a time using the command PLAY-TRACK ( u "filename" -- ). For analysis purposes it is also possible to select an arbitrary amount of tracks, mix them together and play the result. This is accomplished with the words CLEAR-MIX MIX ( u "name" -- ) NMIX ( i*u i "name" -- ) and PLAY-MIX ( -- ).

CLEAR-MIX resets the memory-array in which MIX accumulates the tracks. MIX reads the specified track from the specified file and sorts it into the memory-array. Use PLAY-MIX to hear the result. The word NMIX is more efficient than MIX when multiple tracks must be read. Note that NMIX automatically executes CLEAR-MIX.

Of course it is also possible to play a complete file all at once. However, some professional MIDI products write files that contain several variants of the same musical score, presumably to enable the material to be played over low-fi soundcards but also on high-end GM synthesizers. Consequently MIDIRW has extra PLAY-xx words that select the correct tracks from these files.

The easiest word to use is PLAY-FULL ( "name" -- ). It will work for most Public Domain material that records the percussion on channel 9 (unless you changed #pch in the config.frt file). PLAY-FULL also works for any MANX file.

PLAY-WP ( "name" -- ) plays WordPerfect Presentations 2.0 MIDI-files.

PLAY-SESSIONl ( "name" -- ) is meant for MIDI-files generated with the SESSION program which is bundled with the PRO-AUDIO Spectrum16 soundcard. Plays the low-quality tracks. Likewise PLAY-SESSIONh ( "name" -- ) plays the high-quality tracks.

It is possible to change the replay speed of all of the above PLAY-xx words by setting the DVALUE replay-speed appropriately (see the glossary).

Two additional commands with primarily educational value are the words MPRINTING-ON and MPRINTING-OFF. Using these, all events are dumped to the screen as they are played.

3. Writing MIDI files

The precise mechanics of writing MIDI files is not documented here. In short, writing is done in multiple passes. In the first pass the output of MIDIRW is redirected to memory-arrays ('tracks', one for each player). MANX requests are passed to a set of MIDIRW deferred words which translate the requests to time-stamped MIDI events. In the next passes, these requests are read from the arrays, formatted as a type 1 MIDI file and written to disk. The file is written multiple times as on the first write the MIDI header information fields are not yet correctly filled in.

MANX as a Forth Music Language

1. Introduction

The MANX language allows the programmer to convert conventional graphical music notation to ASCII text, suitable for manipulation by a computer. The text input form is much more suitable for algorithmic transformation, looping, copying, storing, retrieving etcetera. Also, people lacking formal musical training may find the format easier to interpret than a conventional score. MANX's output is a series of commands to a connected speaker, metallophone network or GM synthesizer / soundcard. These commands "execute" the score (so you can hear it). In other modes, MANX just writes to the terminal screen or to disk. Combinations of most of the above are possible.

Note that a musical score is quite ambiguous and leaves a lot of opportunity for a human being to interpret the notes as he or she sees fit. This ambiguity is lost once conversion to a computer readable format has taken place. An example is the directive 'as fast as possible' which I found in Emerson, Lake and Palmer's ELP songbook.

MANX accepts a set of predefined music commands. However, it is just an extension of Forth and all the power of this language is available for additional manipulation. Especially, MANX is still user-extensible.

All of MANX's commands work equally well for compilation and direct execution at the terminal. Some commands have to be entered in pairs, however (e.g. PART || ). There is a debugging mode, toggled with PRINTING-ON and PRINTING-OFF , which shows in plain text what a compiled sequence is doing.

Actually MANX can be used in three modes. In the first mode one experiments at a terminal, typing the needed commands and writing colon definitions interactively. This mode is entered by typing TERMINAL. When MANX is in the wrong mode (when .STAT and .MIDI-STATUS show one of the words RECORDING PLAYING MIXING or OFF after the text 'Vectors : ' on the first line of their output) it will refuse to execute some commands. In most cases MANX will sense that you want TERMINAL mode, but especially when compiling fails it may get confused.

The second mode is typing the commands into an ASCII text file with a special format. This file (with the extension .SCO) is included just like any regular .FRT file. When the word SCORE ( "name" -- ) is used, executing name plays back the score, but only the PART that corresponds to the Player that is currently active (only one, not a group).

The third mode works from the same file used for the second mode. That file is converted to a completely standard MIDI file by the word BUILD-MIDI ( "name" -- ). All the tools from MIDIRW.FRT can then be used to playback and manipulate this file. Note especially that the output file is directly readable by MIDI sequencing or scoring utility programs.

2. General Score Commands

When working in mode 2 or 3 (see introduction) the word SCORE ( "name" -- ) is at the top of the command hierarchy. It defines a word name that is used to playback the notes entered in the PART that corresponds with the current player (see below). No special word is needed to specify the end of a SCORE , however, the number of PART's and the number of events per PART are limited to fixed numbers, restricted by available memory.

The current player

Presently, MANX can be used to generate scores for an orchestra of nine players. The names of these "players" are found in Table 1. Executing one of the switch names from the keyboard will direct all input to the player corresponding to that name.


  I-AM-PLAYER0  Flute reprogram  c2 c3  ( play c2 c3 on flute)
  I-AM-PLAYER1  Voice-Oohs reprogram c2 ( sing c2 )
  I-AM-PLAYER0  c1 			( c1 on flute again )
Also, after entering I-AM-PLAYER0 and including a .SCO file, only the text in the PART reading Player0 PART ... || is compiled, all other PARTs are ignored (see the paragraph 'Player Names' below for the word Player0).

The players Conductor ( I-AM-CONDUCTOR ) and Percussion ( I-AM-PERCUSSION ) are special in that their PART can contain special commands.

 Table 1. The available player names. Future versions of MANX may support
	  up to 16 players (16 is the MIDI limit).


Player Names

The words from the following table push a string identifying a player. This string is used by PART to decide whether the text following in the input stream is for the current player and should be compiled.

 Table 2. Identifying a player.

	Conductor	Percussion	Player0
	Player1		Player2		Player3
	Player4		Player5		Player6


The word PART ( c-addr u -- ) checks to see if c-addr u is the name of the current player. If false, it skips all words up to and including the word || . If true, it compiles the following text into the memory-array used by SCORE .

The word | ( "bar" ) breaks up the note data in a PART into manageable pieces. MANX does timing checks on bar boundaries, based on the data entered with MEASURE in the first bar of a new PART . The statement 4 /4 MEASURE informs MANX that each following bar counts a total of 4 quarter notes. A warning message will be issued for the second bar in below example (the words /4 c3 etc. are explained shortly):

 Player0 PART
 | 3 /4 measure  /4 c3 e3 g3   		( 3/4 )
 | /4 c3  /4 g3  /8 c3 e3 g3 ||		( 2/4 + 3/8)
It is possible to duplicate a bar using n DUPLICATES (duplicate the last entered bar n times) or DUPLICATE (duplicate the last entered bar only once). To replay just any of the previous bars you must define a label before that bar, using the word L: ( "name" -- ). After that, name (which is actually a CONSTANT ) can be used with REDO to replay the bar. To REDO a continguous range of bars, label the first and last or last+1 bar of the range ( with \0 ), then enter BIS ( u1 u2 -- ) or ENCORE ( u1 u2 -- ).

The end of the PART is signalled with the word || .


Notes are characterized by their pitch and their duration. As duration does not change as often as pitch, it is not necessary to re-enter the note duration everytime. (MANX remembers it). The pitch is always required.

Pitch words, and thus note names as duration is implicit, are in Table 3. MANX also understands the American notation, e.g. A#0 for ais0 and Eb3 for es3 (for other languages: please call MANX). Note that because of the MIDI standard, es3 and dis3 are exact equivalents.

 Table 3. The following list declares all valid MANX pitch/note names.
          The notation a0 .. a9  means  a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 .

	  a0   .. a9	ais0 ..	ais9	as0  .. as9	b0   .. b9	
	  bes0 .. bes9	bis0 .. bis9	c0   .. c9	ces0 .. ces9	
	  cis0 .. cis9	d0 .. d9	des0 .. des9	dis0 .. dis9	
	  e0   .. e9	eis0 .. eis9	es0  .. es9	f0   .. f9	
	  fes0 .. fes9	fis0 .. fis9	g0   .. g9	ges0 .. ges9
	  gis0 .. gis9
	  A#0 .. A#9	Ab0 .. Ab9	Bb0 .. Bb9	B#0 .. B#9
	  Cb0 .. Cb9	C#0 .. C#9	Db0 .. Db9	D#0 .. D#9
	  E#0 .. E#9	Eb0 .. Eb9	F#0 .. F#9	Fb0 .. Fb9
  	  Gb0 .. Gb9	G#0 .. G#9	
A very important element of music is silence. This element is only characterized by its duration, so we need a special name for it: rest. A rest defaults to the last entered duration, like a normal note.

To specify the duration of a note or a rest the words in tables 4 and 5 are used. A special case is handled with WHOLE, which specifies a duration equal to a full bar ( 4 /4 MEASURE WHOLE REST is equal to 4 /4 MEASURE /1 REST ).

  Table 4. MANX fixed note durations. /4 means quarter note.

	/1	/1.	/2	/2.	/3	/3.	/4	/4.	
	/5	/6	/6.	/7	/8	/8.	/9	/9.	
	/10 	/11	/12	/12.	/13	/14	/15	/16	
	/16.	/17	/24	/24.	/32	/32.	/48	/48.
	/64	/64.	/96	/96.	/128	/128.	/192	/192.	
  Table 5. MANX variable note durations. 3 \4 means 3 quarter note.

	\1	\2	\3	\4	\6	\8	\9	\12
	\16	\24	\32	\48	\64	\128	\192	\384
	\480	\960	\2304	
Another important characteristic of music is tempo, the speed at which notes are played. MANX uses the word MM ( u -- ) to specify tempo. When the current note duration is a quarter ( /4 ) 120 MM sets a metronome value of 120 quarter notes per minute.

Occasionally, it is necessary to "squeeze" a number of notes into a specified time slot. In a conventional score we might find "play these five sixteenth notes while the other instrument plays a quarter note". To handle this situation MANX has the << ( u1 u2 -- ) and >> words, to arbitrarily "stretch" time.

The present tempo can be saved with \TEMP and restored with /TEMP.

Special Conductor commands

In the Conductor PART it is possible to balance the loudness of all the cooperating Players by using the word VOLUME! ( u1 c-addr u2 -- ). The c-addr u2 describes a string identifying the Player, the u1 is an absolute volume (range 0 .. 100).

The most important task of the Conductor is to control the timing of the SCORE , with the word +TEMPO ( mul div -- ). Typically, a Conductor PART only contains a MEASURE command and a series of rests to take it to the place where a +TEMPO or VOLUME! command is wanted.

A ritardando or acceleration is accomplished with the words RITARD ( time delta -- ) and ACCEL ( time delta -- ). To accelerate the music 'by a little bit' over a time period of 7 quarter notes, enter: 7 /4 10 ACCEL . The actual response curve of RITARD and ACCEL can be edited. It is complementary.

3. Chords and Arpeggios

A chord is a series of notes of the same duration that sound at the same time. An ARPEGGIO is a series of notes that stop at the same moment but have slightly displaced starting times. To save typing, the commands to specify which notes go into the chord or arpeggio and the actual execution of the effect are combined into one: {ARP and { . Both words search for the } delimiter. Between the {ARP or { and } words only note names, rests, words build by PNOTE and words of the TIE class may be entered. The words -TIE -TIE- and TIE- work slightly different when used inside a chord or arpeggio.

The words CHORD and ARPEGGIO take the list build by the last { or {ARP and play it as a chord or arpeggio. Note that a list build with { can be used with ARPEGGIO and a list build with {ARP works with CHORD . However, a list containing TIE commands should not be used with either CHORD or ARPEGGIO.

An infrequently used feature is the possibility to have several lists active, using the words CHORD0 .. CHORD9 with the revectoring word SET.

4. Expression Commands and Ties

A large number of words are available to influence the loudness with which a note is played: +VOL ( mul div -- ) for a relative change, VOL ( u -- ) to change it absolutely. Crescendos and diminuendos are built with CRESC ( time delta -- ) and DIMIN ( time delta -- ). Loudness can be saved and restored with \VOL and /VOL respectively.

In addition to this we can pick from a series of standard musical terms to set an absolute loudness: Fortissimo, Forte, Mezzo-forte, Mezzo-piano, Piano and Pianissimo . The previous paragraph already introduced the word VOLUME!.

The loudness of one single note, PNOTE or chord is raised with [>] and lowered with [v] (Executing these word multiple times will increase the effect). By using \Forte \Pianissimo etc. the loudness of the next note or chord is set in an absolute sense.

And then we have the important articulation issue. The available articulation commands are shown in Table 6. Articulation means sounding a note for only a given percentage of its formal duration.

 Table 6. Articulation commands available in MANX

	Legato		(8/8)	or L8
	Tenuto		(7/8)	or L7
	Portato		(6/8)	or L6
	Non-Legato	(5/8)	or L5
	Staccato	(2/8)	or L2
	Staccatissimo	(1/8)	or L1
	Non-standard names and possibilities are:
	L4		(4/8)
	L3		(3/8)
	L0		fixed time (see /l0) 
See also the words [.] and [-] which lower and raise the articulation index for the following note or PNOTE. Articulation is set to an absolute value for the following NOTE, PNOTE or chord with \L0 \L1 .. \L8. The words TRUE sustain keep all following notes in their sustain phase until FALSE sustain is executed. Articulation can be saved and restored with \ART and /ART respectively.

When the hardware allows it, a few 'technological enhancements' are possible. See Table 7 for a list.

  Table 7.  Hardware related expression commands.

	chorus	 	( u -- )  chorus effect (phasing)
	reverb		( u -- )  reverberation (hall)
	pan		( u -- )  move in stereo sound field
	pitchbend	( n -- )  'bend' the string i.e. change the pitch
	portamento	( F -- )  enable glissando's 
	portatime	( u -- )  set length of glissando
	sostenuto	( F -- )  enable sostenuto 
	reprogram	( u -- )  choose a different timbre
	vibrato-depth	( u -- )  set vibrato depth	
	vibrato-rate	( u -- )  set vibrato rate
	vibrato-delay	( u -- )  set vibrato delay
	tvf-cutoff	( u -- )  set voltage controlled filter cutoff freq.
	tvf-resonance	( u -- )  set voltage controlled filter resonance
	env-attack	( u -- )  set envelope attack (filter and amplitude)
	env-decay	( u -- )  set envelope decay (filter and amplitude)
	env-release	( u -- )  set envelope release (filter and amplitude)
The word reprogram ( u -- ) allows a choice out of over at least 150 different instruments or timbres to be made (see MIDIRW.DOC)

Tangentially related to articulation are the three words of the TIE class: tie- -tie- and -tie . These words keep only the specified note in its sustain phase. Consult the Glossary for their special behavior when { or {ARP is encountered.

5. Percussion

Normally percussion sounds are put in the Percussion PART. The three words bell-tree plok and plok2 can be used in any PART but still generate the correct events. This makes for clearer notation when percussion is infrequently used. However, having three words obviously limits the choice to only three instruments. Therefore we introduced the word BECOMES ( u1 "standard name" -- ), where u1 is the number left by executing one of the percussion instrument names from MIDIRW.FRT ( Brush-Swirl Brush-Slap Brush-Tap Concert-Cymbal1 Concert-Cymbal2 Timpani-F1 etcetera).

Instead of the slightly inelegant BECOMES one may define new words of the plok class using PNOTE ( u1 "name" -- ). This creates a new word name that, when executed, 'hits' the percussion instrument corresponding to the constant u1 (see above).

The word HIT ( u1 -- ), a basic component of PNOTE , is separately available and is useful for an occasional percussive slap here and there.

6. Parallel Constructs

To build parallel musical fragments, MANX supports the words {{ & and }}. See the Glossary. Note that these words do not work properly when executed interactively.

7. Embellishments

A number of embellishments were predefined. The actual execution of these constructs (taken from Bach's 'Kleine Praeludien und Fughetten' Edition Peters No 200) may not be to your liking. The embellishments are mordent ( "name" -- ) praller ( "name" -- ) /\shake ( "name" -- ) \/shake ( "name" -- ). Here name must be a note or PNOTE word.

8. Utilities

It is possible to have each MANX command print its stack effect and name before executing. This feature is switched with the words PRINTING-ON and PRINTING-OFF . It only works in mode 0 and 1.

With MCOMMENTS-ON one instructs MANX to generate bar numbers and put them in the MIDI output file. In this mode the word CMT is available. It is used to embed user comments in the output stream. These comments and bar numbers are printed to the terminal screen. This works in mode 0, 1 en 2. It is, however, a MANX specific feature and other sequencing software will ignore the strings.

The current metronome value (in quarter notes per minute) is printed when typing .MM .

The word .STAT prints information about MANX's state, e.g. MIDI status, song name, general song info, metronome, current part, current program ...

The word .WHO prints the network statistics, e.g. who is conductor, the serial port that is used, ensemble or solo.

The maximum number of bars allowed by the hardware (memory limitations) is returned with /bars .

To play a note not by its name but by its index, use PERFORM-NOTE ( u -- ). The index u is found by applying N? to a note or pnote.

N? ( "name" -- u ) inspects the note name and extracts the index u suitable for use with PERFORM-NOTE.

When using L0, or when the sound output is done with the metallophone network, the content of /l0 specifies the pulse width in milliseconds of all following notes (until another articulation command is found or force-metallo? is turned off).

9. File words

The word BUILD-MIDI ( "name" -- ) converts the MANX commands in the file name.SCO to a binary MIDI file name.MID . The generated .MID file is readable by other (non-Forth) programs, like, for instance, the Windows MediaPlayer.

10. Full Examples of MANX Use

This chapter gives examples of how to use MANX. We will do this by analyzing three of the *.SCO files supplied with the MANX package. The first example only uses the basic commands. The second example demonstrates everything that a typical user needs to enter scores of medium complexity. Finally, the third example points out how to combine ordinary Forth words with the MANX commands and data structures.

Example 1. ZIEP.SCO

When the command INCLUDE ziep.sco is entered, MANX interprets the following text (comments are preceded by the '\' {backslash} character or are enclosed between brackets, as is customary in Forth. It is allowed to mix Forth words and numbers with the MANX commands):
	100 /4 MM 	( set metronome to 100 quarter notes per minute)

	SCORE Ziep	( This will be the Forth name of the piece)

	\ Enter a non-printing comment which will be embedded in the MIDI file.

	INFO" Old Dutch traditional, using portamento"  

	Player0 PART	\ there will be only one player. Its notes start
			\ here and stop when '||' is encountered.

	| 3 /4 MEASURE  \ First bar. Set up for a 3/4 beat.
			Legato 			\ no pause between notes
			Mezzo-Forte 		\ Not too loud	
			Whistle reprogram	\ Play the slide whistle 
			50 pan  		\ sound comes from front stage
			50 portatime  		\ set a time for notes to slide
						\ to the next one (portamento)
			true portamento		\ enable portamento
			/2 rest  /8 d3 d3	\ the notes in bar 0
	|            	/4 g3 			\ bar 1
			[.] [>] g3  		\ the note g3 is played short
						\ (equivalent to L2), and 
						\ emphasized (30% louder).
			/8 g3 a3
	| 2 /4 MEASURE  /4 [.] [>] b3 g3	\ bar 2
	| 3 /4 MEASURE  /8 a3 a3  		\ bar 3
			[>] [.] a3 
			[.] a3  
			b3 a3
	|  		false portamento	\ bar 4. Turn portamento off.
			/4 [>] g3 /2 rest 
	||					\ This ends player0's part.
This file has a part for Player0 only, so if the current player is not Player0 nothing happens when you type ZIEP . You can find out the current player by entering .STAT . If the player is set wrong, type I-AM-PLAYER0 FORGET ziep INCLUDE ziep.sco. After this, entering ZIEP will play a very simple melody on your sound hardware.
One of the possible variations you will want to try is entering PRINTING-ON , then ZIEP. This echoes all events to the screen while playing, giving you a chance to debug things. PRINTING-OFF turns the echoing off again.

The command to convert ZIEP.SCO to a MIDI file with name ZIEP.MID is BUILD-MIDI ziep. In this case it doesn't matter what the current player is, all parts are converted automatically. The resultant binary file can be played back by entering PLAY-FULL ziep.mid. Optionally you can set the replay speed: 150 100 TO replay-speed plays the file 50% faster than the metronome value in the text ( 100 /4 MM ) specifies it. Instead of PRINTING-ON you must now use MPRINTING-ON to get a simultaneous listing of the events. An alternative is entering MCOMMENTS-ON , which will print the bars currently executed at the top of the screen, plus any comments you have put in the text using CMT (note that MCOMMENTS-ON must also be executed before you build the MIDI file). This display is useful for a complicated score where you suspect bars have been lost or misplaced when entering the text. For best results, the word "|" must be used for bars that contain DUPLICATE DUPLICATES BIS ENCORE or REDO statements.

Example 2. BART-113.SCO

The next example features two players (Player0 and Player1), so make sure the current player is set to the part you want to hear or analyze. Enter INCLUDE bart-113.sco to have MANX interpret the following text:
	126 /4 MM

	SCORE Bart-113

	INFO" BARTOK, Bulgarian Rhythm, Mikrokosmos 113. Transcription: Albert 
	      Nijhof, Oct 24, 93"

	Player0 PART

 	|	7 /8 measure  
		true sustain    \ notes are sustained as long as the instrument
				\ allows. When no instrument is set explicitly,
				\ it defaults to electric piano.
		whole rest	\ equivalent to  7 /8 rest
				\ Define a label with name m1
L: m1   |   	/8 rest bes2  rest gis2	  rest bes2 gis2
	| m1 redo		\ the code in this bar re-executes the code of
				\ the bar labelled m1 .
L: m3	| m1 redo
L: m4	| 	/8 a2 d2 gis2 d2 a2 d2 gis2
	| 39 duplicates		\ re-execute the code of the previous bar (m4)
				\ 39 times.
	| m1 .. m3   bis	\ re-execute the bars between 
				\ m1 and m3 (inclusive)
	|	/4 rest  
		5 \8 tie- { a2 a3 }	\ play a two note chord. The tie-
					\ command acts on both notes and says
					\ that a note must be held in its 
					\ sustain phase.
	|	whole -tie- chord	\ equivalent to  7 /8 -tie- { a2 a3 }
					\ or  whole { -tie- a2 -tie- a3 } etc.
	|	5 \8  -tie  chord  	\ finally we may turn off the notes in
					\ the chord ( a2 and a3 )
		/4 rest  false sustain ||

	Player1 PART

	 |  	7 /8 measure whole rest  Acoustic-Guitar-(nylon) reprogram
L: m1	 |	/8 bes2 rest
        	   gis2 rest
	           bes2 /4 rest
	 | m1 redo
L: m3	 | m1 redo
L: m4	 |   	/4 rest e3 a3  /8 b3
	 |   	/4 a3 d4 a3 /8 e3
	 |   	/4 f3  
		5 \8 tie- d3	\ we create sustained note d3 ...	
	 |     	whole -tie- d3
	 |   	5 \8  -tie  d3  \ turn of the sustained d3
		/4 rest
	 |   	/4 a3 e4 dis4   /8 e4
	 |    	/4 f4 e4 cis4  /8 g3
	 |    	/4 a3  5 \8 tie- c4 
	 |	whole -tie- c4
	 |    	5 \8  -tie  c4   /4 rest
	 |    	/4 g4 f4 e4  /8 f4
	 |    	/4 e4 b3 cis4  /8 bes3
	 |    	/4 c4 5  \8 tie- g3 
	 |	whole -tie- g3
	 |    	5 \8  -tie  g3  /4 rest

	 |    	/4 f3 e3 a3  /8 b3
	 |    	/4 cis4 b3 a3  /8 e3
	 |    	/4 f3  5 \8 tie- d3
	 |	whole -tie- d3
L: m23	 |  	5 \8  -tie  d3  /4 rest

	 | m4 .. m23  bis
	 | m1 .. m3   bis

	 |    	/4 { cis3 cis4 } rest rest  /8 rest
	 |    	whole rest
	 |    	duplicate	\ equivalent to  whole rest , re-execute the
				\ previous bar.
This file has two parts, but MANX will only play one PART at the time. A typical command sequence to hear the parts after one another is:

 I-am-Player0  INCLUDE bart-113.sco  bart-113
 FORGET bart-113
 I-am-Player1  INCLUDE bart-113.sco  bart-113
The use of labels in the text makes it possible to hear a specific bar played. You can enter m4 REDO to hear just bar m4, or m4 .. m23 BIS to hear the bars between m4 and m23 inclusive. When you start experimenting in this way you will notice that MANX stops playing as soon as you touch just any key. Also note that replaying just a small part of the score may leave you with an instrument playing a set of tied notes at full blast. The word SILENCE will kill these notes instantly.

Although labels are used for bars to be REDOne, a bar that does not have a label can be specified by putting its internal index number on the data stack. Bars are numbered sequentially, starting at bar 0. For the above example m4 REDO can also be expressed as 4 REDO.

To hear both parts simultaneously you are supposed to use BUILD-MIDI bart-113 .

Example 3. CHORDS.SCO

In this example Forth words and MANX commands are freely mixed. The thing to realize is that MANX commands are just Forth words, and 'bars' are :NONAME colon definitions that are automatically put in a list by the PART , SCORE and | words. This means that any MANX word (e.g. c3 ) or word combination (what you would consider a bar) can be put into a Forth colon definition. These Forth words can then be used in a bar definition again, together with any Forth conditional or looping construct.

Please watch out for words marked IMMEDIATE in the glossary: BIS ENCORE REDO SET BECOMES N? PART | || DUPLICATE DUPLICATES L: { {ARP. Of this set you would not normally want to compile BIS ENCORE REDO PART | || DUPLICATE DUPLICATES and L:, but BECOMES N? { and {ARP are very useful at times.


\ Define a few chords.

: `A		{ a3 cis4 e4 } ;
: `Am		{ a3 c4 e4 } ;
: `A7		{ a3 cis4 e4 g4 } ;
: `Am7		{ a3 c4 e4 g4 } ;
: `AM7		{ a3 e3 gis3 cis4 } ;
: `Adim7	{ fis3 a3 c4 dis4 } ;

: `B		{ fis3 b3 dis4 } ;
: `Bm		{ fis3 b3 d4 } ;
: `B7		{ fis3 a3 b3 dis4 } ;
: `Bm7		{ fis3 a3 b3 d4 } ;
: `BM7		{ b3 fis3 ais3 dis4 } ;
: `Bdim7	{ f3 gis3 b3 d4 } ;

: `C		{ e3 g3 c4 } ;
: `Cm		{ es3 g3 c4 } ;
: `C7		{ e3 g3 bes3 c4 } ;
: `Cm7		{ es3 g3 bes3 c4 } ;
: `CM7		{ c3 e3 g3 b3 } ;
: `Cdim7	{ dis3 fis3 a3 c4 } ;

: `D		{ fis3 a3 d4 } ;
: `Dm		{ f3 a3 d4 } ;
: `D7		{ fis3 a3 c4 d4 } ;
: `Dm7		{ f3 a3 c4 d4 } ;
: `DM7		{ d3 fis3 a3 cis4 } ;
: `Ddim7	{ f3 gis3 b3 d4 } ;

: `E		{ gis3 b3 e4 } ;
: `Em		{ g3 b3 e4 } ;
: `E7		{ gis3 b3 d4 e4 } ;
: `Em7		{ g3 b3 d4 e4 } ;
: `EM7		{ e3 gis3 b3 dis4 } ;
: `Edim7	{ g3 bes3 cis4 e4 } ;

: `F		{ f3 a3 c4 } ; 
: `Fm		{ f3 as3 c4 } ; 
: `F7		{ f3 a3 c4 es4 } ; 
: `Fm7		{ f3 as3 c4 es4 } ; 
: `FM7		{ f3 a3 c4 e4 } ; 
: `Fdim7	{ f3 as3 b4 d4 } ; 

: `G		{ g3 b4 d4 } ;
: `Gm		{ g3 bes4 d4 } ;
: `G7		{ g3 b4 d4 f4 } ;
: `Gm7		{ g3 bes4 d4 f4 } ;
: `GM7		{ fis3 g3 b4 d4 } ;

: `Gdim7	{ g3 bes4 des4 e4 } ;

\ a defining word that build words that play a random chord in a certain key.
: :chord	CREATE 

:chord achord   ' `A , ' `Am , ' `A7 , ' `Am7 , ' `AM7 , ' `Adim7 ,
:chord bchord   ' `B , ' `Bm , ' `B7 , ' `Bm7 , ' `BM7 , ' `Bdim7 ,
:chord cchord   ' `C , ' `Cm , ' `C7 , ' `Cm7 , ' `CM7 , ' `Cdim7 ,
:chord dchord   ' `D , ' `Dm , ' `D7 , ' `Dm7 , ' `DM7 , ' `Ddim7 ,
:chord echord   ' `E , ' `Em , ' `E7 , ' `Em7 , ' `EM7 , ' `Edim7 ,
:chord fchord   ' `F , ' `Fm , ' `F7 , ' `Fm7 , ' `FM7 , ' `Fdim7 ,
:chord gchord   ' `G , ' `Gm , ' `G7 , ' `Gm7 , ' `GM7 , ' `Gdim7 ,

\ Play a random chord from a selection of 7 

: AnyChord	7 CHOOSE 
		  achord bchord cchord 
		  dchord echord fchord 
		  gchord ;

\ Choose a random position on the stereo sound stage
: ASpot		#100 CHOOSE pan ;

\ Choose a random reverberation level
: ADepth	#100 CHOOSE reverb ;

\ Play a random chord, in a random key, at a random position,
\ at a random distance from the listener.
: SomeChord	ASpot ADepth AnyChord ;

   #90 /4 MM   

   SCORE Chords  

   INFO" Random Cubed"

   Player0 PART
   |     4 /4 MEASURE WHOLE rest  Choir-Aahs reprogram  
	 Mezzo-piano -1 TO octave
L: m1
   |  	 /2  SomeChord  
	 ARPEGGIO  \ like CHORD , but arpeggiate the notes.
   |     7  DUPLICATES
   |	 Breath-Noise reprogram 
	 /32 32 0 DO SomeChord LOOP  \ Play 32 chords, length /32
	 BANK0 Marimba reprogram
L: m9
   |     /2  `C7  ARPEGGIO
   |     Voice-Oohs reprogram  m1 .. m9  BIS

   Player1 PART
   |     4 /4 MEASURE WHOLE rest  Pad-2-(warm) reprogram  50 pan  Forte
L: m1
   |  	 12 /4  10 DIMIN     \ start diminuendo, 'a little bit' over 3 bars
	 /8 8 0 DO `C7 LOOP  \ play 8 chords
   |     DUPLICATE 
   |     /8 8 0 DO `Em7 LOOP \ the diminuendo stops here
   |     Piano DUPLICATE     \ go to a known volume	
   |     12 /4 10 CRESC	     \ a crescendo over 3 bars.
	 /8 8 0 DO `Gdim7 LOOP
   |     /8 8 0 DO `GM7 LOOP
   |     /8 8 0 DO `Gdim7 LOOP 
   |     Forte DUPLICATE     \ ... known volume	
   |	 Helicopter reprogram /1 SomeChord  
	 Choir-Aahs Piano reprogram
L: m9
   |     /4 4 0 DO `Cdim7 LOOP
   | m1 .. m9  BIS


Instrument Drivers

MIDIRW comes with ready-to-use drivers for the PC-speaker, for a metallophone, and for any machine that understands the MIDI-protocol -- effectively all modern sound cards and GM synthesizers. However, even if your hardware is special, it is still possible to use it with some minor programming. This section shows how to write driver programs (or words) that interface the routines in MIDIRW.FRT to an actual instrument.

First of all, write a driver file. Choose one of the files PCSPEAKER, BRASS, ALUMINIUM or SYNTH as a template. Your new driver file must contain the set of 8 words in the table below. The term "event" is defined in DOC ENDDOC blocks in MIDIRW.FRT. Briefly, an event is a 32-bit word containing all information your driver needs to fullfil MIDIRW's requests:

Event bits:  31..24  23..16    15..8     7..0    
Meaning:       0      
The channel# addresses one of 16 sub-units. This field can be ignored although you should be aware of the fact that MIDIRW thinks that it can talk to a percussion unit on channel #pch (9 or 15 is standard MIDI practice).

The velocity is a 7-bit number that is commonly interpreted as the loudness with which the instrument sounds.

The note# addresses one of 128 notes on the wanted chan# (C-2 to C9).

The protocol is loosely based on the MIDI specification, so you can read up on that subject if the documentation in MIDIRW.FRT is not sufficient.

 Table 8.   MIDI base-level implementation words in driver files.  

 :NOTE-ON 	( event -- )	Start making the sound (attack phase). Note
				that a special :NOTE-ON request can be made
				that actually means :NOTE-OFF , and that
				a :NOTE-ON can specify one of sixteen 
				sub-units, one of them being a percussion 

 :NOTE-OFF 	( event -- )	Shut off the sound (release phase).

 :CONTROL 	( event -- )	Respond to requests to change a parameter of 
				the current sound (vibrato, reverb, volume 
				etc.) It is acceptable to just do a DROP and 

 :REPROGRAM 	( event -- )	Respond to requests to change the current
				timbre (e.g. acoustic piano, guitar etc.) It 
				is acceptable to just do a DROP and return.

 :PITCHBEND 	( event -- )	Change the frequency of the currently sounding 
				note. It is acceptable to just do a DROP and 

 :CAFTERTOUCH 	( event -- )	Respond to requests to change the volume 
				of the indicated sub-unit. It is acceptable to 
				just do a DROP and return.

 :PAFTERTOUCH	( event -- )	Respond to requests to change the volume of
				the indicated note on the indicated sub-unit.
				It is acceptable to just do a DROP and return.

 :SYSEX		( event -- )	Respond to a sequencer specific request, here
				a special MANX command to set non-registered
				parameter numbers in a synth.
				It is acceptable to just do a DROP and return. 

 :LOUDNESS	( event -- )	Respond to requests to change the general 
				volume of the indicated sub-unit. It is 
				acceptable to just do a DROP and return, 
 				however, do not throw away the '0' message: 
				in this case the indicated sub-unit should 
				be shut off and re-initialized.
After writing the driver code you revector the deferred word SET-LOUDNESS to a meaningful routine (acceptable is ' :LOUDNESS IS SET-LOUDNESS ) and define two words that inform MIDIRW about the driver's capabilities

 drivermax#n	This is a CONSTANT or VALUE that tells MIDIRW how many notes
		your instrument can play simultaneously.

 devoffsb	This is a VALUE that contains the offset between the note
		MIDIRW asks for (say c2) and the actual note you want to 
		hear (say d3). This offset is 0 for a full-featured 
		instrument, but	sometimes you will want to shift the notes 
		MIDIRW is sending to a range your instrument can handle.
		Install devoffsb in devoffs with the following Forth 
		sequence:  'OF devoffsb IS devoffs .
That is all programming that is required. Next make the new driver available to MIDIRW by writing a configuration file (look at SPEAKER.CFG), and by making sure there is a NEEDS -yourdriver in MIDIRW.FRT . Copy yourdriver.CFG to CONFIG.FRT and load MIDIRW.FRT or MANX.FRT.

Appendix 1 The Metallophone Network

A standard PC can have up to four parallel interface adapters, and so is able to drive at least four electromechanical instruments simultaneously, using an extension of the protocol in RELAYS.FRT . If the network grows any bigger than that, multiple PC's must be used and you will experience gross timing problems because a central clock is lacking.

Synchronizing, the easy way

A simple solution to the above problem is to connect all PC's, using their serial ports, and have a Conductor machine broadcast 'start of bar' messages. The player machines send back a notification and continue with the next bar. The conductor machine waits until all notifications are in, then also continues. In this setup the conductor has enough time to drive one or more metallophones itself.

Possible problems with this scheme are that the synchronization points are too few and timing gets 'peristaltic'. Also, the danger exists that complete bars ar missed by some of the machines.

The scheme was tried out and it actually works well in practice. However, we do not recommend it for any serious work. If your application is critical, extend MANX to be able to receive time-stamped MIDI clock messages inside its TIMER words. The clock messages should be broadcasted and received by interrupt driven serial port routines.

Synchronizing Hooks

When using the simple setup described above, MANX can only be used in mode 0 and 1, meaning that MIDI files can not be replayed over the network. When replaying SCORE's in mode 1 the Forth interpreter executes the deferred word SYNC at the start of each bar. The config.frt file can be used to appoint one conductor machine ( TRUE =: I'm-conductor ). The SYNC vector for this machine will then be different (i.e broadcast a message) from the SYNC code of the normal players (i.e. receive a message).

To get all of this to work, connect the machines using a serial cable. At present only two machines are supported, so a standard cable is used. Edit the CONFIG.FRT files on the machines so that one of them is Conductor. ( TRUE =: I'm-Conductor and FALSE =: I'm-Conductor ). Make sure that the VALUE com# is set to the correct value for the serial port that you are about to use. Also make sure that both machines initialize their serial ports with INIT-SR (DEFS.FRT) after they have loaded MANX.FRT . When you enter ENSEMBLE the two machines will synchronize before playing a bar from their PART's. SOLO reverts back to the old unsynchronized situation. In ENSEMBLE mode you may press any key to break a possible deadlock.

That is all there is to it.

Appendix 2 Installing MANX

Installing MANX is possible on a machine that can run iForth 1.x. This means that MS-DOS, Windows NT and Linux platforms are supported.

iForth needs a '386+387 pair, or a '486 or higher. iForth for MS-DOS runs in protected mode. The used DOS-extender, GO32, is not very smart and strange errors or very slow operation will be experienced when the amount of memory is less than two Megabytes (we recommend 4 Mbytes for DOS and 8 MBytes for Windows).

Please install the MANX program files in a separate directory (suggested is /dfwforth/examples/manx) and the *.sco and *.mid files in a sub-directory thereof (suggested is /dfwforth/examples/manx/music).

Depending on the sound hardware you have available, one of the *.cfg files is renamed to CONFIG.FRT . What works on any machine is using the PC-speaker for output by entering the following command on the DOS command line: COPY pcspeaker.cfg config.frt.

The intended use of MANX is to drive a full GM synthesizer box through a MPU-401 compatible interface: COPY synth.cfg config.frt. In this case the file synth.frt may need some editing to set up the correct IRQ and port numbers. MANX under Linux bypasses the device driver and talks to the interface directly. Windows MANX just uses WIN32 calls.

Using MANX with a simple soundcard has its limitations. Sometimes DOS MIDI drivers for these cards are not available, forcing you to use Windows with its MIDI-mapper software. But even in that case interactive use of the sound hardware is possible, you don't need to generate a *.MID file first.