LMUSe Documentation

LMUSe version 0.7a
10/25/98
david sharp 
dsharp@interport.net
----------------------------------------------------------------

c o n t e n t s

L-Systems (general) 
	Context Sensitivity and Stochastic Rules 
Symbol Alphabet 
	Commands specific to music
	Direction commands 
	Movement / Play commands 
	State stack commands 
	Increment and Decrement commands
	Colors and intrument timbre commands
Rules Files Format
Menus
	Production menu 
	Map 
	Edit Menu 
	Mutate menu
        Options menu
Map Files
Play Screen
Scales 
Rules Files Compatibility 
Command Line parameters
Troubles 
Credits 
----------------------------------------------------------------
L-Systems

L-systems were invented by Aristid Lindenmayer in 1968 to model the development of living organisms by recursively applying a set of transformation rules to a simple initial string of symbols and interpreting the resulting (usually more complex) string of symbols as structure elements of the organsism. L-systems also provide a concise grammar for generating classic fractals like von Koch snowflakes, dragon curves and space filling curves, as well as for modeling organic growth.

An L-system starts in generation 0 with a simple string of symbols, and for each subsequent generation, symbols are replaced by new symbols or strings of symbols according to a set of rules. The idea is easiest to see by example. Say our starting string, (called the 'axiom'), is just 

	A 

The replacement rules show how each symbol in the current generation should be replaced. Two simple rules (for example) are 

	A=B 
	B=BA

According to the first rule, every 'A' in the current generation should be replaced by a 'B', and each 'B' in the current generation will be replaced with 'BA' in the next generation. 

	generation 0: A (the axiom) 
	generation 1: B (the A was replaced with B ) 
	generation 2: BA (the B of generation 1 was replaced with BA) 
	generation 3: BAB (the B of gen 2 replaced with BA and the A replaced with B)
	generation 4: BABBA 

Note how the replacements for each generation occur in 'parallel'. We will call the number of generations the "recursion level". When the symbols are interpreted as graphics commands, reading from left to right, the resulting pictures can get very complex. In most L-system implementations the symbol 'F' is interpreted as a command to "draw a line". Because of the recursive way the production string is made, L-systems are a concise way to generate the 'self-similar' nature of fractals. 

The purpose of LMUSe is to interpret the resulting symbol strings as musical directions. For example, 'F' is interpreted as "play the note". See 'Symbols'. LMUSe starts with a 'rule file' which contains an axiom string, a set of replacement rules, a default recursion level, and another parameter the 'angle' (a number of the specially interpreted symbols have to do with changing the drawing turtle's direction and orientation).

	#=== Sample Rules file ==== 
	5 #recursion level 
	10 #angle 
	AB #axiom 
	A=+FB # first rule 
	B=AF # second rule 
	#=========================== 

In LMUSe, '#' is a special 'comment' symbol. LMUSe ignores everything on a line after a '#'. The rules are applied to the axiom to make a 'production string' (the first generation). The rules are then applied to that production string in turn, making a new production string (the second generation), which is run through the rules, the process repeated "recursion level" number of times. The result at the end is just called the "production string".

By itself, the production string is just a string of symbols. The production string is then 'interpreted'. That is, the symbols are mapped to drawing and/or music playing commands. In LMUSe, the musical commands are in the form of MIDI messages. 
----------------------------------------------------
Context Sensitivity and Stochastic Rules

Rules like A=AB, and X=FB^&F, are called 'context-free' because the symbol to be replaced (on the left of the '=') is replaced by the right side of the '=' no matter what other symbols happen to surround the symbol to be replaced. 'Context-sensitive' rules are rules whose application does depend on the surrounding symbols. In LMUSE, context-sensitivity of a rule is denoted with '>' or '<' after the symbol to be replaced and before the '='.

For examples: 
	A>B=AB     # "if B is to the immediate right of A replace the A with AB". 
	A<F=FFAB # "if F is to the left of A, replace the A with FFAB" 

In LMUSe rules, the symbol to be replaced is always the first symbol in the rule's line. If the above pair of rules were in the same rules file and both conditions were true, (for example if the production contained the sequence "FAB") only the first rule would be actually applied. This is because once a rule is applied to a symbol, all following rules for that symbol are ignored. Also, "A is to the left of B" is True if all that separates A and B is a number or a number in parentheses, or, of course, if A is directly adjacent to B.

To combine both '<', and '>' in a single rule condition, the two conditions must be in that order:

                   A<B>C=X 

would only match BAC and replace the A with X (BAC becomes BXC). 

LMUSe also implements 'stochastic rules'. 

	A(.5)=BBA 

will replace A with BBA only 50% of the time. The pair of rules: 

	A(.5)=BBA 
	A=ABA 

will replace A with BBA 50% of the time, otherwise (the other 50% of the time) A is replaced with AAB. The order of these two rules is important. Reversing them: 

	A=ABA 
	A(.5)=BBA 

will always replace A with ABA. This is because the first (A=ABA) is not a stochastic rule (no probability in  parentheses) and since it comes first, it is applied. Once a rule is applied to a symbol, the rest of the rules for  that symbol are skipped, so the second line has no effect at all. 

To have three stochastic rules each with a probability of 1/3, you would write: 

	A(.33)=BBA 
	A(.5)=ABA 
	A=BABB 

The way it works is, the probability in parentheses is the probability that the rule will be applied if LMUSe gets to that rule, and LMUSe stops looking for a rule to apply once it has applied one. That is, there is a .33 probability that the first rule will be applied. If it isn't applied (probability .67), then the second rule is attempted. Half the time the second rule is attempted, it is applied. That is 1/2 of .67 =.335 probability that the second rule will be applied. And finally, if and only if neither of the first two are applied, the last rule is applied. Again, once a rule is applied to a symbol, following rules are skipped. 

To combine a stochastic condition with a context-sensitive condition, the stochastic condition must come at the end: 
	F<A>B(.5)=FF

Stochastic rules have their random effect as the production string is being built. Once the production string is done you would have to do another 'Make' to see any difference due to the randomness.

LMUSe transformation rules can contain another type of randomness. The '~' (tilde) changes, randomly, the current state's direction. And '~(x)' changes the direction randomly up to a maximum of x degrees. This random change occurs at the time of interpretation and will give (probably) different results every time the production string is interpreted. To avoid differences between interpretations, you can do 'ReMap' instead of 'Remake'.

---------------------------------------------------------------
The State and Stack

In interpreting the production string, the string is treated as sequence of commands to a 'turtle'. These commands can alter the turtle's state and/or cause the turtle to draw or make sound.

In LMUSe, the turtle's state consists of the turtle's position (x, y, and z coordinates), a 3d vector telling it what direction it is facing ('forward'), another vector telling what direction the top of its head is pointing ('up'), and a vector telling what direction is to the turtle's left. The state also holds the current 'length' and 'thickness', color or instrument timbre, and the size of the basic turning angle. The state also holds the map the turtle is using to convert its current state into pitches, durations, and volumes. In addition, the state holds what 'time' it is (when the notes it is making are to be played), and how far to transpose pitches.

Each of these components of the turtle's state can change and 'develop' as the production string is interpreted.

There is only one turtle, so in order for it to make branching structures, or polyphonic musical lines, it needs some sort of memory of where it has been so that it can go back to certain points in its development to pick up where it left off.

The turtle's state stack acts like the turtle's memory. A command which tells the turtle to put its state onto the stack is called a 'push', and a command which tells the turtle to retrieve its old state from the stack is called a 'pop'. When a state is 'pushed' it is always placed on 'top' of the stack, and when the turtle does a 'pop' it always gets its new state off the top of the stack ('last in, first out').  The symbol '{' is used to push the turtle's state and time and the accompanying 'pop state and time' symbol is '}'.

To push the state of the turtle, but not time (that is, so that a 'pop' will send the turtle back to where it was, but not back in time), you use '[', and naturally the accompanying pop symbol is ']'.

It is often convenient to just push and pop the time (to allow the turtle to continue developing, but parallel in time to its previous development). The LMUSe symbols for pushing and popping just the time are '\' (push) and '/' (pop).


---------------------------------------------------------------
The LMUSe Symbol Alphabet
(Most of this list is from Laurens Lapre's lparser.txt)

Commands specific to music 
-------------------------------------
t(x)  transpose up (+x) or down (-x) by x semitones 
t     transpose 0
d(x)  multiply note durations by x
d     multiply note durations by 1.0
      (cancels d(x))
v(x)  multiply note velocities by x 
v     multiply note velocities by 1.0
      (cancels v(x))
*(x)  write to MIDI channel x
*     write to MIDI channel 1
m(x)  use map number x for interpreting
--------
(also see the T(x), D(x), and V(x) stack commands)


Turtle Direction commands
-------------------------
+     turn left around up vector 
+(x)  turn x degrees left around up vector 
-     turn right around up vector 
-(x)  turn x degrees right around up vector 
&     pitch down around left vector 
&(x)  pitch x degrees down around left vector 
^     pitch up around left vector 
^(x)  pitch x degrees up around left vector 
<     roll counter clockwise
      around forward vector
<(x)  roll x degrees left
      around forward vector
>     roll clockwise around forward vector 
>(x)  roll x degrees clockwise
      around forward vector
|     turn 180 degrees around up vector 
%     roll 180 degrees around forward vector 
$     roll until horizontal 
~     turn/pitch/roll in a random direction 
~(x)  turn/pitch/roll in random direction to a
      maximum of x degrees

Movement / Play commands
------------------------
F     draw full length forward 
      play 
F(x)  draw x length forward 
      play
Z     draw half length forward 
      play 
Z(x)  draw x length forward 
      play
f     move forward full length, draw within {} 
      play within {}, otherwise rest 
f(x)  move forward x, draw within {} 
      play within {}, otherwise rest 
z     move forward half length, draw if within {}
      play within {}, otherwise rest 
z(x)  move forward x, draw if within {} 
      play within {}, otherwise rest 
g     move forward full length 
      rest 
g(x)  move forward x 
      rest 
.     don't move

State stack commands
--------------------
[     push current state but not event time 
]     pop current state but not event time 
{     push current state and time 
{x    push current state and time,
      writing to MIDI channel x
}     pop current state and time
\     push event time
\x    push event time,
      writing to MIDI channel x
/     pop event time

T(x)  ** push pitch transposition by x onto transpose
      stack 
T     ** pop transpose amount from transpose stack. 
D(x)  ** push duration multiplier x onto the duration
      multiplier stack 
D     ** pop duration multiplier from duration
      multiplier stack 
V(x)  ** push velocity multiplier x onto the velocity
      multiplier stack 
V     ** pop velocity multiplier from velocity
      multiplier stack

** To use the transpose, and duration and velocity
   multiplier stacks they must be enabled from the
   Map dialog)

Increment/Decrement commands
----------------------------
"     increment length (times 1.1) 
'     decrement length (times 1/1.1) 
"(x)  multiply length with x
'(x)  multiply length with x
;     increment angle (times 1.1) 
:     decrement angle (times 1/1.1)
:(x)  multiply angle with x
;(x)  multiply angle with x
?     increment thickness (times 1.4) 
!     decrement thickness (times 1/1.4)
?(x)  multiply thickness with x
!(x)  multiply thickness with x

Color / timbre-instrument commands
----------------------------------
c     increment color index 
      increments instrument program number 
c(x)  set color index to x 
      sets instrument program number to x 



@     end of rules (optional)

---------------------------------------------------------------------------------------------
Rule File Format
---------------------------------------------------------------------------------------------
The format for rule files follows the format of Lparser. Each rule file
must be organized in this order, line by line:

	recursion level
	angle (in degrees)
	thickness (optional in LMUSe, required by Lparser)
	axiom
	transformation rule 1
	transformation rule 2
 	more rules, one to a line
	...
        @ (end of rules marker, optional in LMUSe, required by Lparser)

In addition, the file can contain comments.  Anything after "#" on a line
is ignored by LMUSe.

An example:

	# this whole line is ignored
	4		# default recursion level
	25		# basic angle of 25 degrees
	50		# thickness is 50% of length
	A      		# the axiom 
	A=+B^FA	# rule 1
	B=BBt(12)F	# rule 2
	@		# end


---------------------------------------------------------------------------------------------
Menus
---------------------------------------------------------------------------------------------
Production menu
-------------------------
(Also see Help menu / Process Overview) Making the production string and interpreting can take a long time, depending on recursion level and how long the production string gets. You can cancel/abort a `Make' or `Interpret' with the ESC key or clicking the right mouse button. Depending on how far the interpretation gets, you may have enough to play.
From the production screen, you can save the drawing to a PCX file by hitting `CTRL-d'.
Also, from the production screen or the play screen, you can do a `screen dump' to a PCX file by hitting `CTRL-p'.

* Load, Make, and Interpret
Gets the name of the rule file to use, and makes the production string. Then it goes ahead and interprets the string and plays the result. Use this to load a file and make music with least fuss. 

* Load Rules
Gets the name of a rule file and loads the rules into memory. (Doesn't make a production)

* Make Production 
Makes the production string from already loaded axiom and rules. (Doesn't interpret or play it).
Pressing ESC or clicking the right mouse button interrupts and aborts making the production string.

* Interpret Production 
Interprets the production string. You are asked how you want the production string interpreted. That is, what parameter should be mapped to pitch, what maps to note durations and note volume.
Pressing ESC or clicking the right mouse button aborts the interpretting.

* Remake and Interpret 
Makes and interprets the production string using the already loaded rules. Remake and Interpret also recalculates the necessary screen dimensions and state limits. Reinterpret(Remap) (see below) does not and so it is certainly safer to use Remake and Interpret, although it is more time consuming.
Pressing ESC or clicking the right mouse button aborts/cancels the process. 

* Reinterpet (Remap) 
Reinterpret the already made production string, going through the mapping process anew. Note that if the rule file contains stochastic rules, you will need to Remake the production string to get different results from rules's stochastic nature. Remap will just reinterpret the production.
On the other hand, certain symbols, like `~', yield stochastic results during interpretation. Pressing ESC aborts the remapping.

* Play
Go to the 'Play' screen to hear your interpreted production

* Save Rule File As
Save the current transformation rules as a rules file, including current recursion level and basic angle

If the rules were originally loaded from disk, be aware that 'Save Rules' does not keep comments you may have in the original file. To keep the original file, you will have to remember to save the rules with a modified name so the original file isn't overwritten.

* Get Production 
Read in a previously saved production string from disk. Since this production string is already `made', the only Production Menu opotions that make sense to use on it are `Interpret' or `Reinterpret/Remap'. (`Make' will make a new production string from whatever rules are currently in use which may have nothing to do with the production string you have loaded from disk. In this case the production string is overwritten and will no longer be in memory). When a production string is saved, the map parameters and the rule file angle are not saved, so when you `Get' a production, you will have to either remember these or supply new ones (or use the defaults)

* View/Save Production 
Look at the current production string. Option to save the production string (as *.out). 

* Save MIDI 
Saves your music as a (SMF format 1, multitrack) MIDI file. MIDI files are widely supportedby sequencing programs, sound cards, and web browsers on nearly every type of computer. There are also utilities for converting MIDI files into CSound scores and other formats

* Load Map
Gets parameters (map, scale, etc) from a previously saved map file.

* Save Map
Save parameters (map, scale, etc) to a map file.

* Play a MIDI file
Load and play a previously created MIDI file. 

* Stop MIDI - Ctrl-s
Stops the playing of a MIDI file.

* DOS shell
Shells to DOS command prompt

* Quit 
Quits LMUSe

-------------------------------------
Map menu
-------------------------------------
* Map 
Opens the map dialog. For the most part, this menu item is unnecessary since you are automatically presented with the map dialog on every Interpret. Click on the `Pitch' box with the mouse and drag a line to the parameter you want to dictate the pitches to be played. Similarly for `Durations' and `Volume'. LMUSe keeps track of the x, y, and z coordinates of an interpreted production. At all times the interpretation has three directions: forward (where the line is headed), up, and left. These are unit vectors each with x, y, and z components. The difference between `state length' and `draw length' is that the `state length' only changes with the length incrementing and decrementing commands (see Symbols under Help). The `draw length' comes from the actual length being drawn (or not drawn) on the screen. The draw length is affected by the difference between F and F(5) for example, or the difference between F and Z.
(see Symbols). 

The map(s) determine how the L-system production string (the list of symbols resulting from the recursive rewriting of the axiom) is interpreted as notes to be played. The production string itself can contain directions as to which map should be used (the m(x) symbol; see Help/Symbols).

You can load a previously saved map with the 'Load Map' button. (See 'Map Files' below). If the map file does not contain a mapnumber, the map will be loaded into the currently viewed map.

In the Map dialog, the fields are all part of the map (except the basic angle) and will be saved as part of the map file (except the basic angle).

'Load INI file' gets parameters (map, scale, etc) from a previously saved INI file.

Use the three "spread" sliders to increase the interpreted range of the parameters. For example, by making the "pitch spread" greater than 1.00, the mapped ptiches will be spread out further from middle c. A pitch spread less than 1.00 causes the mapped pitches to be squeezed closer to middle c. Basically, increasing the "spread" makes changes in pitch, duration, and volume more dramatic.
A negative value for the spread `inverts' the map. For example, when the duration spread is positive and duration is mapped to `draw length', longer lines make for longer note durations, but if a negative value is chosen for the duration spread, longer lines will yield shorter notes.

The "Scale" button is for choosing a musical scale into which the generated notes are "forced".
How the notes are forced into a scale is determined with the scale function button. (see Help/Scales)

Multiply durations slider is for stretching or compressing all musical event times. Multiplying by a number greater than 1.0 stretches out the notes, while multiplying durations by a number less than 1.0 compresses all the notes. Similar to changing tempo.

"Use Transpose stack" enables the "T(x) ... T" transpose stack.
"Factor stacks" enables the "D(x) ... D" and "V(x) ... V" duration and velocity multiplier stacks.
If you aren't using these extra stack constructs in a set of transformation rules, it is safest to turn this off (unchecked).

"Load a Map" gets parameters (map, scale, etc) from a previously saved map file.

-------------------------------------
Edit Menu 
------------------------------------
* Edit Rules File
Spawns an external editor that you have picked. If there is a currently loaded rule file, the name of the rule file is passed to the editor as a command line parameter, so that you can edit that file. When you quit the editor, you should be returned to LMUSe and the rule file is reloaded from disk. If, while you are using the editor, you change files to edit one other than the one currently loaded into LMUSe and you want to run that other file, you will have to load
the other file explicitly. LMUSe has no idea of what you are actually doing in the editor.

*Edit Memory Rules
Writes the rules from memory to a temporary file, then spawns an external editor to edit the temporary file.

* Pick editor
LMUSe does not contain an editor of its own. To use the Edit function, you must specify an external DOS editor, hopefully one that accepts filenames as a command line parameter. (And don't specify a Windows editor, like `Write' or `WinWord', etc). 

-------------------------------------
Mutate Menu 
-------------------------------------
* Mutate CTRL-m 
Makes a random change/mutation to the currently loaded rules. These mutations include things like appending one replacement string to another, changing directions in a rule, etc. Hitting `Mutate' once may have no effect on the production or it may have a devastating effect. It is, after all, random. It is common, after mutating to try and make a production string only to have LMUSe tell you it ran out of string space. Also, on occasion interpreting mutated rules leads to some arithmetic exception which I have not succeeded in tracking down. "Mutate" just mutates; it doesn't make a new production string. To go ahead and make a new production string and interpret it, use "Mutate, Remake/Interpret".
There is only one set of rules in memory at any one time. To retrieve the original (before mutations) rules, use "Production/Make and Interpret" to reload the original rule file. 

* Mutate & Remake/Interpret 
Does a mutation just like Mutate, but then makes a production string using the mutated rules, then interprets the new string. If you want to make, say, 5 mutations at once, hit "Mutate" 4 times (equivalently hit CTRL-m 4 times), then the last time use "Mutate & Remake/Interpret"

* Save Mutated Rules 
Saves the mutated version of the transformation rules as a rule file.
The default extension for these `mutated rule files' is `.lm' to help keep track of which is the original rule file and which is the mutated version. 

-------------------------------------
Options Menu
-------------------------------------

* Sound
Turn off/on sound output.

* Draw
Turn off/on drawing the graphical L-system. The drawing mostly just shows how the MIDI interpretation is progressing. Turning off drawing has a noticeable effect speeding up the interpretation step.

* Autoplay
Turn off/on automatically playing the interpretation when it is done. (after "Load, Make, and Interpret", "Interpret", "Remake", and "Remap")

* Write info into MIDI file
Toggles writing certain LMUSe information (the rule file name, map file name, mutations, etc) into a text field in saved MIDI files. In some sequencers this field is visible as the name of track 0.

*View
Choose the viewing plane for the drawing, and the size of the drawing. These have no effect on the musical interpretation.

* Maximum Production String Size
Allows you to change the amount of memory allocated for the production strings. On occasion, a production can run out of space. In this case, LMUSe aborts the production and tells you that it ran out of production string space. The 'Maximum Production String Size' is how many megabytes are allocated for the production string. The default is 2 Megabytes, but can be anything from 1 to 99 Megabytes.

=================================================
Map Files
---------------
A 'map' file is a file that contains the map parameters (basically, the parameters you choose in the map dialog).
The format of these files is a list of "parameter=value" statements. The hash ('#') is used as a comment starter (everything on a line after a hash symbol is ignored).
An example file is LMUSe.INI:
# LMUSe v0.7a map file LMUSE.INI
# Fri Oct 16 01:12:27 1998
# Current rulefile: (none) 
# Everything to the right of '#' on a line is ignored.
# Each map line is of the form 'parameter=value'.
# Including any of these parameter fields is optional.
# Letter cases in map files are ignored.

# tempo in beats per minute
tempo=120

# transposestack is a special stack for transposing the generated
# pitches. (L-system symbols T(x) ... T ).
# transposestack=1 enables this stack.
transposestack=0

# factorstacks are special stacks for holding duration and volume
# multipliers. (L-system symbols D(x) ... D , and V(x) ... V ).
# factorstacks=1 enables these stacks.
factorstacks=0

# randomseed is an (unsigned) integer
# To actually use this seed you need to
# uncheck 'Random Seed' in the dialog presented
# when doing a 'Make' or 'Remake'
randomseed=220

# writeparameters is a flag (=0 or 1) to disable/enable
# writing text information into saved midi files. Default=1
writeparameters=1

# mapnumber tells which map (0 thru 9) the following
# (up to the next mapnumber statement) are supposed to go
# into when the file is loaded. mapnumber statements are
# necessary to include several maps in a single map file
mapnumber=0

# pitch, duration, and volume of notes are each determined by
# any one of the following L-system variables:
# x          - the x coordinate of the turtle's position
# y          - the y coordinate of the turtle's position
# z          - the z coordinate of the turtle's position
# forwardx   - (or 'fx') the x component of the turtle's forward direction
# forwardy   - (or 'fy') the y component of the turtle's forward direction
# forwardz   - (or 'fz') the z component of the turtle's forward direction
# leftx      - (or 'lx') the x component of the turtle's 'left' orientation
# lefty      - (or 'ly') the y component of the turtle's 'left' orientation
# leftz      - (or 'lz') the z component of the turtle's 'left' orientation
# upx        - the x component of the turtle's 'up' orientation
# upy        - the y component of the turtle's 'up' orientation
# upz        - the z component of the turtle's 'up' orientation
# length     - (or 'statelength') the state length of the L-system
# drawlength - the 'draw length' (affected by temporary length modifiers)
# thickness  - the Lparser line thickness
pitch=x
duration=drawlength
volume=forwardx

# pspread, dspread, and vspread are magnifiers for the influence
# of the pitch, duration and volume parameters on the notes generated.
# Recommended to stay in interval -4.0 to 4.0
pspread=1.000000
dspread=1.000000
vspread=1.000000

# 'scale=scalename' tells LMUSe what scale to use.
# The predefined scale choices are 'Major', 'minor', 'Blue1', 'Penta1',
# 'diminished', 'Twelvetone', or 'whole'.
# Alternatively, you can give a list of number halfsteps from
# starting with the number '1'. For example, a major scale
# could be given by: scale=1,3,5,6,8,10,12
scale=Major

# scalefn is the algorithm used to get the pitches to conform to the
# desired musical scale. (see LMUSe.txt)
# Choices are: slideto, steps, constant, ignore
scalefn=slideto

# transpose amount
transpose=0

# duration multiplier
dmultiplier=1.000000

mapnumber=1
pitch=x
duration=drawlength
volume=forwardx
pspread=1.000000
dspread=1.000000
vspread=1.000000
scale=Major
scalefn=slideto
transpose=0
dmultiplier=1.000000

# maps 2 thru 8 could go here. (order is not important)

mapnumber=9
pitch=x
duration=drawlength
volume=forwardx
pspread=1.000000
dspread=1.000000
vspread=1.000000
scale=Major
scalefn=slideto
transpose=0
dmultiplier=1.000000

# end of the file
=================================================

The Play Screen
---------------
'Play' starts the music at the beginning. 

Clicking on 'Pause' stops the music until you click on 'Pause' again. 

'Save Midi' saves the piece as a standard midi file (format 1).

'New' and 'Exit' are functionally identical. Either one stops the playing and sends you back to the production screen. 

The note display shows pitch by height in the box, and duration of a note by length of its drawn line. At the bottom of the box where the notes are displayed is a 'ticker' which shows you where in time the piece is playing. If you move the mouse cursor into this area and click the mouse, the piece will jump to that time and start playing from there. 

=================================================
Using Musical Scales

You can choose a musical scale in the Map dialog box under "Scale".
The different scales are described below. 

`User' choice is for defining your own scale. If you pick `User', you are given a box where you type in some scale steps and the scale you type in will be used. The scale you type in should start with  '1' (lowest note of the scale) and thereafter each following number denotes the next higher note in the scale, in 'half tones'. Put spaces or commas between different scale notes. For example: 

        1 3 5 6 8 10 12 

would make a major scale. 

The scales in the list are defined, either by convention or by me, as:

twelve tone
1 2 3 4 5 6 7 8 9 10 11 12
c c# d d# e f f# g g# a a# b 

Major 
1 3 5 6 8 10 12 
c d e f g a b 

Penta 1
1 5 8 10 11
c e g a a# 

minor 
1 3 4 6 8 9 12
c d d# f g g# b 

blues 1
1 3 4 5 8 9 10 11
c d d# e g g# a a# 

whole tone
1 3 5 7 9 11 
c d e f# g# a# 

diminished
1 2 4 5 7 8 10 11
c c# d# e f# g a a# 

----------------------

Scale Function
Below the button for choosing a scale is the `scale function button.
LMUSe gets note pitches from some L-system state variable, as chosen in the `connect' box in the Map dialog. These variables are actually numbers. If you want to use a scale, those numbers need to end up being notes in the scale. LMUSe lets you choose between two (three) ways to do this. 

The `slide to' setting finds the lowest note greater than or equal to the generated number. It finds the next note by going 'up' the scale until reaches the number or greater. It uses semi-tones to step up.

`steps' uses the generated number to count directly up the scale. That is, it uses the scale itself to step. 

`constant' is just a way to get a constant pitch rather than a scale. 

=================================================
Rules Files Compatibility

Lparser *.LS files should all work in LMUSe (meaning only that they will be accepted and interpreted by LMUSe). Be aware, though, that files that work in LMUSe won't necessarily work with Lparser. The LMUSe parser was designed to interpret the large number of LParser files available but LParser won't accept some of the LMUSe rules (context sensitive or stochastic rules). On the other hand, while LParser can make beautiful graphics, LMUSE can't. The drawing that LMUSe does while interpreting is intended mainly as a 'progress indicator'. LMUSE is for generating music and it is just great that some of the LParser files do make nice music when fed to LMUSE.

I have tried to keep the file extensions of the examples consistent. A file with just an 'L' extension is an LMUSe rules file which does not contain a 'thickness' (the third non-comment in Lparser files is the starting thickness of lines as a percent of their length), or if it contains stochastic rules (a la A(.5)=ABB) or context sensitive rules (e.g. A<F=BF). If I believe a file is compatible with Lparser (for example, contains a thickness), it has the 'ls' extension. A file that has been mutated by LMUSe (saved after 'mutating') is given the 'lm' extension. 'lm' files which were originally 'ls' files before mutation should be compatible with Lparser, but I haven't checked all of them.

Certain of the symbols are interpreted differently in the two programs. For example 't(x)' in LMUSe transposes the following notes by x semitones. In LParser, t(x) is interpreted as a 'tropism' or gravity influence. This interpretation of 't(x)' is completely ignored by LMUSe. In LMUSe, '{' and '}' are mostly for creating parallel in time (polyphonic) musical lines. Their use in LParser is for making polygons like leaves, flower petals, etc). LMUSe does not know 'polygons' at all and so the generated graphics often look different from what you might expect from seeing the same file interpreted by LParser. 

Another popular program for doing L-systems is Fractint. Fractint L-system files (*.l) are 2-dimensional. To use them with LMUSe requires some easy adaptations to the Fractint file. First, a Fractint 'L' file can contain many sets of L-system rules. The different L-system rule sets have to be isolated in their own file to be used in LMUSe. Fractint L-system rules, parameters and axioms are also enclosed in curly brackets. You have to erase those. Plus you have to get rid of the labels like 'Angle' and Axiom'. and insert a recursion level on the first line. Also, the comment character in LMUSe is '#' while in the Fractint .L files it is ';'. And the angle in the Fractint files is a division of 360 degrees rather than the number of degrees itself. One other major difference in symbols is that @nnn in Fractint systems is the command to multiply line segment lengths by nnn, while the corresponding LMUSe command is "(nnn). (a double quotation mark followed by the multiplier).

Also note that Fractint's interpretation of .L files is case insensitive (e.g. F'='f'). LMUSe is quite sensitive to case. (e.g. 'F' and 'f' are interpreted differently).
There are a number of other differences which I guess I am not prepared to detail.

For example (grabbed from fractint.l):

        Koch1 { ; Adrian Mariano
        ; from The Fractal Geometry of Nature by
        ; Mandelbrot
        Angle 6 
        Axiom F--F--F F=F+F--F+F }


would become (koch1.l):

        # Adrian Mariano 
        # from The Fractal Geometry of Nature
        # by Mandelbrot
        3 # recursion level 
        60 # 60 degrees = 360 degrees/ 6 
        F--F--F # Axiom 
        F=F+F--F+F 


Most of the more symmetric L-systems make static/boring music. One thing that `helps' such files is changing the basic angle. Naturally this will `screw up' the picture, but often gives the music more life. 

=======================================
Command Line parameters

LMUSe can take certain command line parameters.
From the DOS command line you can start LMUSe with:

        LMUS [-sS] [-dD] [-mM] [-wW] [-iI]

-sS     S is the number of kilobytes to reserve for production string space. e.g. -s2048 reserves 2048 kilobytes, or 2 megabytes. Note that LMUSe actually allocates for twice this much (making two strings).

-dD     D is a code number for digital sound cards. Acceptable codes currently go from -1, 0, 1 thru 8:
        -1 = Let LMUSe detect the appropriate sound card (this is the default).
         0 = No digital sound.
         1 = Sound Blaster (autodetect type)
         2 = SB 1.0 (8 bit mono single shot dma)
         3 = SB 1.5 (8 bit mono single shot dma)
         4 = SB 2.0 (8 bit mono auto-initialised dma)
         5 = SB Pro (8 bit stereo)
         6 = SB16 (16 bit stereo)
         7 = Gravis Ultrasound (not written yet)
         8 = ESS AudioDrive

-mM     M is a code number for midi cards. Acceptable codes currently go from -1, 0, 1 thru 9:
        -1 = Let LMUSe detect the appropriate MIDI card (this is the default).
         0 = No midi sound.
         1 = Adlib or SB FM synth (autodetect type)
         2 = OPL2 synth (mono, used in Adlib and SB)
         3 = dual OPL2 synths (stereo, used in SB Pro-I)
         4 = OPL3 synth (stereo, SB Pro-II and above)
         5 = SB MIDI interface
         6 = MPU-401 MIDI interface
         7 = Gravis Ultrasound (not written yet)
         8 = sample-based software wavetable player
         9 = AWE32 (EMU8000 chip)

         For example, to run LMUSe without sound you could use the command
         line
             LMUS -m0 -d0

-wW     W is either 0 or 1. -w0 disables writing the current map parameters as text into saved MIDI files. -w1 enables it (the default).

-iI     I is the path and name of a map file to load.

Each of these parameters is optional. That is, none are normally needed.

=======================================
Trouble


Please email dsharp@interport.net for any problems not listed here. I have accumulated some fixes for problems on particular systems.

* It doesn't run under Windows 95/98.
* The MIDI sound doesn't work:
If you are running LMUSe in a DOS window or DOS box (Win 95), try running LMUSe after rebooting to DOS. This is pretty common generic advice, but it is the best I can offer without more details. For other situations (e.g. it still doesn't work), please email me at dsharp@interport.net with as many details of the sitution as you can manage.

One thing that causes LMUSe to fail is if it can't find the file 'LMUS.DAT'. If LMUS.DAT is not in the directory LMUSe is run from, you need to set the environmental variable LMUSDATA to the directory where LMUS.DAT is. For example, on the DOS command line you can type:
      SET LMUSDATA=C:\LMUSE\LMUS.DAT
if LMUS.DAT is in C:\LMUS. The above line could be added to your AUTOEXEC.BAT file.

*HELP functions don't work.
This is probably because LMUSe can't find the file HELP.DAT. The HELP.DAT file must be in the same directory that you are running LMUSe from, or you can set the environmental variable LMUSHELP to the directory where HELP.DAT is. For example, on the DOS command line you can type:
      SET LMUSHELP=C:\LMUSE\HELP.DAT
replacing C:\LMUSE\HELP.DAT with the path to HELP.DAT


One way around most related problems is to use the command line version of LMUSe. It has no graphics, sound, or interface with the user (beyond the command line, rule file, and map file), but it does dump a midi file at the end.

* Running out of production string space:
The default limit for production string space is 2 megabytes. You can increase this limit under the 'Options' menu or in the dialog box presented as LMUSe starts to make the production string ("Make", Make and Interpret", or "Remake"). The box titled "max production length" is the maximum length of a production in Megabytes. You can also use the command line option "-sXXXX" where "XXXX" is the number of kilobytes of string space to allocate. For example, "-s4000" will allocate room for 4 megabyte production strings. Be aware, however, that LMUSe actually allocates for two strings of this size. That is, "4" in the 'max production length' field or -s4000 on the command line will actually allocate for two 4 megabyte strings.

* Running out of stack space:
If you are finding that the stack space is often too small, let me know. Running out of stack space is most likely to occur when trying to run a mutation. The real remedy is to increase the stack space by recompiling LMUSe with a larger stack size. (The current size is 2K). A workaround to try is to reduce the recursion level you are attempting, if the recursion level is not critical to your project.

* Arithmetic errors:
A mutated set of rules sometimes causes an "arithmetic error" during interpretation. This is usually because a mutation has caused the l-system object to grow out of control. LMUSe should then just quit interpreting and tell you that it encountered an arithmetic error.
However, if LMUSe actually crashes due to an arithmetic/floating point error, please send me details. 

* The drawing runs off the screen:
When Re-interpret(Remap) is run and a new view is chosen, LMUSe uses its previous view parameters. That is, Remap does not figure the screen limits of the new drawing. The "solution" is to use "Remake and Re- Interpret" instead, even though it does take longer.

* The drawing does not resemble the LParser rendering:
LMUSe drawings are just primitive 2d projections and LMUSe blithely ignores the fact that some lines should be behind others. There are a number of LParser's drawing symbols which are interpreted differently (or not at all) by LMUSe. Probably most important (i.e. having the most dramatic effect on the drawings) is that LParser polygons, "{....}", are not supported by LMUSe. In a minimal attempt at compatiblility, LMUSe takes a stab at drawing the polygons by treating them as normal (non-polygon) drawing commands, but actually does a pretty poor job.
The drawing is mainly meant to be a progress indicator while LMUSe is turning the production string into music.

=================================================

Credits

Special thanks to: 

D J Delorie for DJGPP v2 
DJGPP web site 

Shawn Hargreaves for Allegro v3.0 
shawn@talula.demon.co.uk
http://www.talula.demon.co.uk/


Laurens Lapre for LParser.
ljlapre@xs4all.nl 
http://www.xs4all.nl/~ljlapre/

Tim Thompson and Michael Czeiszperger for `midifile.c'

End of File



