MODE Compact Reference Manual

Contents
	1:	Class Definitions and Comments for Important Classes
	2:	Class Example Code

================================================================
Class:					AbstractEvent

Superclass:			Object
Category:				Music-Events
Instance variables:	properties 

AbstractEvent is the base class in the event list hierarchy (although it can be instantiated).
Instances of AbstractEvent are objects that can be used as dictionaries or property lists.

Their properties can be accessed either with at: and at:put: or by using the new property names themselves as selectors (e.g., (anAEventInstance at: #color put: #green) or (anAEventInstance color: #green)).

Instance variables:
	properties	 <Dictionary or nil> property list dictionary

The global dictionary called Events can be used for sharing event instances.

This implementation is MODE 1.1, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-May, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					AdagioVoice

Superclass:			Voice
Category:				Music-Voices
Instance variables:	typeTable source buffer hereChar tokenType notes tempo rate synchPoint time duration nextTimeDelta pitchClass modifier octave loudness voice timbre restFlag hadAttributeFlag 
Class variables:		DynamicsTable DurationsTable PitchTable AdagioTypeTable StopChar 

I am a parser for the Adagio score representation language as described in the CMU Midi Toolkit handbook. I am  invoked by "AdagioParser parse: stream" where the stream usually comes from a string or file. I operate according to a table of token types, TypeTable. (See my class initialization message.) I work by collecting note attributes and flags until a delimiter is reached, at which point I output a note and update the current time according to the current set of attributes. Delimiters are comma, semi-colon, and the end of a line.
Class:					Amplitude

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Representation

Instances of the Amplitude species are used for the loudness parameters of musical events.
Amplitudes come in several flavors, as in the classes RatioMagnitude, MIDIVelocity and SymbolicLoudness.
The class Amplitude is abstract, its class creation method answers an instance of a concrete Amplitude/Loudness class.

Examples:
	Amplitude value: 0.77		"create a ratio instance - range 0.0 to 1.0 (cmusic)"
	Amplitude value: 77		"create an MIDI instance - range 0 to 127"
	Amplitude value: #mp		"create a symbolic instance - range #ppp to #fff"

See also the class example.
Class:					Arpeggio

Superclass:			Chord
Category:				Music-EventGenerators
Instance variables:	delay 

Arpeggii can be created on Chords or other event lists and can step through their events (assumed to be simultaneous at the start) with the given delay time.

Instance variables:
	delay <Duration or Number> the delay betyween the onsets of my events
Class:					BlockDuration

Superclass:			ConditionalDuration
Category:				Music-Magnitudes-Implementation


Class:					BooleanDuration

Superclass:			ConditionalDuration
Category:				Music-Magnitudes-Implementation


Class:					Chord

Superclass:			Cluster
Category:				Music-EventGenerators
Instance variables:	root inversion 

Instances of Chord are eventLists that can be created by giving them a root and inversion. They can return eventLists.

Instance variables:
	root <Pitch> the root of the chord
	inversion <Integer> the inversion level (unused at present)
Class:					Cloud

Superclass:			EventGenerator
Category:				Music-EventGenerators
Instance variables:	density 

Clouds are eventLists that are describe in terms of their contours or selection criteria.
This can be (e.g.,) POD-style specification of ranges for random selection, or selection from a given set of pitches.
See the class examples of my subclasses for description examples.

Instance variables:
	density		<Number> number of notes per second
Class:					Cluster

Superclass:			EventGenerator
Category:				Music-EventGenerators

Cluster is an abstraction of a set of simultaneous events.
A cluster need only have a set of pitches.

Class:					CmixVoice

Superclass:			NotelistVoice
Category:				Music-Voices


Class:					CmusicVoice

Superclass:			NotelistVoice
Category:				Music-Voices

Cmusic voices know how to print events onto streams in standard cmusic format.
The ignore their instrument associations, assuming they are being used as holders for note parameter transformers.
CmusicVoices use the property dictionaries of events for an arbitratry number of note parameters.
If events are played on them that have properties names like 'p5' or 'p21', they will be printed out in order.
For complex instruments, one can create new subclasses of CmusicVoice that perform special parameter translations or printout formatting.

Instance variables:
	stream			<Stream> my output stream (usually a file or the Transcript)
Class:					ConditionalDuration

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Implementation

Instances of ConditionalDuration are duration times where the value is a block.
The accessing protocol allows them to be spawned as co-processes in schedulers.
The valueAt: and waitUntil: methods allow flexible conditional scheduling and tests have shown that several dozen conditionals can be managed in real-time on modest hardware.

See the class examples.

Class:					CsoundVoice

Superclass:			NotelistVoice
Category:				Music-Voices


Class:					DBLoudness

Superclass:			RatioLoudness
Category:				Music-Magnitudes-Implementation

Instances of DBLoudness represent deciBel loudness values.
This is not implemented yet.
Class:					Duration

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Representation

Instances of the Duration species are used for the duration parameters of musical events.
Durations come in several flavors, as in the classes RatioDuration, MSecondDuration and ConditionalDuration.
The class Duration is abstract, its class creation method answers an instance of a concrete Duration class.

Examples:
	Duration value: 0.77		"create an instance with seconds as the unit"
	Duration value: 770		"create an instance with milliseconds as the unit"
	Duration value: 1/4		"create an instance with beats as the unit"
	Duration value: [ :x | x > 4]	"create an instance for: 'until x > 4'"

See also the class example.
Class:					DurationEvent

Superclass:			AbstractEvent
Category:				Music-Events
Instance variables:	duration voice 

Instances of DurationEvent are events that have special slots for their duration and voice properties.

Instance variables:
	duration 	<Duration species or nil> duration--a relative time
	voice		<Voice, Symbol or Number> voice--a voice or key

Class:					DynamicCloud

Superclass:			Cloud
Category:				Music-EventGenerators

Dynamic clouds are clouds that have starting and ending conditions (ranges or selection sets) and interpolate between them over their duration.
Class:					DynamicSelectionCloud

Superclass:			SelectionCloud
Category:				Music-EventGenerators

Dynamic selection clouds are described by their beginning and ending pitch and amplitude sets and interpolate between them.
Class:					EventAssociation

Superclass:			Association
Category:				Music-Support

EventAssociations are used for the (time -> event) elements of EventLists.
They are like regular Associations, but require both key and value to be equal for the Association to be equal.

EventAssociations are created with the message '=>' sent to any object, e.g., 
	21 => anEvent.
They print themselves in this way as well.
Class:					EventGenerator

Superclass:			EventList
Category:				Music-EventGenerators

This class is the parent of most of the simple motive classes in this category.
An EventGenerator can create an EventList using its given parameters and a function (block) to use to create Event sequences.  See the subclasses for examples.

This implementation is MODE 1.0, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-February, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					EventList

Superclass:			DurationEvent
Category:				Music-Events
Instance variables:	events index 

Instances of class EventList (subclass of DurationEvent), are used for holding onto multiple timed events.
EventLists are events themselves and can have arbitrary properties as well as a collection of (relative start time -> event) associations.

Class EventList implements much collection-style protocol for event processing, as well as having special block application methods.
All EventList algorithms are recurrsive in order to handle arbitrarily-deep hierarchical EventLists (possible because EventList is a subclass of DurationEvent).
The class also has numerous powerful and flexible instance creation methods.

Instance Variables:
	events 	<SortedCollection of EventAssociations (Duration => MEvent)> 
				the list's events, time/event associations sorted by relative start times
	index 	<Integer> the current position (used in scheduling)

Standard properties are #tempoScale for the tempo scaling factor (used by the CMN editors as the MS/whole note scale), and #code (#duration, #delta, or #startStop) to support different event coding schemes.
The class also supports typed links to other event lists, e.g., "eList1 isTonicAnswerOf: eList2" or "eList1 hasPreviousVersion: eList2", which can be very useful properties in editors and browsers.

The global dictionary EventLists holds onto instances that can be referenced with their name symbols; these can have gensym-like names such as #temp.23.
Creating a named EventList automatically adds it to the global dictionary.
There are tools for browsing and maintaining this dictionary.

Class:					EventScheduler

Superclass:			Object
Category:				Music-Support
Instance variables:	clients appointments running doWait 
Class variables:		Schedule 

An instance of EventScheduler is a simple driver for real-time message-passing among any classes that can return timed event association values.  
One uses Schedules by setting up clients which a master scheduler process continuously evaluates for their next timed activations.
Clients can return appointments which are sorted into the scheduler's list of (time -> event) associations that is evaluated continuously when running.
Changed messages are sent from the accessor messages to simplify EventScheduler browsers and inspectors.
This implementation is based on Mark Lentczner's original 1986 design.

Instance variables:
	clients 		<Collection> client objects
	appointments	<SortedCollection of (time -> event) Associations> the schedule
	running 		<Boolean> running schedule?
	doWait		<Boolean> whether or not the scheduler should do real-time 
					scheduling--set to false if there is a lower level of scheduling 
					(e.g., primitive-level) or if output need not be real-time

Class variable:
	Schedule 	<EventScheduler> shared instance accessed by the class 
					message masterSchedule

Class:					ExponentialFunction

Superclass:			LinearFunction
Category:				Music-Functions

Instances of ExpSeg are exponential-segment functions of one free variable.
They use ZPoints for x|y|exponent. The exponent determines the speed of the exponential/logarithmic transition between breakpoint values. A value of 0 leads to linear interpolation.
Class:					FloatSound

Superclass:			SampledSound
Category:				Music-Sound

Instances of FloatSound are used for sounds with 32-bit floating-point numbers as samples.
There are behaviors for mapping into other formats.
Class:					FourierSummation

Superclass:			Function
Category:				Music-Functions
Instance variables:	myForm myArray 

Instances of Fourier are functions that interpret their points as 3-element arrays (harmonic, amplitude, phase), and sum sine waves into their array given the fourier summation of these components.

Instance variables:
	myForm		<Form> my function plot--default size = 512@180
	myArray		<Array of Floats> my value array--default length = 512
Class:					Function

Superclass:			DurationEvent
Category:				Music-Functions
Instance variables:	data range domain 

Instances of of Function and its subclasses represent abstractions of 1- or n-dimensional functions of time. Class Function is concrete and represents functions that are described by a array of data points assumed to lie equally-spaced in the unit interval.
Functions are normally created from an array of values over the unity interval; x varies from 0.0 to 1.0 and y is free over that range.
Examples are a ramp from 0 to 1 such as:
	[(LinearFunction from: #((0 0) (1 2))) at: 0.33]
or a spline that traces a sine-like path centered around 1:
	[(SplineFunction from: #((0 1) (0.33 2) (0.67 0) (1 1))) at: 0.35]

InstanceVariables:
	data <Array of Numbers, OrderedCollection of (Z)Points, or UninterpretedBytes>
				the data values or breakpoints of the function
	range <Interval> the x-range
	domain <Interval> the y-range

This implementation is MODE 1.0, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-March, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					GranularSound

Superclass:			Sound
Category:				Music-Sound
Instance variables:	grains 

Instances of GranularSound represent sounds that use granular synthesis rather than stored samples.

Instance Variables:
	grains	<OrderedCollection of Sounds> the receiver's grains

Note that this class is not implemented yet.
Class:					HertzPitch

Superclass:			NumericalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of HertzPitch are frequency values in Hertz.
This is the most general Pitch representation.
The value is assumed to be a floating-point number.
Class:					IntervalMagnitude

Superclass:			NumericalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of subclasses of the abstract class IntervalMagnitude are NumericalMagnitudes where a specific interval is defined within which values are possible. Examples are MIDI values in the range of 0 .. 127.
Class:					Length

Superclass:			OrdinalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of Length represent subjective length (~ duration * loudness) values.
The instance variable tables are used for the name -> relation symbol map.

See the class examples.
Class:					LinearFunction

Superclass:			Function
Category:				Music-Functions

Instances of LinSeg are line-segment functions of one free variable.
Class:					MIDIDevice

Superclass:			Model
Category:				Music-MIDI-Ports
Instance variables:	port debug 
Class variables:		MStream 

MIDIDevice is a subclass of Model whose instances are used to model MIDI input/output hardware devices.
The abstract class MIDIDevice implements the generic MIDI note on/off type events.
Subclasses of MIDIDevice exist for specific models of devices and  implement the device-specific (system exclusive) commands.
MIDIDevice are passed Events and channel numbers by their voices and generate commands as ByteArrays that they pass to MIDIPorts.
Several devices may share one port (if there are several MIDI-capable devices on one cable), and one voice may point to several device/channel pairs on one or more devices.

Instance variables:
	port			<MidiPort> the MIDIPort I use

Class variable:
	MStream	<WriteStream> the stream I dump by bytes on if my port is nil (good for debugging new subclasses)

Standard MIDI Commands:
		Note On = 9n kk vv
		Note Off = 8n kk vv
		Key Pressure = An kk vv
		Pitch Wheel = En ll ll
		After Touch Channel Pressure = Dn vv
		Control Change = Bn cc vv
		Program change = Cn pp

Relevant Constants for description of MIDI commands:
		n = 4-bit channel number
		kk = 7-bit key number
		vv = 7-bit key velocity
		ll = 7-bit low-order value
		hh = 7-bit high-order value
		cc = 7-bit control number
		pp = 7-bit program number
Class:					MIDIEcho

Superclass:			Ostinato
Category:				Music-EventGenerators

Instances of class MIDIEcho can read MIDI events and process them through their blocks. An example is the class method transposeMIDI, which echos MIDI keyOn events two octaves higher.

	((MIDIEcho new) 
		process: 
			[ :e | 
			e pitch: (MIDIPitch value: (e pitch value + 24)). e]) 
		play
Class:					MIDIFB01

Superclass:			MIDIDevice
Category:				Music-MIDI-Ports

MidiFB01 is a type of MidiDevice for the system exclusive commands of the Yamaha FB-01 synthesiser.
It implements the special commands available here (like note commands with fractional pitch and given duration).

The standard FB01 note command is like:
		2n k f v d1 d2 = cmd:channel, noteNum, frac, vel, durLow, durHigh
Class:					MIDIPF70

Superclass:			MIDIDevice
Category:				Music-MIDI-Ports


Class:					MIDIPitch

Superclass:			IntervalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of MIDIPitch are well-tempered piano key numbers where 60 is middle-c (c3) according to the MIDI standard.

The translation key <--> Hz. is done with the logarithm or 27.5 Hz. (very low A).
Class:					MIDIPort

Superclass:			ExternalReadAppendStream
Category:				Music-MIDI-Ports
Instance variables:	notesOn process bytes tick debug 
Class variables:		MStream 

Instances of the subclasses of MIDIPort are used for the interface betweeen MIDI devices and the "real world." They may cache output data, throttle I/O streams, or cache active notes for the porpose of sending note-offs them selves.
They implement both note-oriented (e.g., play: pitch at: aDelay dur: aDur amp: anAmp voice: voice), and data-oriented (e.g., put: data at: delay length: size) behaviors for MIDI I/O.

Subclasses must implement:
	[put: data at: delay length: size];
	[play: pitch at: aDelay dur: aDur amp: anAmp voice: voice];
	[nextEventInto: anEventAssociation]; and 
	[get: data length: size].

The use of 'tick' may very among subclasses; those that run in real time will use it differently than those that write output ahead of real-time and assume another layer of delta-time buffering below.

InstanceVariables:
	notesOn 		<SortedCollection of (tick -> (voice@pitch)) or nil> 
					currently-active	notes; note that an Event list could used
	process		<UnixProcess or nil> The output process	
	bytes 			<ByteArray> cached data	
	tick 			<Integer> the offset tick when running ahead of real-time

Class variable:
	MStream	<WriteStream> the stream I dump by bytes on if my port is nil (good for debugging new subclasses)

Class:					MIDIVelocity

Superclass:			IntervalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of MIDIVelocity are key velocities (approximately proportional to loudness) in the range 0 to 127.

The SymbolicLoudness class maps symbolic dynamic names onto this range on an approximately logarithmic scale.
Class:					MIDIVoice

Superclass:			Voice
Category:				Music-Voices
Instance variables:	currentTime 

A MidiVoice is used to play note events onto one or more output devices.
I store MidiDevices in my instruments and play events onto them when asked to.

Instance variables:
	instruments	<set of Associations>	my instruments, stored as channel -> MidiDevice

Class:					MSecondDuration

Superclass:			NumericalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of MSecondDuration are duration times in milli-seconds.
This is the default time representation (most general duration) and is usually used for keys in event lists.
Class:					Mu8Sound

Superclass:			SampledSound
Category:				Music-Sound

Instances of Mu8Sound are used for sounds with 8-bit Mu-law-encoded samples.
There are behaviors for mapping into other formats.
Class:					MusicEvent

Superclass:			DurationEvent
Category:				Music-Events
Instance variables:	pitch loudness 

Instances of class MusicEvent are concrete musical note event objects used for eventLists and eventGenerators.

Instance variables:
	pitch <Pitch-species MusicMagnitude> the pitch/frequency
	loudness <Loudness-species MusicMagnitude> the loudness/amplitude

Class:					MusicEvent

Superclass:			DurationEvent
Category:				Music-Events
Instance variables:	pitch loudness 

Instances of class MusicEvent are concrete musical note event objects used for eventLists and eventGenerators.

Instance variables:
	pitch <Pitch-species MusicMagnitude> the pitch/frequency
	loudness <Loudness-species MusicMagnitude> the loudness/amplitude

Class:					MusicEvent

Superclass:			DurationEvent
Category:				Music-Events
Instance variables:	pitch loudness 

Instances of class MusicEvent are concrete musical note event objects used for eventLists and eventGenerators.

Instance variables:
	pitch <Pitch-species MusicMagnitude> the pitch/frequency
	loudness <Loudness-species MusicMagnitude> the loudness/amplitude

Class:					MusicMagnitude

Superclass:			Magnitude
Category:				Music-Magnitudes-Representation
Instance variables:	value 

Instances of the subclasses of MusicMagnitude are used to represent scalar magnitudes in musical objects.
The class MusicMagnitude is a place for the music magnitudes to share their state and basic accessing behavior.
MusicMagnitudes generally implement arithmetic and comparison, using a mostGeneral version within a species for coercion.

The 'type abstraction' classes (Duration, Pitch, Amplitude), are never instantiated; their class creation methods answer instances of their species.

The 'representational abstraction' classes (NominalMagnitude, OrdinalMagnitude, NumericalMagnitude, RatioMagnitude), share value models and coercion techniques.
Note that the concrete classes therefore answer their species by property model rather than by implementation subclass (i.e., HertzPitch species --> Pitch rather than NumericalMagnitude).

Instance variables:
	value		<Number or Symbol> the magnitude's value

This implementation is MODE 1.1, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-June, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					NominalMagnitude

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Implementation

Instances of the NominalMagnitude classes are named (symbolic) properties where a symbol <--> value map is well-established for a given range and domain, e.g., 0.0 to 1.0 or 0 to 127.
Examples are pitch (#d4) or dynamic (#mp) names.

Class Instance Variable:
	NameMap	<Dictionary or Array of (Symbol -> Number or Interval)> the class' look-up table
Class:					NotelistVoice

Superclass:			Voice
Category:				Music-Voices
Instance variables:	parameterMap 

Instances of the subclasses of NotelistVoice can read or write note list file streams in various formats for software sound synthesis packages such as cmusic, csound, or cmix.

Instance Variables:
	parameterMap		<OrderedCollection of Symbols, Blocks, or Associations> 
			the object's P_map, used to print out or parse note commands.

Class:					NumericalMagnitude

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Implementation

Instances of the subclasses of NumericalMagnitude are music magnitudes with numerical values.
When the values are floating-point numbers, the range is often 0.0 to 1.0.
Integer ranges such as 0 to 127 can also be used in subclasses.

One may want to add range-checking for these cases.

Note that the class NumericalMagnitude is vacuous at present, and exists solely for representational modeling.
Class:					OpcodeVoice1

Superclass:			Voice
Category:				Music-Voices
Instance variables:	tempo time command byte2 byte3 eventList 

This voice class is a file I/O convertor that can transform **OLD** Opcode format MIDI file dumps into EventLists and/or play them in real-time. 
The messages here will look like:
(OpCodeVoice newOn: 'Scores:n3.a.sc') loadOnto: (EventList newNamed: #n3.a)

Instance variables:
	tempo <Integer> the tempo read in from a Midi dump file
	time <Integer> the current time
	command <Byte> first byte of the command
	byte2 <Byte> second byte of the command
	byte3 <Byte> third byte of the command
	eventList <EventList> the resulting event list
Class:					OpcodeVoice2

Superclass:			Voice
Category:				Music-Voices
Instance variables:	fileType tracks ppq tempo 

This voice class is a file I/O convertor that can transform Standard 1.0 format MIDI file dumps into 
EventLists and/or play them in real-time. 
The messages here will look like:
(OpcodeVoice2 newOn: 'Scores:n3.a.sc') loadOnto: (EventList newNamed: #n3.a)

A type 0 MIDI file contains a single, multi-channel track. 
A type 1 contains one or more simultaneous tracks. 
A type 2 contains a number on independent single-track patterns.

Instance variables:
	fileType <Integer> MIDI file type: 0, 1 or 2.
	tracks <Integer> number of tracks in the file.
	ppq <Integer> time division in pulses per quarter-beat.
	tempo <Integer> the tempo read in from a Midi dump file in microseconds per beat.
Class:					OrdinalMagnitude

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Implementation
Instance variables:	table 

Instances of the OrdinalMagnitude classes are order-only magnitudes.
They use the instance or class instance tables for holding comparative relationships among instances (e.g., mag1 might know that it's > mag2).
The relation-setting (i.e., order assignment) messages are: ==, >>, <<, =<, and =>.
The query messages are: =?, > < <=, and >=.

Each subclass may decide whether instances or the class will hold the table of relationships.
The decision should be made on the basis of the expected number of magnitude instances and the sparseness of their relationships.

See the subclass' class examples.

Instance Variable:
	table	<Dictionary of OrdinalMagnitude -> Symbol> instance rel. table

Class Instance Variable:
	Table	<Dictionary of OrdinalMagnitude -> Symbol> class rel. table of all instances

This implementation is MODE 1.0, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-February, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					Ostinato

Superclass:			EventGenerator
Category:				Music-EventGenerators
Instance variables:	list playing process 

Ostinati can repeat their basic eventList without end, if necessary.

Instance variables:
	list <EventList> my riff
	playing <Boolean> am i on?
	process <Process> the process that's playing me

Class:					PField

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Representation
Instance variables:	name field 

Instances of PField magnitudes are used for arbitrary parameters of musical events oriented towards formats with positional parameter declarations, e.g., Music-V-style notelist formats (see uses).

Instance variables:
	field		<Integer> field in the score
	name	<String or Symbol> the parameter's name (optional)

Examples:
	PField field: 5 value: 0.7 name: #position
	PField field: 9 value: 'legato' name: #expression

Class:					Pitch

Superclass:			MusicMagnitude
Category:				Music-Magnitudes-Representation

Instances of the Pitch species are used for the pitch or frequency parameters of musical events.
Pitches come in several flavors, as in the classes HertzPitch, RatioPitch, MIDIPitch and SymbolicPitch.
The class Pitch is abstract, its class creation method answers an instance of a concrete Pitch class.

Examples:
	Pitch value: 440.0 	"create an instance with units of Hertz"
	Pitch value: 77		"create an instance with units of MIDI key numbers"
	Pitch value: #e4		"create a symbolic instance"
	Pitch value: 'e4'		"same as using a symbol"
	Pitch value: 4/3		"create a ratio instance"

Note that new pitch representations such as music11-like pch (4.11 = 11th note in oct 4) or oct (4.1100 = oct4 + 1100 cts) notations can be added by overriding the float-to-Hz or float-to-midi conversions.

See also the class example.
Class:					PrimMIDIPort

Superclass:			MIDIPort
Category:				Music-MIDI-Ports

Class PrimMIDIPort is instantiated; its instances serve as driver interfaces for the C-language MIDI scheduler via their messages.

This code is rather stale (as I use SunMIDIPorts), and will be redone soon.

This implementation is MODE 1.0, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-February, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					ProPort

Superclass:			SoundPort
Category:				Music-Sound

An instance of ProPort can send and receive samples to/from an Ariel S56/S56X and ProPort external audio interface via the SPARCstation's SBUS.
The user primitives in this class interface to the driver routines using SampledSound objects.
Class:					RatioDuration

Superclass:			RatioMagnitude
Category:				Music-Magnitudes-Implementation

Instances of RatioDuration are 'beat' fractions.
They can be expanded into msec. relative to some given event (a whole note), or use the default tempo of 1 sec.
Class:					RatioLoudness

Superclass:			RatioMagnitude
Category:				Music-Magnitudes-Implementation

Instances of RatioLoudness are fractional amplitude values normally relative to the range 0 to 1.

Class:					RatioMagnitude

Superclass:			NumericalMagnitude
Category:				Music-Magnitudes-Implementation
Instance variables:	relative 

Instances of the RatioMagnitude subclasses are fractional values relative to some context-defined reference value--their relative. The relative may be provided, or it may be assumed if uninitialized (e.g., for a default whole note's duration or default reference pitch).

Instance Variable:
	relative		<MusicMagnitude> the reference value
Class:					RatioPitch

Superclass:			RatioMagnitude
Category:				Music-Magnitudes-Implementation

Instances of RatioPitch are fractional pitch values normally relative to c=261.623Hz.
They can be transformed into other values (e.g., note names or key numbers), but often at a loss of accuracy if they are not well-tempered.

Class:					Roll

Superclass:			Cluster
Category:				Music-EventGenerators
Instance variables:	number delta noteDuration 

Rolls repeat their single events.
It will eventually be possible to apply pitch, amplitude or duration envelopes to them as well.

Instance variables:
	number			<Integer> how many notes to play
	delta			<Number> delta time between events
	noteDuration	<Number> duration of events
Class:					SampledSound

Superclass:			Sound
Category:				Music-Sound
Instance variables:	cueList 

Instances of Sound represent digitally-sampled sound objects.
They can be read/written to/from files, displayed and played.
The class SampledSound is concrete and assumes 16-bit linear encoding of samples; there are subclasses for floating-point and 8-bit Mu-law sample types.

Instance variables:
	samples	<UninterpretedBytes> the sound's samples
	cueList	<SortedCollection of sample indeces or nil> the points in the data not 
			to play, i.e., pointers denoting sections that have been deleted. For 
			example, having a cueList of (1000 2000) means that samples (1000, 2000] 
			have been virtually cut.

Other properties, such as the sound's (optional) file name, its sample rate, or the number of channels, are stored in the property list dictionary that is inherited by virtue of being an event subclass.

Note that not all of this class is finished--there are methods that call non-existant user primitives, and others that are not fully implemented.
Class:					SecondDuration

Superclass:			MSecondDuration
Category:				Music-Magnitudes-Implementation


Class:					SelectionCloud

Superclass:			Cloud
Category:				Music-EventGenerators

Selection clouds are created with a set of pitch and amplitude values and return eventLists selected from these values.
Class:					Sharpness

Superclass:			OrdinalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of Sharpness represent subjective sharpness (~ pitch * loudness) values.
The instance variable tables are used for the name -> relation symbol map.

See the class examples.
Class:					Sound

Superclass:			Function
Category:				Music-Sound

Instances of the subclasses of Sound are used to represent sound objects.
The abstract class Sound is vacuous.
Sounds use their Function and DurationEvent behaviors actively.

This implementation is MODE 1.1, Palo Alto, May, 1992.

The entirety of this software is Copyright (c) 1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research. 
All Rights Reserved.
Class:					SoundFile

Superclass:			Model
Category:				Music-Sound
Instance variables:	sound fileName file position headerSize format rate channels size props 

Instances of SoundFile are used for reading and writing sound objects to/from files.
They handle formatting, headers and I/O.
Currently implemented formats include the NeXT, SPARC, and BICSF/IRCAM soundfile formats. Special code is implemented for reading IRCAM headers with comments and max-amp records. Ths C-code for managing these sound files is part of cmix, available free from Princeton.edu.

Instance variables:
	sound		<SampledSound> the sound's samples
	rate		<Number> the sound's sampling rate
	channels	<Number> the number of channels
	fileName	<String> the file's name
	file		<ExternalStream> the file's stream
	position	<Number> the current position
	headerSize	<Number> the size of the soundfile header
	props		<Dictionary> the property list dictionary of the receiver
	format		<Symbol> the format--currently only #linear16Bit is handled
	size		<Number> the size in samples

This implementation is MODE 1.0, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-February, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					SoundManager

Superclass:			Model
Category:				Music-Sound
Instance variables:	elements 
Class variables:		SoundMemory Sounds 

The SoundManager class is used for managing sampled sound storage within a virtual image. Its class messages are called for creating sounds. In some cases, users will want to allocate one large UninterpretedBytes and have the SoundManager manage pointers into it.
In the current implementation, this is not done and the SoundManager class messages allocate new UB objects on-the-fly.
Class:					SoundPort

Superclass:			ExternalReadAppendStream
Category:				Music-Sound
Instance variables:	playingSem 

SoundPort instances are interfaces to real-time sound I/O streams.

Concrete subclasses add primitive interfaces to special devices such as audio ports or coprocessors.
Class:					SPARCAudioPort

Superclass:			SoundPort
Category:				Music-Sound

An instance of SPARCAudioPort can send and receive samples to/from the SPARCstation's sound driver.
The user primitives in this class interface to the driver routines using Mu8Sound objects.
Class:					SplineFunction

Superclass:			LinearFunction
Category:				Music-Functions
Instance variables:	linSeg 

Instances of SplineSeg are cubic splines betwen their points.

Instance Variable:
	myForm		<Form> my cached for (used for value look-up)
Class:					SunMIDIPort

Superclass:			MIDIPort
Category:				Music-MIDI-Ports

SunMIDIPort uses the mread and mplay programs via UnixProcesses and pipes to read and write MIDI data. Instances are used as the ports of MIDI devices, which MIDI voices use to play event lists. 
Note that SunMIDIPort instances assume the mplay program buffers output according to its delta delay times, and reads data in its given message/data format.
There are class utility messages for turning all notes off.

The data format for mplay is an 8-byte header followed by raw MIDI data:
	long delay;		/* clock ticks until action */
	char type;			/* message type; 0=data */
	char network;		/* MIDI network; 0=default */
	short size;		/* number of MIDI data bytes */
	char data[];		/* 3-n bytes of data */

Tick is set to 0 at init time, and is used to accumulate the clock because mplay runs ahead of real time.

Class:					SymbolicLoudness

Superclass:			NominalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of SymbolicLoudness are dynamic names in the range #ppp to #fff.

The class instance variable NameMap is used for the name <--> MIDI velocity range (0 to 127) mapping dictionary.

Class:					SymbolicPitch

Superclass:			NominalMagnitude
Category:				Music-Magnitudes-Implementation

Instances of SymbolicPitch represent well-tempered note names relative to a4=440Hz.
The range is c0 to g#9 and the values are symbols.
Note the confusion between the sharp sign (always placed after the note name) and Smalltalk's symbol key #.
One often writes ('c#3' asSymbol) to be safe.

The class instance variable NameMap is used for the name <--> MIDI key number mapping array.

Class:					Trill

Superclass:			Roll
Category:				Music-EventGenerators

A trill is like a roll, except that it can be given an eventList for repetition.
Class:					Voice

Superclass:			MusicMagnitude
Category:				Music-Voices
Instance variables:	name instruments stream 
Class variables:		DefaultVoice 

Subclasses of Voice implement the mappings between symbolic event parameters (like timbre descriptions and pitch names) and concrete output event data.
They can be used for generating sound compiler notelists or (real-time output or file dumps of) MIDI data.

The instance variables are:
	instruments <set of symbols, associations or devices> my instruments
	name 		<String or Symbol> my handle or name
	stream		<Stream> my optional output stream

The global object Voices is a dictionary that note events can refer to with integer or symbolic keys.

This implementation is MODE 1.0, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-February, 1992.

The entirety of this software is Copyright (c) 1984-1992, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research.  All Rights Reserved.
Class:					ZPoint

Superclass:			Point
Category:				Music-Support
Instance variables:	z 

ZPoints define a third instance variable in addition to Point's x and y to hold 3-dimensional point values.

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

Class:					BinaryTreeLayoutManager

Superclass:			HierarchyLayoutManager
Category:				MusicUI-Layout

Instances of BinaryTreeLayoutManager are used to generate display lists which mirror the hierarchy of their models (accessed using a TreeAccessor) in the tree structure of a binary tree.
Class:					BTreeNode

Superclass:			TreeNode
Category:				MusicUI-Trees
Instance variables:	right 


Class:					CMNLayoutManager

Superclass:			PitchTimeLayoutManager
Category:				MusicUI-Layout
Instance variables:	stepArray staffTop 

Instances of CMNLayoutManager are used to generate display lists which common-practise Western music notation.
They handle (together with CMNViews) the nasty heuristics of CMN generation.
Class:					CMNView

Superclass:			PitchTimeView
Category:				MusicUI-Editors
Instance variables:	steps sharps staves ledgers xTable 

Instances of CMNView display common-practise Western music notation (after a fashion).
For reasons of size and readability, it is kept simple. It handles clefs, accidentals and ledger lines, but has no beaming or fancy page layout; this should be added in a subclass.

Instance Variables:
	staves	<OrderedCollection of (Integer -> Symbol)> the x positions of the staves 
				and their symbolic names (clefs), e.g., 40 -> #piano.
	steps	<Array of Integers> the step array (pitch number mapped to y value)
	sharps	<Array of Integers> the sharp array (pitch offsets that take accidentals)
	ledgers	<Array of Integers> The y positions of the ledger lines (5 by default)
	xTable	<OrderedCollection of Integers> the table of x positions of the events;
			needed for fancy layout or lots of notes or accidentals
Class:					ColorActionButton

Superclass:			ActionButton
Category:				MusicUI-Support
Instance variables:	onColor offColor 


Class:					ColorBox

Superclass:			VisualPart
Category:				MusicUI-Support
Instance variables:	color 


Class:					ColorPopUp

Superclass:			PopUpMenu
Category:				MusicUI-Support
Instance variables:	colorArray x y 


Class:					DisplayItem

Superclass:			DependentPart
Category:				MusicUI-DisplayLists
Instance variables:	offset color 

Instances of the subclasses of the abstract class DisplayItem are used as the items in display lists. They can generally display themselves on graphics contexts.
These are done this way because I don't think wrappers are right for use in display lists.

Instance Variables:
	offset		<Point> the object's offset relative to its container (display list)
	color		<ColorValue> the object's display color (or nil)

The subclasses add special display-related state and behavior such as an extent point and display method, or a visual item such as a string or image to display.
They generally implement displayOn: aGraphicsContext and bounds accessing methods.

This implementation is MODE 1.1, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-May, 1992.

The entirety of this software is Copyright (c) 1990, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research. 
All Rights Reserved.

Class:					DisplayLine

Superclass:			DisplayItem
Category:				MusicUI-DisplayLists
Instance variables:	width extent 

Instances of DisplayLine are used for visual lines in display lists.

Instance Variables:
	width		<Number> the object's line width
	extent		<Point> the object's visual extent
Class:					DisplayList

Superclass:			DependentComposite
Category:				MusicUI-DisplayLists
Instance variables:	offset 

Instances of DisplayList are used for representing composed structured graphics. They can be nested (see the class examples) and can display themselves and their components.

Instance Variables:
	offset		<Point> the object's offset distance relative to its container
Class:					DisplayListController

Superclass:			ControllerWithMenu
Category:				MusicUI-DisplayListViews
Instance variables:	selection 

Instances of DisplayListController (or its subclasses) are used by DisplayListViews (or subclass instances) for menu management and selection.

By default, a simple YellowButton menu allows for group/inspect/redraw/zoom.
The RedButton is used for display item selection (by pointing or boxing-in).
LeftShift extends the selection, and dragging a selection moves it.

Instance Variables:
	selection		<DisplayList> the object's selected items
Class:					DisplayListEditor

Superclass:			Model
Category:				MusicUI-DisplayListViews
Instance variables:	selection list 

An instance of DisplayListEditor is used as the intermediary model for viewing lists.
It handles selection and operation on the list.
It adds itself as a dependent of the list and echoes its change messages (i.e., the update: message says self changed).

Instance Variable:
	list			<DisplayList> the 'subject' list model
	selection		<DisplayItem orDisplayLIst> the current selection or nil

Class:					DisplayListView

Superclass:			AutoScrollingView
Category:				MusicUI-DisplayListViews
Instance variables:	displayList pixmap background page zoom grid backgroundColor foregroundColor redrawn cache 

DisplayListViews can display and scroll structured graphics display lists generated by various models or layout managers.
Using their page offset, they can scroll over very large display lists.
They can have colored or gridded background pixmaps and can scroll/page on demand; they display their lists on their graphics contexts.

Subclasses generally override the displayOn: or displayOnImage methods, and add initialization or transformation methods.

Instance Variables
	displayList	<DisplayList> the view's display list
	pixmap			<Pixmap or nil> the view's cached display pixel map (optional)
	background		<Pixmap or nil> the view's background form (e.g., gridding)
	zoom			<Point or nil> the display list's zoom-in factor or nil
	pageOffset		<Point> the offset in "pages" used for very large display lists
	backgroundColor	<ColorValue> graphics background color
	foregroundColor	<ColorValue> graphics display color
	redrawn		<nil or not> set to nil to re-draw cache

See the class examples for numerous ways of using display list views.
The subclasses add knowledge of smart display list generation, background pixmap generation (e.g., gridding), display of item or x/y-range selection, x- or y-scaling or step/grid, property->color mapping, "clef forms" or other special pixmaps, multiple-model viewing, etc.

Class:					DisplayPolyline

Superclass:			DisplayRectangle
Category:				MusicUI-DisplayLists
Instance variables:	vertices 


Class:					DisplayRectangle

Superclass:			DisplayLine
Category:				MusicUI-DisplayLists
Instance variables:	fill 

Instances of DisplayRectangle can be used to display bordered or filled rectangles in display lists. This is a subclass of DisplayLine for reasons of practicality. a "purist" (e.g., David Liebs), would create an intermediate abstract class (e.g., BoundedDisplayItem) for both DisplayLine and DisplayRectangle.

Instanve Variables:
	fill		<Boolean or nil> whether or not to fill the receiver on display (no by default)
Class:					DisplayString

Superclass:			DisplayItem
Category:				MusicUI-DisplayLists
Instance variables:	string font 

Instances of DisplayString are used for visual text items in display lists.

Instance Variables:
	string		<String or Text> the object's string/text
	font		<ImplementationFont> the object's display font
Class:					DisplayVisual

Superclass:			DisplayItem
Category:				MusicUI-DisplayLists
Instance variables:	visual 

Instances of DisplayVisual are used for displaying arbitrary visual objects (e.g., cached images) in display lists.

Instance Variables:
	visual		<VisualComponent> the object's visual object, typically an image
Class:					EventInspector

Superclass:			Inspector
Category:				MusicUI-SupportOLD

EventInspector allows extra menu messages like property access
Class:					EventInspectorView

Superclass:			Inspector
Category:				MusicUI-SupportOLD

EventInspectorView is used for events and eventLists, it adds new functions and buttons.
Class:					EventListDictionaryInspector

Superclass:			DictionaryInspector
Category:				MusicUI-Support
Class variables:		EvListDictListMenu 

ELDInspector is used for eventLists; it has the play and edit functions
Class:					EventListDictionaryInspectorView

Superclass:			Inspector
Category:				MusicUI-Support

ELDIView is used with the ELDInspector.
Class:					EventListEditor

Superclass:			Model
Category:				MusicUI-Editors
Instance variables:	list ostinato selection defaultEvent 

Instances of EventListEditor are used as the models of EventListViews.
They hold onto EventLists and send messages to them.

Instance variables:
	list 			<EventList> my EventList (subject)
	ostinato 	<Ostinato> my loop process (if i'm looping)
	selection 	<EventList> The "selected" notes
	ampl 		<Number or Amplitude> My default amplitude

Class:					FunctionController

Superclass:			DisplayListController
Category:				MusicUI-Functions
Instance variables:	modelIndex 

Instances of FunctionController are the controllers used within FunctionViews.
The allow click-and-drag breakpoint function editing.

Instance Variables
	modelIndex		<Integer 1-4> the index into the view's array of functions.
Class:					FunctionView

Superclass:			DisplayListView
Category:				MusicUI-Functions
Instance variables:	models aScale vRange hRange colors width 

Instances of class FunctionView are views on breakpoint or sampled data functions.
They can display up to 4 model functions on a fixed-size non-scrolling field.

Instance variables:
	models		<Array of 1 to 4 Functions> the function array
	aScale		<Number> the y-scale of the view
	vRange		<Number> the vertical range, normally = aScale
	hRange		<Number> the horizontal range
	colors 	<Array of 1 to 4 colorValues> the colors for the 4 functions
Class:					GridTracker

Superclass:			MenuTracker
Category:				MusicUI-Support
Instance variables:	x y 


Class:					GroupingLayoutManager

Superclass:			SequenceLayoutManager
Category:				MusicUI-Layout
Instance variables:	levelScale 

Instances of GroupingLayoutManager are used to generate display lists which display the hierarchical grouping of event lists.
Class:					GroupingView

Superclass:			TimeSequenceView
Category:				MusicUI-Editors

Instances of Grouping view display the hierarchy of event lists.
Class:					HauerSteffensView

Superclass:			PitchTimeView
Category:				MusicUI-Editors


Class:					HierarchyLayoutManager

Superclass:			LayoutManager
Category:				MusicUI-Layout
Instance variables:	length xStep yStep treeAccessor 

Instances of the HierarchyLayoutManager classes are used to generate display lists from tree-like data and tree accessors.

Instance Variables:
	length		<Integer or Point> temp. depth used in layout
	xStep		<Integer> step size for x
	yStep		<Integer> step size for x
	treeAccessor	<TreeAccessor> the TreeAccessor used to access the model

Class:					IndentedListLayoutManager

Superclass:			HierarchyLayoutManager
Category:				MusicUI-Layout

Instances of IndentedListLayoutManager are used to generate display lists which mirror the hierarchy of their models (accessed using a TreeAccessor) in the indentation of a list-like outline.
Class:					IndentedTreeLayoutManager

Superclass:			IndentedListLayoutManager
Category:				MusicUI-Layout
Instance variables:	list 

Instances of IndentedTreeLayoutManager are used to generate display lists which mirror the hierarchy of their models (accessed using a TreeAccessor) in the indentation of a list-like tree.
Class:					InstrumentSelector

Superclass:			View
Category:				MusicUI-SupportOLD
Instance variables:	eLView 

The InstrumentSelector is used for the iconic menus of instreument icons used in the HSEventListViews.

Instance variables:
	elView	<EventListView> the view I effect
Class:					InstrumentSelectorController

Superclass:			Controller
Category:				MusicUI-SupportOLD

I am the controller for the InstrumentSelector and do simplistic gridding for icon selection.
Class:					LayoutManager

Superclass:			Object
Category:				MusicUI-Layout
Instance variables:	view orientation itemAccessor 

Instances of the LayoutManager classes are used to generate display lists given random data structures and possibly hints in terms of structure accessors.
This is David's miraculous idea and the heart of the Navigator architecture.

Instance Variables:
	view		<DisplayListView> the view--May provide the displayItems
	orientation	<Symbol or nil> my 'base' symbol (e.g., #top)
	itemAccessor	<StructureAccessor> my referencing protocol translator

Look for class references to the LayoutManager classes (mostly from DisplayListView classes), for lots of examples of the use of LayoutManagers.

This implementation is Topaz 0, STEIM, Amsterdam, May/June 1990.

The entirety of this software is Copyright (c) 1990, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research. 
All Rights Reserved.
Class:					LeafLinearTreeLayoutManager

Superclass:			BinaryTreeLayoutManager
Category:				MusicUI-Layout

Instances of LeafLinearBinaryTreeLayoutManager are used to generate display lists which mirror the hierarchy of their models (accessed using a TreeAccessor) in the tree structure of a binary tree whose leaves are adjusted to lie in a line at the same y value.
Class:					LPCFrame

Superclass:			Object
Category:				MusicUI-LinearPrediction
Instance variables:	npoles resid amp thresh pitch data 
Class variables:		DefaultNPoles 


Class:					LPCFrameController

Superclass:			ControllerWithMenu
Category:				MusicUI-LinearPrediction
Instance variables:	selection1 selection2 


Class:					LPCFrameData

Superclass:			OrderedCollection
Category:				MusicUI-LinearPrediction
Instance variables:	filename sound source 


Class:					LPCFrameView

Superclass:			DisplayListView
Category:				MusicUI-LinearPrediction
Instance variables:	step pScale aScale rScale pBase aBase rBase 


Class:					Mix

Superclass:			EventList
Category:				MusicUI-Mixing
Instance variables:	output 

A Mix instance has an array of elements and a mixing window.
It interfaces with the SoundManager for interactive mixing and performance.

Instance variables:
	sound		<SampledSound> the current mix's result or temp. sound

This implementation is MODE 1.0, Palo Alto, July, 1991.

The entirety of this software is Copyright (c) 1991, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research. 
All Rights Reserved.
Class:					MixController

Superclass:			PitchTimeController
Category:				MusicUI-Mixing


Class:					MixElement

Superclass:			MusicEvent
Category:				MusicUI-Mixing
Instance variables:	sound fadeIn fadeOut envelope 

Instances of MixElement are Event types with special behaviors for sound manipulation.

Instance variables:
	sound		<SampledSound> the instance's sound object

Class:					MixLayoutManager

Superclass:			PitchTimeLayoutManager
Category:				MusicUI-Mixing


Class:					MixView

Superclass:			PitchTimeView
Category:				MusicUI-Mixing
Instance variables:	colorArray buttonOffsets 

A MixView can display the elements ofa Mix top-to-bottom with various switches and sliders, a la MacMix.

Class:					MODESystemController

Superclass:			StandardSystemController
Category:				MusicUI-Support
Class variables:		MODEBlueButtonMenu 


Class:					NetLink

Superclass:			Model
Category:				MusicUI-Networks
Instance variables:	name 


Class:					NetNode

Superclass:			Model
Category:				MusicUI-Networks
Instance variables:	name inputs outputs 


Class:					NetworkLayoutManager

Superclass:			LayoutManager
Category:				MusicUI-Networks


Class:					NoteSelector

Superclass:			InstrumentSelector
Category:				MusicUI-SupportOLD

NoteSelector is a fancier InstrumentSelector for use in the common-practise music notation editors.
It presents a menu of note heads and rests.
Class:					PathEditorController

Superclass:			Controller
Category:				MusicUI-SupportOLD

I am the controller for the PathEditor, use redButton to move points, yellowButton to recomputer path.
Class:					PhaseVocFrame

Superclass:			LPCFrame
Category:				MusicUI-PhaseVocoder


Class:					PhaseVocFrameData

Superclass:			LPCFrameData
Category:				MusicUI-PhaseVocoder


Class:					PhaseVocFrameView

Superclass:			LPCFrameView
Category:				MusicUI-PhaseVocoder
Instance variables:	colorArray 


Class:					PhraseView

Superclass:			TimeSequenceView
Category:				MusicUI-Editors


Class:					PitchTimeController

Superclass:			TimeSequenceController
Category:				MusicUI-Editors


Class:					PitchTimeLayoutManager

Superclass:			SequenceLayoutManager
Category:				MusicUI-Layout
Instance variables:	pitchScale pitchOffset 

Instances of the PitchTimeLayoutManager classes are used to generate display lists with "x = time" and "y = pitch" from event lists.
The default layout is linear pitch-to-y, like piano-roll or Hauer-Steffens notation.

Instance Variables:
	pitchScale		<Integer> the key#/pixel scale
	pitchOffset		<Integer> the bottom of the layout as a key#

Class:					PitchTimeView

Superclass:			TimeSequenceView
Category:				MusicUI-Editors
Instance variables:	pitchOffset yScale 

Instances of PitchTimeView (and its subclasses) are time-line oriented DisplayListViews which make the assumption that the y-coordinate is related to pitch.
The relationship may be a function (as in piano-roll and Hauer-Steffens notation), or involve a look-up table (as in CMN).

Instance Variables:
	pitchOffset	<Number> the view's lowest pitch (normally a key number)
Class:					PlayList

Superclass:			FileBrowser
Category:				MusicUI-Sound
Instance variables:	longList 


Class:					PositionTimeLayoutManager

Superclass:			PitchTimeLayoutManager
Category:				MusicUI-Layout

Instances of PositionTimeLayoutManager are used to generate display lists with "x = time" and "y = position" from event lists.

Class:					PositionTimeView

Superclass:			PitchTimeView
Category:				MusicUI-Editors


Class:					ProgressionNode

Superclass:			TRTreeNode
Category:				MusicUI-Trees


Class:					ProlongationNode

Superclass:			TRTreeNode
Category:				MusicUI-Trees
Instance variables:	strength 


Class:					SequenceLayoutManager

Superclass:			LayoutManager
Category:				MusicUI-Layout
Instance variables:	timeScale timeOffset 

Instances of the SequenceLayoutManager classes are used to generate display lists with "x = time" from event lists.

Instance Variables:
	timeScale		<Integer> the msec./pixel scale
	timeOffset		<Integer> the start of the layout in msec.

Class:					SoundBrowser

Superclass:			Browser
Category:				MusicUI-Sound
Instance variables:	sound soundView 
Class variables:		RootName SoundLibrary 

The SoundBrowser is a new Browser for managing the System's SoundLibrary with class SoundManager.

Class:					SoundBrowserView

Superclass:			Browser
Category:				MusicUI-Sound

The SoundBrowserView is a new BrowserView with special relevance to the SoundManager.
Class:					SoundController

Superclass:			ControllerWithMenu
Category:				MusicUI-Sound
Instance variables:	selection 

Instances of SoundController are used with SoundViews and perform horizontal scrolling and menu operations
Class:					SoundEditor

Superclass:			Model
Category:				MusicUI-Sound
Instance variables:	copyBuffer sound markers selection1 selection2 lastSelection buffer view changed 


Class:					SoundSelector

Superclass:			InstrumentSelector
Category:				MusicUI-SupportOLD
Instance variables:	labels 


Class:					SoundView

Superclass:			DisplayListView
Category:				MusicUI-Sound
Instance variables:	step scale 
Class variables:		SelectionGlyph 

Instances of SoundView are used for displaying samples sound objects in R4.
They can do horizontal scrolling and scaling.

Instance variables:
	displayContents	<GraphicsContext> the cached display
	marker1, 2		<Number> the offset into the sound in samples for 2 markers
	step				<Number> the step size for displaying--show every n'th sample
	scale			<Number> the vertical scale for multiplying the sample's value

Class:					StructureAccessor

Superclass:			Object
Category:				MusicUI-Layout
Instance variables:	subject itemGenerator 

Instances of StructureAccessor and its subclasses are 'protocol convertors' which provide predictable interfaces (e.g., tree-speak), for diverse data structures.
The basic display item generating protocol is: 
	(aStructureAccessor itemFor: aModelNode).

InstanceVariableNames:
	subject			<Object> the model or victim
	itemGenerator   	<Symbol or Block> the DisplayItem generator
						Model items are passed to it (if it's a Block),
						or have to perform: it (if it's a Symbol).

Class:					TimeSequenceController

Superclass:			DisplayListController
Category:				MusicUI-Editors


Class:					TimeSequenceView

Superclass:			DisplayListView
Category:				MusicUI-Editors
Instance variables:	clefForm xScale xColor yColor headColor clefColor itemAccessors 

Instances of SequenceView (and its subclasses) are time-line oriented DisplayListViews.
Time may run horizontally (default) or vertically, depending on the layout manager.

Instance Variables:
	clefForm	<Form> the view's clef form or axes (optional), may be staff or scale/grid/ruler
	xScale	<Number> the time-to-x-coordinate scale
	xColor	<ColorValue> the color of the lines for note duration
	yColor	<ColorValue> the color of the lines for note amplitude
	headColor	<ColorValue> the note head color
	clefColor	<ColorValue> the clef color
	itemAccessors	<Symbol or Dictionary of (Voice -> Symbol)> the item accessor(s) to use to generate the display list items for the notes

This implementation is MODE 1.1, STEIM, Amsterdam, May/June 1990; updated at the Lagoon in Palo Alto, July, 1991-May, 1992.

The entirety of this software is Copyright (c) 1990, Stephen Travis Pope, Nomad Object Design/Nomad Computer Music Research. 
All Rights Reserved.
Class:					TreeAccessor

Superclass:			StructureAccessor
Category:				MusicUI-Trees
Instance variables:	terminalQuery childAccessor 

Instances of TreeAccessor tree-navigation interfaces to diverse data structures.
The basic display tree walking protocol is: 
	(aTreeAccessor childrenOf: aModelNode); and
	(aTreeAccessor isTerminal: aModelNode).

InstanceVariableNames:
	terminalQuery	<Symbol or Block> the isLeaf or hasChildrenNot query
	childAccessor		<Symbol or Block> accessor to get a node's children
						Model items are passed to these (if they're Blocks),
						or have to perform: them (if they're Symbols).

Class:					TreeController

Superclass:			DisplayListController
Category:				MusicUI-Trees


Class:					TreeEditor

Superclass:			DisplayListEditor
Category:				MusicUI-Trees
Instance variables:	root leaves layoutManager 


Class:					TreeLayoutManager

Superclass:			BinaryTreeLayoutManager
Category:				MusicUI-Layout

Instances of TreeLayoutManager are used to generate display lists which mirror the hierarchy of their models (accessed using a TreeAccessor) in the tree structure of a graphical tree.
Class:					TreeNode

Superclass:			NetNode
Category:				MusicUI-Trees
Instance variables:	children 


Class:					TRTreeEditor

Superclass:			TreeEditor
Category:				MusicUI-Trees
Instance variables:	sequenceView 


Class:					TRTreeLayoutManager

Superclass:			LeafLinearTreeLayoutManager
Category:				MusicUI-Layout
Instance variables:	sequenceView 
Class variables:		EmptyDot Dot 

Instances of TRTBinaryTreeLayoutManager are used to generate display lists which mirror the hierarchy of their models (tension-relaxation or prolongational reduction trees accessed using a TreeAccessor) in the tree structure of a binary tree whose leaves are adjusted to lie in a line at the same y value and whose branches are straightened according to the TRTree semantics described in "A Generative Theory of Tonal Music" by Fred Lerdahl and Ray Jackendoof.
Class:					TRTreeNode

Superclass:			BTreeNode
Category:				MusicUI-Trees
Instance variables:	key 



================================================================
[1] Example Code

From Objectworks\Smalltalk(R), Release 4.1 of 15 April 1992 on 6 June 1992 at 10:47:20 pm

MusicMagnitude class methodsFor: 'examples'
MODEExampleList
	"Answer a list of all of the example methods in the MODE categories"
	"MusicMagnitude MODEExampleList inspect"

	| aCollection |
	aCollection := OrderedCollection new.
	(Smalltalk organization categories select: [ :cat | | siz |
		siz := 'Music-' size.
		(cat size >= siz) and: [(cat copyFrom: 1 to: siz) = 'Music-']])
	do: [ :catName |
		 (Smalltalk organization superclassOrder: catName) do:	"For all classes"
			[ :selectedClass | 		"If #examples category"
			(selectedClass class organization listAtCategoryNamed: #examples) do:
				[ :selector | 		"Collect selectors"
				aCollection add: selectedClass class name , ' ' , selector ]]].
	(Smalltalk organization categories select: [ :cat | | siz |
		siz := 'MusicUI-' size.
		(cat size >= siz) and: [(cat copyFrom: 1 to: siz) = 'MusicUI-']])
	do: [ :catName | 
		 (Smalltalk organization superclassOrder: catName) do:	"For all classes"
			[ :selectedClass | 		"If #examples category"
			(selectedClass class organization listAtCategoryNamed: #examples) do:
				[ :selector | 		"Collect selectors"
				aCollection add: selectedClass class name , ' ' , selector ]]].
	^aCollection

MusicMagnitude class methodsFor: 'examples'
MODEExampleListView
	"Open a message list browser on all of the example methods in the MODE 
	categories--note the LeftShiftHack on the list view menu adding 'do it' 
	and 'browse class' items."
	"MusicMagnitude MODEExampleListView"

MusicMagnitude class methodsFor: 'examples'
MODEExampleMenu
	"Start up a menu of the examples and execute the selection, 
		possibly inspecting the result."
	"MusicMagnitude MODEExampleMenu"

	| classes messages labels selection returnValue |
	classes := OrderedCollection new.
	messages := OrderedCollection new.
	labels := OrderedCollection new.
	(Smalltalk organization categories select: [ :cat | | siz |
		siz := 'Music-' size.
		(cat size >= siz) and: [(cat copyFrom: 1 to: siz) = 'Music-']])
	do: [ :catName |
		 (Smalltalk organization superclassOrder: catName) do:	"For all classes"
			[ :selectedClass | 		"If #examples category"
			(selectedClass class organization listAtCategoryNamed: #examples) do:
				[ :selector | 		"Collect selectors"
				(selector includes: $:) ifFalse:
					[labels add: (selectedClass name, ' ', selector).
					classes add: selectedClass name.
					messages add: selector]]]].
	selection := (PopUpMenu labelArray: labels) startUp.
	selection = 0 ifTrue: [^nil].
"	selection := DialogView show: (PopUpMenu labelArray: labels) 
			withLabel: 'MODE 1.1 Examples'.
	selection = nil ifTrue: [^nil]."
	returnValue := (Smalltalk at: (classes at: selection)) 
			perform: (messages at: selection).
	returnValue == nil ifFalse: 
		[(returnValue isKindOf: Behavior)
			ifTrue: [Transcript show: 'Returned: ', returnValue printString; cr]
			ifFalse: [returnValue inspect]]

MusicMagnitude class methodsFor: 'examples'
modeRootName
	"Answer the directory name of the base of the MODE release fileset."
	"You may want to edit this to './' if your image is in that directory."
	"MusicMagnitude modeRootName"

	^'./mode/'

MusicMagnitude class methodsFor: 'examples'
MODEUIExampleListView
	"Open a message list browser on all of the example methods in the MODE 
	categories--note the LeftShiftHack on the list view menu adding 'do it' 
	and 'browse class' items."
	"MusicMagnitude MODEUIExampleListView"

MusicMagnitude class methodsFor: 'examples'
MODEUIExampleMenu
	"Start up a menu of the UI examples and execute the selection, 
		possibly inspecting the result."
	"MusicMagnitude MODEUIExampleMenu"

MusicMagnitude class methodsFor: 'examples'
MusicConstantDictionary
	"Answer the global music constants (mostly icons)."
	"MusicMagnitude MusicConstantDictionary inspect"
	"Browser browseAllCallsOn:
		(Smalltalk associationAt: #MusicConstants)"

	^MusicConstants

MusicMagnitude class methodsFor: 'examples'
utilityMessages
	"Select these utilities, inspect..."
	
"	MusicMagnitude MusicConstantDictionary
	(Browser browseAllCallsOn:
		(Smalltalk associationAt: #MusicConstants))
	RemoteSocketServer allInstances
	Voices
	EventLists
	MIDIVoice allInstances
	MIDIDevice
	SunMIDIPort instanceCount
	MIDIPort instanceCount
	ProPort instanceCount
	SunMIDIPort allNotesOff
	MIDIPort allNotesOff
	ProPort allSoundOff
	SampledSound allSubInstances
	EventListEditor allSubInstances
	Undeclared		DependentsFields
	AbstractEvent allSubInstances size
	DisplayItem allSubInstances
	DisplayListView allSubInstances
	Semaphore allInstances
	Semaphore instanceCount
	Process instanceCount
	Process allInstances

"

Duration class methodsFor: 'examples'
example
	"Print a simple message to the transcript demonstrating the various types."
	"Duration example"

	| me |
	me := Duration value: 1/4.
	Transcript show: me printString; cr;
		show: me asMS printString; cr.
	me inspect

Amplitude class methodsFor: 'examples'
example
	"Print a simple message to the transcript demonstrating the various types."
	"SymbolicLoudness nameMap inspect"
	"Amplitude example"

	| me |
	me := Amplitude value: #mf.
	Transcript show: me printString; cr;
		show: me asRatio printString; cr;
		show: me asMIDI printString; cr.
	me inspect

Pitch class methodsFor: 'examples'
example
	"Print a simple message to the transcript demonstrating the various types."
	"SymbolicPitch nameMap inspect"
	"Pitch example"

	| me |
	me := Pitch value: 'c3'.
	Transcript show: me printString; cr;
		show: me asHertz printString; cr;
		show: me asMIDI printString; cr.
	me inspect

Length class methodsFor: 'examples'
example
	"Demonstrate the use of an OrdinalMagnitude with a scale of length."
	"Length example"

	| a b c d e f |		"define six values with names."
	Length useTable.
	a := Length value: #sip.
	b := Length value: #gasp.
	c := Length value: #focus.
	d := Length value: #inhale.
	e := Length value: #gesture.
	f := Length value: #breath.
					"put them in some order."
	a << b.	b << c.	c << d.	d << e.	e << f.
					"now ask some queries and let them extrapolate."
	Transcript show: '(f > e) ', (f > e) printString; cr.
	Transcript show: '(f > b) ', (f > b) printString; cr.
	Transcript show: '(f =? f) ', (f =? f) printString; cr.
	Transcript show: '(f =? a) ', (f =? a) printString; cr.
	Transcript show: '(f >= a) ', (f >= a) printString; cr.
	Transcript show: '(d >= b) ', (d >= b) printString; cr.
	Transcript show: '(b >= d) ', (b >= d) printString; cr.
	Transcript show: '(f < a) ', (f < a) printString; cr.
	Transcript show: '(a < f) ', (a < f) printString; cr.
					"inspect them if you hold down <LEFT-SHIFT>"
	InputState default  leftShiftDown ifTrue: [self halt].
	Length allInstances asSortedCollection inspect

Sharpness class methodsFor: 'examples'
example
	"Demonstrate the use of an OrdinalMagnitude with a scale of sharpness."
	"Sharpness example"

	| a b c d e f |		"define six values with names."
	a := Sharpness value: #soft.
	b := Sharpness value: #nasal.
	c := Sharpness value: #round.
	d := Sharpness value: #high.
	e := Sharpness value: #loud.
	f := Sharpness value: #shrill.
					"put them in some order."
	a << b.	b << c.	c << d.	d << e.	e << f.
					"now ask some queries and let them extrapolate."
	Transcript show: '(f > e) ', (f > e) printString; cr.
	Transcript show: '(f > b) ', (f > b) printString; cr.
	Transcript show: '(f =? f) ', (f =? f) printString; cr.
	Transcript show: '(f =? a) ', (f =? a) printString; cr.
	Transcript show: '(f >= a) ', (f >= a) printString; cr.
	Transcript show: '(d >= b) ', (d >= b) printString; cr.
	Transcript show: '(b >= d) ', (b >= d) printString; cr.
	Transcript show: '(f < a) ', (f < a) printString; cr.
	Transcript show: '(a < f) ', (a < f) printString; cr.
					"inspect them if you hold down <LEFT-SHIFT>"
	InputState default  leftShiftDown ifTrue: [self halt].
	Sharpness values inspect

ConditionalDuration class methodsFor: 'examples'
example
	"Print a simple message to the transcript demonstrating the various types."
	"ConditionalDuration example"

	| t0 t me |
	t0 := Time millisecondClockValue.		"get the time"
					"make a duration 'until the argument is > 3000'"
	me := ConditionalDuration value: [ :x | x > 3000].
	Transcript cr; show: t0 printString; cr.
					"use it to wait 3000 msec."
	me waitUntil: [Time millisecondClockValue - t0].
	t := Time millisecondClockValue.	
	Transcript show: (t - t0) printString; cr.
					"make a duration 'until 3 seconds from now'"
	me := ConditionalDuration value: [ :x | Time millisecondClockValue > (t + 3000)].
					"wait it out."
	me waitUntil: [].
	t := Time millisecondClockValue.	
	Transcript show: (t - t0) printString; cr.
	me inspect

AbstractEvent class methodsFor: 'examples'
eventInspectExample
	"Demonstrate the creation of an AEvent."
	"AbstractEvent example"

	((AbstractEvent new) color: #green; shape: #round) inspect

AbstractEvent class methodsFor: 'examples'
example
	"Demonstrate the creation of an AEvent."
	"AbstractEvent example inspect"

	^(AbstractEvent new) color: #green; shape: #round

DurationEvent class methodsFor: 'examples'
eventInspectExample
	"Demonstrate the creation of a DEvent."
	"DurationEvent example inspect"

	(DurationEvent dur: 250 msec voice: #flute) inspect

DurationEvent class methodsFor: 'examples'
example
	"Demonstrate the creation of a DEvent."
	"DurationEvent example"

	^DurationEvent dur: 250 msec voice: #flute

EventList class methodsFor: 'examples'
creationExamples
	"Select the expressions below one-at-a-time and inspect the results."

"	EventList named: (EventList nextName) 
		fromPitches: #(36 38 40 43 45).
"
	(EventList named: (EventList nextName) 
		fromStartTimes: #(0 500 1000 1500 2000 2500 3000)) inspect.

"	(440 Hz, 250 msec, (#voice -> #flute)), 
		((1/4) => (471 Hz, (1/4) beat, (#voice -> #flute)))"

EventList class methodsFor: 'examples'
randomExample
	"Create an event list with random data."
	"EventList randomExample"
	"PitchTimeView randomExample"
	"(EventList newNamed: #pRand)
			addAll: (EventList randomExample);
			addAll: (EventList randomExample)"

	| rand size arr1 arr2 arr3 arr4 |
	rand := Random new.
	size := 32.
	arr1 := Array new: size.
	arr2 := Array new: size.
	arr3 := Array new: size.
	arr4 := Array new: size.
	1 to: size do: [ :i | arr1 at: i put: (rand nextIntFrom: 200 to: 250)].
	1 to: size do: [ :i | arr2 at: i put: (rand nextIntFrom: 32 to: 80)].
	1 to: size do: [ :i | arr3 at: i put: (rand nextIntFrom: 1 to: 5)].
	1 to: size do: [ :i | arr4 at: i put: (rand nextIntFrom: 48 to: 60)].
	^EventList named: 'random1'  
		fromSelectors: #(duration: loudness: voice: pitch:) 
		values: (Array with: arr1 with: arr2 with: arr3 with: arr4)

EventList class methodsFor: 'examples'
randomExample: length
	"Create an event list with random data."
	"EventList randomExample: 200"
	"PitchTimeView randomExample"

	| rand arr1 arr2 arr3 arr4 |
	rand := Random new.
	arr1 := Array new: length.
	arr2 := Array new: length.
	arr3 := Array new: length.
	arr4 := Array new: length.
	1 to: length do: [ :i | arr1 at: i put: (rand nextIntFrom: 200 to: 250)].
	1 to: length do: [ :i | arr2 at: i put: (rand nextIntFrom: 32 to: 80)].
	1 to: length do: [ :i | arr3 at: i put: (rand nextIntFrom: 1 to: 5)].
	1 to: length do: [ :i | arr4 at: i put: (rand nextIntFrom: 48 to: 60)].
	^EventList named: 'random1'  
		fromSelectors: #(duration: loudness: voice: pitch:) 
		values: (Array with: arr1 with: arr2 with: arr3 with: arr4)

EventList class methodsFor: 'examples'
randomExample: length from: data
	"Create an event list with random data."
	"(EventList randomExample: 64 
		from: ((#duration: -> (100@200)), (#pitch: -> (36@60)),
				(#ampl: -> (48@64)), (#voice: -> (1@4)))) edit"

	| rand arr sels i |
	rand := Random new.
	arr := Array new: data size.
	sels := Array new: data size.
	i := 1.
	data associationsDo: [ :item | | a |
		a := Array new: length.
		1 to: length do: [ :c | 
			a at: c put: (rand nextIntFrom: item value x to: item value y)].
		arr at: i put: a.
		sels at: i put: item key.
		i := i + 1.].
	^EventList named: EventList nextName
		fromSelectors: sels 
		values: arr

EventList class methodsFor: 'examples'
randomSWSSExample
	"Create an event list with random data appropriate for software sound synthesis."
	"EventList randomSWSSExample edit"
	"(EventList newNamed: #sRand)
			addAll: (EventList randomSWSSExample);
			addAll: (EventList randomSWSSExample)"

	| rand size params data |
	rand := Random new.
	size := 128.
	params := 9.
	data := Array new: params.
	1 to: params do:
		[ :i | data at: i put: (Array new: size)].
	1 to: size do: 
		[ :i | (data at: 1) at: i put: (rand nextIntFrom: 200 to: 450)].	"dur"
	1 to: size do: 
		[ :i | (data at: 2) at: i put: (rand nextFrom: 0.3 to: 0.7)].		"ampl"
	1 to: size do: 
		[ :i | (data at: 3) at: i put: (rand nextFrom: 60 to: 500)].		"pitch"
	1 to: size do: 
		[ :i | (data at: 4) at: i put: (rand nextIntFrom: 1.0 to: 5.0)].	"ratio"
	1 to: size do: 
		[ :i | (data at: 5) at: i put: (rand nextFrom: 1.0 to: 8.0)].		"index"
	1 to: size do: 
		[ :i | (data at: 6) at: i put: (rand nextFrom: 0.05 to: 0.1)].	"attack"
	1 to: size do: 
		[ :i | (data at: 7) at: i put: (rand nextFrom: 0.05 to: 0.1)].	"decay"
	1 to: size do: 
		[ :i | (data at: 8) at: i put: (rand nextFrom: 0.01 to: 0.1)].	"i_attack"
	1 to: size do: 
		[ :i | (data at: 9) at: i put: (rand nextFrom: 0.05 to: 0.1)].	"i_decay"
	^EventList named: #SWSSExample
		fromSelectors: #(duration: loudness: pitch: cmratio: index: 
					attack: decay: iAttack: iDecay:) 
		values: data

EventList class methodsFor: 'examples'
randomSWSSExample2
	"Create an event list with random data appropriate for software sound synthesis."
	"EventList randomSWSSExample2 edit"
	"((EventList newNamed: #sRand)
			addAll: (EventList randomSWSSExample2);
			addAll: (EventList randomSWSSExample2)) edit"

	| rand size params data |
	rand := Random new.
	size := 64.
	params := 6.
	data := Array new: params.
	1 to: params do:
		[ :i | data at: i put: (Array new: size)].
	1 to: size do: 
		[ :i | (data at: 1) at: i put: (rand nextIntFrom: 300 to: 750)].	"dur"
	1 to: size do: 
		[ :i | (data at: 2) at: i put: (rand nextFrom: 0.35 to: 1.0)].		"ampl"
	1 to: size do: 
		[ :i | (data at: 3) at: i 
					put: ((rand nextIntFrom: 42 to: 72) truncateTo: 2)].	"pitch"
	1 to: size do: 
		[ :i | (data at: 4) at: i put: (LinearFunction exampleEnvelope)].	"envelope"
	1 to: size do: 
		[ :i | (data at: 5) at: i put: (rand nextFrom: 0.0 to: 1.0)].		"position"
	1 to: size do: 
		[ :i | (data at: 6) at: i put: (rand nextFrom: 0.3 to: 1.0)].		"duty"
	^EventList named: #SWSSExample
		fromSelectors: #(duration: loudness: pitch: envelope: position: duty:) 
		values: data

EventList class methodsFor: 'examples'
scaleExampleFrom: start to: stop in: dur
	"Answer an event list with a scale."
	"EventList scaleExampleFrom: 48 to: 60 in: 1500"
	"MIDIDevice MIDIPlayExample2"

	| size arr4 ndur |
	size := stop - start.
	ndur := (dur / size) truncated.
	arr4 := Array new: size.
	0 to: size-1 do: [ :i | arr4 at: i+1 put: (start + i)].
	^EventList named: EventList nextName  
		fromSelectors: #(duration: loudness: voice: pitch:) 
		values: (Array with: ndur with: 72 with: 1 with: arr4)

EventList class methodsFor: 'examples'
sentenceExample
	"Create an event list for a beautiful sentence."
	"EventList sentenceExample"

	EventList named: 'phrase2'  
		fromSelectors: #(duration: loudness: phoneme:) 
		values: (Array with: #(420 420 720 354    408 420 615 570 
					369 312 369    690 462 477 660 ) 
				with: #(0.4 0.3 0.9 0.6    0.42 0.32 0.8 0.5 
					0.44 0.52 0.2   0.94 0.62 0.46 0.34 ) 
				with: #(#und #die #fra #gen    #sind #die #sae #tze 
					#die #ich #nicht    #aus #spre #chen #kann)).
	(EventList named: 'phrase2') inspect

EventList class methodsFor: 'examples'
wordExample
	"Create an event list for a long word."
	"EventList wordExample"

	EventList named: 'phrase1'  
		fromSelectors: #(duration: loudness: phoneme:) 
		values: (Array with: #(595 545 545 540 570 800 540) 
				with: #(0.8 0.4 0.5 0.3 0.2 0.7 0.1) 
				with: #(#dun #kel #kam #mer #ge #sprae #che)).
	(EventList named: 'phrase1') inspect

MusicEvent class methodsFor: 'examples'
eventInspectExample
	"Demonstrate the terse format of event description."
	"MusicEvent eventInspectExample"

	(440 Hz, 250 msec, (#voice -> #flute), 0.7071 ampl) inspect
"	((880 Hz, 250 msec, (#voice -> #flute), 0.7071 ampl) accent: #sfz) inspect"

MusicEvent class methodsFor: 'examples'
example
	"Demonstrate the terse format of event description."
	"MusicEvent example inspect"

	^(440 Hz, 250 msec, (#voice -> #flute), 0.7071 ampl)
"	((880 Hz, 250 msec, (#voice -> #flute), 0.7071 ampl) accent: #sfz) inspect"

Function class methodsFor: 'examples'
averagedFunctionFileExample
	"Function usage example; read a function from a binary file and view it."
	"Function averagedFunctionFileExample"

	FunctionView onFunction: ((Function readFloatsFrom: 'snd/yy/ec/syl/y2.env') averagedTo: 32)

Function class methodsFor: 'examples'
fileExample
	"Function usage example; read a function from a binary file and view it."
	"Function fileExample inspect"

	^Function readFloatsFrom: 'snd/yy/ec/syl/y2.env'

Function class methodsFor: 'examples'
functionFileExample
	"Function usage example; read a function from a binary file and view it."
	"Function functionFileExample"

	FunctionView onFunction: Function default

Function class methodsFor: 'examples'
functionPlayExample
	"Function usage example; make a roll-type eventList and apply a crescendo/decrescendo to it"
	"Function functionPlayExample"

	| temp fcn |
	temp := EventList newNamed: #test3.
	(0 to: 4000 by: 50) do: 	"4 seconds, 20 notes per second"
			[ :index |			"add the same note"
			temp add: (MusicEvent dur: 100 pitch: 36 ampl: 100) 
					at: index].
	fcn := LinearFunction from: #((0 @ 0) (0.5 @ 1) (1 @ 0)).
	temp applyFunction: fcn to: #loudness.
	temp play

Function class methodsFor: 'examples'
functionViewExample
	"Function usage example; make a z-z function and view it."
	"Function functionViewExample"

	FunctionView onFunction: (Function from: #( 0 1 0 0.5 1.0 0.5 0 1 0 0.3 0.6 0.9 1 0 1 0))

Function class methodsFor: 'examples'
maxedFunctionFileExample
	"Function usage example; read a function from a binary file and view it."
	"Function maxedFunctionFileExample"

	FunctionView onFunction: ((Function readFloatsFrom: 'snd/yy/ec/syl/y2.env') maxTo: 128 win: 32)

Function class methodsFor: 'examples'
randomViewExample
	"Function usage example; make a random walk fcn and view it."
	"Function randomViewExample"

	FunctionView onFunction: (Function randomOfSize: 64 from: 0.2 to: 0.9)

Function class methodsFor: 'examples'
randomViewExample2
	"Function usage example; make a random walk fcn and view it."
	"Function randomViewExample2"

	FunctionView onFunction: (Function randomWalkSize: 128 from: 0.3 to: 0.7)

LinearFunction class methodsFor: 'examples'
exampleEnvelope
	"Answer a LinSeg of a typical envelope function."
	"LinearFunction exampleEnvelope"
	"FunctionView onFunction: (LinearFunction from: pts)"

	| rand pts size x y |
	rand := Random new.
	size := rand nextIntFrom: 4 to: 7.
	pts := Array new: size.
	pts at: 1 put: 0@0.
	pts at: size put: 1@0.
	x := 0.
	y := 0.8.
	2 to: size - 1 do:
		[ :i |
		x := x + (rand nextFrom: 0.1 to: 0.25).
		y := ((y + (rand nextFrom: -0.3 to: 0.3)) min: 1.0) max: 0.0.
		x < 0.95 ifTrue: [pts at: i put: (x@y)]].
	^LinearFunction from: pts

LinearFunction class methodsFor: 'examples'
linearExample
	"Make a LinSeg and answer a value."
	"LinearFunction linearExample"

	| fcn |
	fcn := LinearFunction ofSize: 2.
	fcn add: (0@0.5); add: (1@1).
	Transcript show: (fcn at: 0.14) printString; cr.
	fcn inspect

LinearFunction class methodsFor: 'examples'
linearViewExample
	"Make a LinSeg and open a view on its form."
	"LinearFunction linearViewExample"

	FunctionView onFunction: 
		(LinearFunction from: #((0 0) (0.2 1) (0.8 0.5) (1 0)))

SplineFunction class methodsFor: 'examples'
splineExample
	"Make a SplineSeg."
	"SplineFunction splineExample"

	| fcn |
	fcn := SplineFunction from: #((0 1) (0.35 1.3) (0.65 0.7) (1 1)).
	fcn inspect.
"	^fcn at: 0.14 
"

SplineFunction class methodsFor: 'examples'
splineViewExample
	"Make a SplineSeg and open a view on its form."
	"SplineFunction splineSegViewExample"

	FunctionView onFunction: 
		(SplineFunction from: #((0 0.5) (0.35 0.7) (0.65 0.2) (1 0.5)))

ExponentialFunction class methodsFor: 'examples'
expADSRViewExample
	"Make an exp seg and open a view on its form."
	"ExponentialFunction expsegViewExample"

	FunctionView onFunction: 
		(ExponentialFunction from: #((0 0 -5) (0.2 1 -3) (0.8 0.5 -2) (1 0)))

ExponentialFunction class methodsFor: 'examples'
expASRViewExample
	"Make an exp seg and open a view on its form."
	"ExponentialFunction expASRViewExample"

	FunctionView onFunction: 
		(ExponentialFunction from: #((0 0 -3) (0.3 0.9 0) (0.7 0.9 -3) (1 0)))

ExponentialFunction class methodsFor: 'examples'
expsegViewExample
	"Make an exp seg and open a view on its form."
	"ExponentialFunction expsegViewExample"

	FunctionView onFunction: 
		(ExponentialFunction from: #((0 0 -3) (0.2 1 -5) (0.6 0.5 -1) (1 0)))

FourierSummation class methodsFor: 'examples'
fourierExample
	"Make a Sine summation that approaches a square wave"
	"FourierSummation fourierExample"

	| fcn |
	fcn := FourierSummation from: #((1 1 0) (3 0.3 0) (5 0.2 0) 
							(7 0.15 0) (9 0.11 0) (11 0.09 0)).
	Transcript show: (fcn at: 0.14) printString; cr.
	fcn inspect

FourierSummation class methodsFor: 'examples'
fourierViewExample
	"Make a Sine summation that approaches a square wave and open a view on it."
	"FourierSummation fourierViewExample"

	FunctionView onFunction: (FourierSummation from: #((1 0.5 0) (3 0.3 0) (5 0.2 0) 
							(7 0.17 0) (9 0.15 0) (11 0.1 0)))

MIDIVoice class methodsFor: 'examples'
MIDIPlayExample1
	"Play some random notes on a voice on a device on a port."
	"MIDIVoice MIDIPlayExample1"
	"MIDIPort allNotesOff"

	| voice device port scale |
	port := MIDIPort default writeStream.
	device := MIDIDevice on: port.
	voice := MIDIVoice on: device.
	scale := EventList scaleExampleFrom: 48 to: 60 in: 2000.
"	scale eventsDo: [ :e | e duration: (e duration * 3)]."
	voice play: scale; close

MIDIVoice class methodsFor: 'examples'
MIDIPlayExample2
	"Play some random notes on a voice on a device on a port."
	"MIDIVoice MIDIPlayExample2"
	"MIDIPort allNotesOff"
	"MIDIVoice instanceCount"
	"MIDIDevice instanceCount"
	"SunMIDIPort instanceCount"

	| events voice |
	events := (EventList randomExample: 256 
		from: ((#duration: -> (60@150)), (#pitch: -> (48@60)),
				(#ampl: -> (64@94)), (#voice: -> (1@1)))).
	voice := MIDIVoice default.
	voice play: events.
	(Delay forSeconds: 8) wait.
	voice close

MIDIVoice class methodsFor: 'examples'
MIDIVoiceInspectExample
	"MIDIVoice MIDIVoiceInspectExample"

	(MIDIVoice on: (MIDIDevice on: (MIDIPort default writeStream))) inspect

CsoundVoice class methodsFor: 'examples'
randomExampleToFileAndEdit
	"Set up a CsoundVoice printing to the named file and play some random notes."
	"CsoundVoice randomExampleToFileAndEdit"

	self randomExampleToFileNamed: 'rand.sco'

CsoundVoice class methodsFor: 'examples'
randomExampleToFileNamed: fname
	"Set up a CmusicVoice printing to the named file and play some random notes."
	"CsoundVoice randomExampleToFileNamed: 'rand.sco'"

	 | file list rand voice |
	file := fname asFilename writeStream.
	rand := Random new.
	list := EventList randomExample: 64.
	list do: [ :ass | | ev |
		ev := ass event.
		ev at: #pos put: rand next.
		ev at: #prop1 put: (rand nextFrom: 320 to: 480).
		ev at: #prop2 put: (rand nextIntFrom: 12000 to: 23000)].
	voice := CsoundVoice newNamed: '1' onStream: file.
	voice addMap: #pos.
	voice addMap: [ :e | ((e at: #prop1) / 1000) printString].
	voice addMap: #prop2.
	voice play: list.
	file close.
	(Filename named: fname) edit

CmixVoice class methodsFor: 'examples'
randomExampleToFileAndEdit
	"Set up a CmixVoice printing to the named file and play some random notes."
	"CmixVoice randomExampleToFileAndEdit"

	self randomExampleToFileNamed: 'rand.m'

CmixVoice class methodsFor: 'examples'
randomExampleToFileNamed: fname
	"Set up a CmixVoice printing to the named file and play some random notes."
	"CmixVoice randomExampleToFileNamed: 'rand.m'"

	 | file list rand voice |
	file := fname asFilename writeStream.
	rand := Random new.
	list := EventList randomExample: 64.
	list do: [ :ass | | ev |
		ev := ass event.
		ev at: #pos put: rand next.
		ev at: #prop1 put: (rand nextFrom: 320 to: 480).
		ev at: #prop2 put: (rand nextIntFrom: 12000 to: 23000)].
	voice := CmixVoice newNamed: 'fm_two' onStream: file.
	voice addMap: #pos.
	voice addMap: [ :e | ((e at: #prop1) / 1000) printString].
	voice addMap: #prop2.
	voice play: list.
	file close.
	(Filename named: fname) edit

CmusicVoice class methodsFor: 'examples'
randomExampleToFileAndEdit
	"Set up a CmusicVoice printing to the named file and play some random notes."
	"CmusicVoice randomExampleToFileAndEdit"

	self randomExampleToFileNamed: 'rand.sc'

CmusicVoice class methodsFor: 'examples'
randomExampleToFileNamed: fname
	"Set up a CmusicVoice printing to the named file and play some random notes."
	"CmusicVoice randomExampleToFileNamed: 'rand.sc'"

	 | file list rand voice |
	file := fname asFilename writeStream.
	rand := Random new.
	list := EventList randomExample: 64.
	list do: [ :ass | | ev |		"add a few extra properties"
		ev := ass event.
		ev at: #pos put: rand next.
		ev at: #prop1 put: (rand nextFrom: 320 to: 480).
		ev at: #prop2 put: (rand nextIntFrom: 12000 to: 23000)].
	voice := CmusicVoice newNamed: 'violin' onStream: file.
	voice parameterMap at: 3 put: [ :e | #(in1 in2 in3 in4) at: e voice].
	voice addMap: [ :e | (e pitch asHz value printString clipTo: 5), 'Hz'].
	voice addMap: #pos.
	voice addMap: [ :e | ((e at: #prop1) / 10) truncated printString].
	voice addMap: #prop2.
	voice play: list.
	file close.
	(Filename named: fname) edit

CmusicVoice class methodsFor: 'examples'
randomExampleToTranscript
	"Set up a CmusicVoice printing to the Transcript and play some random notes."
	"CmusicVoice randomExampleToTranscript"

	 (CmusicVoice newNamed: 'violin' onStream: Transcript) 
			play: (EventList randomExample: 8)

OpcodeVoice2 class methodsFor: 'examples'
midiFileExample
	"Read and edit a midi file dump."
	"OpcodeVoice2 midiFileExample"

	(OpcodeVoice2 newOn: MusicMagnitude modeRootName, 'scores/fuga1.midi') loadOnto: (EventList newNamed: #fuga1).
	(EventList named: #fuga1) edit

SampledSound class methodsFor: 'examples'
defaultName
	"Answer the default file name."

	^MusicMagnitude modeRootName, 'data/kombination.snd'

SampledSound class methodsFor: 'examples'
fileExample
	"Answer a typical sound read in from a file."
	"SampledSound fileExample inspect"

	^SampledSound fromFile: SampledSound defaultName

SampledSound class methodsFor: 'examples'
fileExampleInspect
	"Answer a typical sound read in from a file; inspect it."
	"SampledSound fileExampleInspect"

	(SampledSound fromFile: SampledSound defaultName) inspect

SampledSound class methodsFor: 'examples'
immediateInspect
	"Answer a sampled sound from immediate data; inspect it."
	"SampledSound immediateInspect"

	| t |
	 t := Array new: 64000. 
	 0 to: 255 do: 
		[ :i | 1 to: 250 do:
			[ :j | t at: ((i * 250) + j) 
			put: (j / 250 * 32000 - 16000) asInteger]].
	(SampledSound fromData: t named: 'ramp' 
			rate: 32000 channels: 1 format: #lin16Bit) inspect

SampledSound class methodsFor: 'examples'
rmsViewExample
	"Read a sampled sound from the file, take the rms into 64 values, and edit that."
	"SampledSound rmsViewExample"

	| arr snd |
	arr := Array new: 128 withAll: 0.0.
	snd := SampledSound fileExample.
	snd sampleMaxFrom: 1 to: snd size into: arr.
	(Function from: arr) edit.

SampledSound class methodsFor: 'examples'
sawtooth
	"Create a file named 'data.out' with raw sawtooth samples."
	"SampledSound sawtooth"

	| sr dur freq stream waveLen incr samps |
	sr := 16000.
	dur := 4.
	freq := 800.
	waveLen := sr // freq.
	incr := 32767 // waveLen.
	samps := sr * dur.
	stream := 'data.out' asFilename writeStream binary.
	0 to: samps do: 
		[ :i | | index |
		index := i \\ waveLen.
		stream nextWordPut: (index * incr) asInteger].
	stream close

SampledSound class methodsFor: 'examples'
sawtoothDataFile
	"Create a file named 'data.out' with raw sawtooth samples."
	"SampledSound sawtoothDataFile"

	| sr dur freq stream waveLen incr samps |
	sr := 16000.
	dur := 4.
	freq := 800.
	waveLen := sr // freq.
	incr := 32767 // waveLen.
	samps := sr * dur.
	stream := 'data.out' asFilename writeStream binary.
	0 to: samps do: 
		[ :i | | index |
		index := i \\ waveLen.
		stream nextWordPut: (index * incr) asInteger].
	stream close

ProPort class methodsFor: 'examples'
SoundOff
	"Turn all sound off."
	"ProPort MIDIOff"

	ProPort allSoundOff

ProPort class methodsFor: 'examples'
soundOutputExample
	"Play a soundfile."
	"ProPort soundOutputExample"

	SoundPort default playFile: (SampledSound fileExample)

EventGenerator class methodsFor: 'examples'
randomExample
	"Play random examples from the set of examples in my subclasses"
	"[Sensor anyButtonPressed] whileFalse: [EventGenerator randomExample]"

	((Smalltalk at: 
			(#(Cloud DynamicCloud SelectionCloud DynamicSelectionCloud "Peal") 
					atRandom)) 
		randomExample) play

Cluster class methodsFor: 'examples'
example1
	"Cluster example1"
	"play a low 2 second cluster"

	(Cluster  dur: 2.0
		list: (EventList named: #clus1)
		ampl: (80 to: 100) 
		voice: 6) eventList edit "playPrim" "inspect"

Cluster class methodsFor: 'examples'
example2
	"Cluster example2"
	"play a low 2 second cluster"

	(Cluster  dur: 2.0
		pitchSet: #(48 49 50 51 52 53 54 55)
		ampl: 100
		voice: 6) edit "play"

Roll class methodsFor: 'examples'
rollExample
	"create and edit some rolls"

	"((Roll length: 2000 rhythm: 100 note: 48) ampl: 100) eventList"
	"((Roll length: 2000 rhythm: 100 note: 48) ampl: 100) eventList edit"
	"((Roll length: 2000 rhythm: 50 note: 60) ampl: 100) eventList playPrim"

Chord class methodsFor: 'examples'
example
	"Create and edit some chords"

	"(Chord majorTriadOn: 'c3' inversion: 0) inspect"

	"((Chord majorTetradOn: 'f2' inversion: 2) duration: 1.0) inspect"

	"((Chord majorTetradOn: 'g2' inversion: 1) duration: 1.0) inspect"

Ostinato class methodsFor: 'examples'
ostinatoExamples
	"create and edit some ostinati"

	"Ostinato onList: (EventList named: #scale1)"
	"Ostinato onList: (EventList named: #scale1) edit"
	"Ostinato newNamed: #scaleO onList: (EventList named: #scale1)"
	"(Ostinato named: #scaleO) play"
	"(Ostinato named: #scaleO) playOn: 1 at: 0"
	"(Ostinato named: #scaleO) stop"

MIDIEcho class methodsFor: 'examples'
arpeggiateMIDI
	"MIDIEcho arpeggiateMIDI"

	((MIDIEcho new) 
		process: 
			[ :e | 
			^((Arpeggio on: 
				((Chord majorTetradOn: (e pitch) inversion: 0)
					duration: 1.0)
				delay: 0.1) eventList)]) 
		play

MIDIEcho class methodsFor: 'examples'
chordMIDI
	"MIDIEcho chordMIDI"

	((MIDIEcho new) 
		process: 
			[ :e | 
			^(((Chord majorTetradOn: (e pitch) inversion: 0)
					duration: 1000; loudness: 80) "eventList")]) 
		play

MIDIEcho class methodsFor: 'examples'
echoMIDI
	"MIDIEcho echoMIDI"

	MIDIEcho new play

MIDIEcho class methodsFor: 'examples'
transposeMIDI
	"MIDIEcho transposeMIDI"

	((MIDIEcho new) 
		process: 
			[ :e | 
			e pitch: (MIDIPitch value: (e pitch value + 24)). e]) 
		play

Cloud class methodsFor: 'examples'
dictionaryExample
	"Answer an initialized Cloud generated from the given property map dictionary."
	"Cloud dictionaryExample"

	(Cloud fromDictionary: ((#duration -> 5000), 
			(#pitch -> (48 to: 70)),
			(#loudness -> (50 to: 100)), 
			(#voice -> (1 to: 4)), 
			(#density -> 15))) eventList edit

Cloud class methodsFor: 'examples'
example1
	"Create a low 6 second stochastic cloud with 5 events per second"
	"Cloud example1"

	(Cloud  dur: 6
		pitch: (48 to: 60)  
		ampl: (80 to: 120) 
		voice: (1 to: 4)
		density: 5) eventList edit "asScore" "play" "inspect"

Cloud class methodsFor: 'examples'
randomExample
	"Create a stochastic cloud with random properties."
	"Cloud randomExample"

	| rand pBase score |
	rand := Random new.
	pBase := 20 + (rand next * 60) rounded.
	score := (Cloud  dur: (2 + (rand next * 6) asInteger)
		pitch: (pBase to: (pBase + (rand next * 40)) rounded)  
		ampl: (80 to: 120) 
		voice: (1 to: 8)
		density: (rand next * 20)) eventList.
"	Processor yield.
	score play.
	(Delay forMilliseconds: (score duration + 1000)) wait
"
"	score inspect
"
	score edit

Cloud class methodsFor: 'examples'
randomExample2
	"Create a stochastic cloud with random properties."
	"Cloud randomExample2"

	| rand pBase score |
	rand := Random new.
	pBase := 20 + (rand next * 60) rounded.
	score := (Cloud  dur: (2 + (rand next * 6))
		pitch: (pBase to: (pBase + (rand next * 40)) rounded)  
		ampl: (80 to: 120) 
		voice: (1 to: 8)
		density: (rand next * 20)) eventList.
	score edit

SelectionCloud class methodsFor: 'examples'
example1
	"Create a low 4 second cloud selecting pitch, amp and voice from value arrays."
	"SelectionCloud example1"

	(SelectionCloud  dur: 4  
		pitch: #(48 50 52 55 57 )
		ampl: #(80 80 120)
		voice: #(1 2 3 4)
		density: 8) eventList edit "play" "inspect"

SelectionCloud class methodsFor: 'examples'
exampleRand
	"SelectionCloud exampleRand"
	"play a selection cloud"

	| rand pBase pArray aArray score |
	rand := Random new.
	pBase := 20 + (rand next * 40) rounded.
	pArray := Array new: 2 + ((rand next * 4) rounded).
	1 to: pArray size do: [:ind | pArray at: ind put: (pBase+(rand  next * 12) rounded)].
	pBase := 20 + (rand next * 60) rounded.
	aArray := Array new: 2 + ((rand next * 6) rounded).
	1 to: aArray size do: [:ind | aArray at: ind put: (pBase+(rand  next * (120 - pBase)) rounded)].
	score := (SelectionCloud  dur: (3 + (rand next * 4) rounded)
		pitch: pArray
		ampl: aArray
		voice: (1 to: 8)
		density: (3 + (rand next * 15) rounded)) eventList.
	score inspect.
"	score play.
	(Delay forMilliseconds: (score duration + 1000)) wait
"

SelectionCloud class methodsFor: 'examples'
randomExample
	"Create a selection cloud with random properties."
	"SelectionCloud randomExample"

	| rand pBase pArray aArray score |
	rand := Random new.
	pBase := 20 + (rand next * 40) rounded.
	pArray := Array new: 2 + ((rand next * 4) rounded).
	1 to: pArray size do: [:ind | pArray at: ind put: (pBase+(rand  next * 12) rounded)].
	pBase := 20 + (rand next * 60) rounded.
	aArray := Array new: 2 + ((rand next * 6) rounded).
	1 to: aArray size do: [:ind | aArray at: ind put: (pBase+(rand  next * (120 - pBase)) rounded)].
	score := (SelectionCloud  dur: (3 + (rand next * 4) rounded)
		pitch: pArray
		ampl: aArray
		voice: (1 to: 8)
		density: (3 + (rand next * 15) rounded)) eventList.
	score inspect.
"	score play.
	(Delay forMilliseconds: (score duration + 1000)) wait
"

DynamicSelectionCloud class methodsFor: 'examples'
example1
	"Create a selection cloud that focuses onto a trill."
	"DynamicSelectionCloud example1"

	(DynamicSelectionCloud  dur: 4
		pitch: #( #(36 38 40 43 45) #(53 54) )
		ampl: #(80 80 120)
		voice: #(1 3 5 7)
		density: 16) eventList "edit" "asScore" "playPrim" inspect

DynamicSelectionCloud class methodsFor: 'examples'
example2
	"Create a selection cloud that makes a transition from one pair of notes to another"
	"DynamicSelectionCloud example2"

	(DynamicSelectionCloud dur: 4
		pitch: #( #(60 62 64) #(72 74 76) )
		ampl: #(80 80 120)
		voice: #(1 3 5 7)
		density: 12) eventList edit "inspect" "play"

DynamicSelectionCloud class methodsFor: 'examples'
randomExample
	"Answer a dynamic selection cloud with random properties."
	"DynamicSelectionCloud randomExample"

	| rand pBase pArray1 pArray2 aArray1 score |
	rand := Random new.
	pBase := rand nextIntFrom: 42 to: 54.
	pArray1 := Array new: (rand nextIntFrom: 2 to: 4).
	1 to: pArray1 size do: 
			[:ind | pArray1 at: ind put: (rand nextIntFrom: pBase to: pBase + 12)].
	pBase := rand nextIntFrom: 60 to: 72.
	pArray2 := Array new: (rand nextIntFrom: 4 to: 8).
	1 to: pArray2 size do: 
			[:ind | pArray2 at: ind put: (rand nextIntFrom: pBase to: pBase + 12)].
	pBase := rand nextIntFrom: 40 to: 60.
	aArray1 := Array new: (rand nextIntFrom: 2 to: 6).
	1 to: aArray1 size do: 
			[:ind | aArray1 at: ind put: (rand nextIntFrom: pBase to: pBase + 50)].
	Transcript cr; show: 'DynSelCloud: ', pArray1 printString; cr; 
			show: pArray2 printString; cr; cr.
	score := (DynamicSelectionCloud  dur: 8
		pitch: (Array with: pArray1 with: pArray2)
		ampl: aArray1
		voice: (1 to: 8)
		density: (rand nextIntFrom: 5 to: 15)) eventList.
"	score inspect.
"
"	score play.
	(Delay forMilliseconds: (score duration + 1000)) wait
"
	score edit

DynamicCloud class methodsFor: 'examples'
crescendoExample
	"Create an 8-second cloud that goes from soft to loud on the same pitch."
	"DynamicCloud crescendoExample"

	(DynamicCloud  dur: 8  
		pitch: (20 to: 20)
		ampl: #((20 to: 30) (80 to: 120))
		voice: (1 to: 1)
		density: 20) eventList "edit" play "inspect"

DynamicCloud class methodsFor: 'examples'
example1
	"Create a 6-second cloud that goes from low to high and soft to loud."
	"DynamicCloud example1"

	(DynamicCloud  dur: 6  
		pitch: #((30 to: 44) (50 to: 50))
		ampl: #((20 to: 40) (90 to: 120))
		voice: (1 to: 4)
		density: 20) eventList edit "play" "inspect"

DynamicCloud class methodsFor: 'examples'
example4
	"DynamicCloud example4"
	"play a 6 second cloud that focuses on its center"

	(DynamicCloud  dur: 6  
		pitch: #((30 to: 54) (40 to: 40))
		ampl: #((20 to: 40) (90 to: 120))
		voice: (1 to: 8)
		density: 10) eventList "edit" "play" inspect

DynamicCloud class methodsFor: 'examples'
focusExample
	"Create a 6-second cloud that focuses on its center."
	"DynamicCloud focusExample"

	(DynamicCloud  dur: 6  
		pitch: #((30 to: 54) (40 to: 40))
		ampl: #((20 to: 40) (90 to: 120))
		voice: (1 to: 8)
		density: 10) eventList edit "play" "inspect"

DynamicCloud class methodsFor: 'examples'
randomExample
	"Create a dynamic second cloud with random properties."
	"DynamicCloud randomExample edit"

	| rand |
	rand := Random new.
"	^DynamicCloud  dur: 6
		pitch: #((30 to: 54) (40 to: 40))
		ampl: #((20 to: 40) (90 to: 120))
		voice: (1 to: 8)
		density: 10)
"
	^DynamicCloud  dur: (rand nextIntFrom: 3 to: 8)  
		pitch: (Array with: ((rand nextIntFrom: 24 to: 48) 
					to: (rand nextIntFrom: 24 to: 54))
				with: ((rand nextIntFrom: 48 to: 60)
					to: (rand nextIntFrom: 60 to: 72)))
		ampl: (Array with: ((rand nextIntFrom: 24 to: 36)
					to: (rand nextIntFrom: 36 to: 48))
				with: ((rand nextIntFrom: 72 to: 88)
					to: (rand nextIntFrom: 80 to: 112)))
		voice: (1 to: 4)
		density: (rand nextIntFrom: 4 to: 16)

SunMIDIPort class methodsFor: 'examples'
MIDIOff
	"Turn all notes off."
	"SunMIDIPort MIDIOff"

	MIDIPort allNotesOff

SunMIDIPort class methodsFor: 'examples'
MIDIPlayExample1
	"Play a few notes out MIDI from the port level."
	"SunMIDIPort MIDIPlayExample1"
	"MIDIPort allNotesOff"
	"SunMIDIPort initialize"
	"MStream inspect"

	| port del |
	port := MIDIPort default writeStream.
	del := 150.		"ticks/note."
	#(36 38 40 41 43 45 47 48) do: [ :p |
		port play: p at: 0 amp: 84 voice: 1.
		port play: p at: del amp: 0 voice: 1].
	(Delay forMilliseconds: (9*del)) wait.
	port close

SunMIDIPort class methodsFor: 'examples'
MIDIPlayExample2
	"Play a few notes out MIDI from the port level."
	"SunMIDIPort MIDIPlayExample2"
	"MIDIPort allNotesOff"
	"SunMIDIPort initialize"
	"MStream inspect"

	| port del |
	port := MIDIPort default writeStream.
	del := 150.		"ticks/note."
	#(36 38 40 41 43 45 47 48) do: [ :p |
		port play: p at: del dur: 450 amp: 84 voice: 1].
	port notesOff.
	(Delay forMilliseconds: (9*del+ 450)) wait.
	port close

MIDIDevice class methodsFor: 'examples'
MIDIPlayExample1
	"Play a few notes out MIDI from the device level."
	"MIDIDevice MIDIPlayExample1"
	"MIDIPort allNotesOff"
	"MIDIDevice initialize"
	"MStream inspect"

	| device port scale t0 |
	port := MIDIPort default writeStream.
	device := MIDIDevice on: port.
	scale := EventList scaleExampleFrom: 48 to: 60 in: 2500.
	scale eventsDo: [ :e | e duration: (e duration * 3)].
	t0 := 0.
	scale events do: [ :ass |
		device play: ass value at: (ass key value - t0).
		t0 := ass key value].
	port notesOff.
	(Delay forMilliseconds: 3000) wait.
	device close.
	Transcript show: ' done.'; cr.
"	MIDIPort allNotesOff"

MIDIDevice class methodsFor: 'examples'
MIDIPlayExample2
	"Play a few notes out MIDI from the device level."
	"MIDIDevice MIDIPlayExample2"
	"MIDIPort allNotesOff"
	"MIDIDevice initialize"
	"MStream inspect"

	| device port scale t0 |
	port := MIDIPort default writeStream.
	device := MIDIDevice on: port.
	scale := EventList scaleExampleFrom: 28 to: 103 in: 2500.
	t0 := 0.
	scale events do: [ :ass |
		device play: ass value at: (ass key value - t0).
		t0 := ass key value].
	port notesOff.
	(Delay forMilliseconds: 3000) wait.
	device close.
	Transcript show: ' done.'; cr.
"	MIDIPort allNotesOff"

DisplayList class methodsFor: 'examples'
exampleHierarchical
	"Create and answer a large display list with a lines, strings, and visuals."
	"(DisplayList exampleHierarchical) display"

	| dl1 dl2 dl3 dl4 dl5 dl6 rand size |
	size := 100.
	dl1 := DisplayList new.
	dl2 := DisplayList new.
	dl3 := DisplayList new.
	dl4 := DisplayList new.
	dl5 := DisplayList new.
	dl6 := DisplayList new.
	rand := Random new.
	10 timesRepeat:
		[ | pt |
		pt := (rand next * size) rounded @ ((rand next * size) rounded).
		dl1 add: ((DisplayString string: (pt printString) 
				offset: pt) color: (ColorValue random: rand))].
	10 timesRepeat:
		[ | x y w h |
		x := (rand next * size) rounded.		y := (rand next * size) rounded.
		w := (rand next * size) rounded.		h :=  (rand next * size) rounded.
		dl2 add: ((DisplayRectangle offset: (x@y) extent: (w@h))
				color: (ColorValue random: rand); fill: true)].
	10 timesRepeat:
		[ | x y w h |
		x := (rand next * size) rounded.		y := (rand next * size) rounded.
		w := (rand next * size) rounded.		h :=  (rand next * size) rounded.
		dl3 add: ((DisplayRectangle offset: (x@y) extent: (w@h))
				color: (ColorValue random: rand); fill: true)].
	10 timesRepeat:
		[ | pt |
		pt := (rand next * size) rounded @ ((rand next * size) rounded).
		dl4 add: ((DisplayString string: (pt printString) 
				offset: pt) color: (ColorValue random: rand))].
	dl5 add: dl1; 
		add: dl2 at: (250@0); 
		add: dl3 at: (0@250); 
		add: dl4 at: (250@250).
	dl6 add: dl5 at: (50@50).
	^dl6

DisplayList class methodsFor: 'examples'
gridExample
	"Create and answer a large display list with lines and strings."
	"(DisplayList gridExample) display"
	"DisplayListView example"

	| dList rand ext step |
	ext := 1000.
	step := 50.
	dList := DisplayList new.
	0 to: (ext/step) do:
		[ :i |
		dList add: (DisplayLine offset: (i*step)@0 extent: 0@ext).
		dList add: (DisplayLine offset: 0@(i*step) extent: ext@0)].
	rand := Random new.
	1 to: 50 do:
		[ :i | | pt |
		pt := (rand next * 500) rounded @ ((rand next * 500) rounded).
		dList add: (DisplayString string: (pt printString) offset: pt)].
	^dList

DisplayList class methodsFor: 'examples'
gridExampleX: x byY: y
	"Create and answer a large display list with lines and strings."
	"(DisplayList gridExampleX: 3000 byY: 500) display"
	"DisplayListView example"

	| dList rand step |
	step := 50.
	dList := DisplayList new.
	0 to: (x/step) do:
		[ :i |
		dList add: (DisplayLine offset: (i*step)@0 extent: 0@y)].
	0 to: (y/step) do:
		[ :i |
		dList add: (DisplayLine offset: 0@(i*step) extent: x@0)].
	rand := Random new.
	1 to: (x * y / 20000) do:
		[ :i | | pt |
		pt := (rand next * x) rounded @ ((rand next * y) rounded).
		dList add: (DisplayString string: (pt printString) offset: pt)].
	^dList

DisplayList class methodsFor: 'examples'
polylineExample
	"Answer a display list with randomly-placed random-color polylines over the given extent."
	"DisplayList polylineExample"

	(DisplayList polylinesX: 600 byY: 600 items: 100) display

DisplayList class methodsFor: 'examples'
polylineExampleHuge
	"Answer a display list with randomly-placed random-color polylines over the given (very large) extent."
	"DisplayList polylineExampleHuge"

	(DisplayList polylinesX: 6000 byY: 2000 items: 2000) displayNonCached

DisplayList class methodsFor: 'examples'
polylinesX0: x byY: y
	"Answer a display list with randomly-placed random-color polylines over the given extent."
	"(DisplayList polylinesX: 600 byY: 600) display"

	| dList rand xArr yArr inset scale   x0 y0 size pointArray |
	inset := 64.
	scale := 32.
	dList := DisplayList new.
	rand := Random new.
	x0 := rand nextIntFrom: inset to: x-inset.
	y0 := rand nextIntFrom: inset to: y-inset.
	((x/30) + (y/30)) timesRepeat:
		[size := rand nextIntFrom: 3 to: 7.
		pointArray := Array new: size.
		pointArray at: 1 put: x0.
		yArr at: 1 put: y0.
		xArr at: size put: x0.
		yArr at: size put: y0.
		1 to: size do: [ :i |
			xArr at: i put: x0.
			yArr at: i put: y0.
			x0 := x0 + (rand nextIntFrom: 8 to: scale).
			y0 := y0 + (rand nextIntFrom: 8 to: scale)].
		dList add: ((DisplayPolyline
				offset: ((rand nextIntFrom: inset to: x-inset)
						@(rand nextIntFrom: inset to: y-inset)))
				color: ColorValue random);
				vertices: pointArray].
	^dList

DisplayList class methodsFor: 'examples'
polylinesX: x byY: y
	"Answer a display list with randomly-placed random-color polylines over the given extent."
	"(DisplayList polylinesX: 600 byY: 600) display"

	| dList rand inset scale x0 y0 size pointArray |
	inset := 16.
	scale := 128.
	dList := DisplayList new.
	rand := Random new.
	x0 := rand nextIntFrom: inset to: x-inset.
	y0 := rand nextIntFrom: inset to: y-inset.
	((x/20) + (y/20)) timesRepeat:
		[size := rand nextIntFrom: 3 to: 7.
		pointArray := Array new: size.
		pointArray at: 1 put: (0@0).
		pointArray at: size put: (0@0).
		x0 := y0 := 0.
		2 to: size-1 do: [ :i |
			pointArray at: i put: (x0 @ y0).
			x0 := x0 + (rand nextIntFrom: scale negated to: scale).
			y0 := y0 + (rand nextIntFrom: scale negated to: scale)].
		dList add: ((DisplayPolyline
				offset: ((rand nextIntFrom: inset to: x-inset)
						@(rand nextIntFrom: inset to: y-inset)))
				color: ColorValue random;
				vertices: pointArray)].
	^dList

DisplayList class methodsFor: 'examples'
polylinesX: x byY: y items: num
	"Answer a display list with randomly-placed random-color polylines over the given extent."
	"(DisplayList polylinesX: 600 byY: 600 items: 1000) display"

	| dList rand inset scale x0 y0 size pointArray |
	inset := 16.
	scale := 128.
	dList := DisplayList new.
	rand := Random new.
	x0 := rand nextIntFrom: inset to: x-inset.
	y0 := rand nextIntFrom: inset to: y-inset.
	num timesRepeat:
		[size := rand nextIntFrom: 3 to: 7.
		pointArray := Array new: size.
		pointArray at: 1 put: (0@0).
		pointArray at: size put: (0@0).
		x0 := y0 := 0.
		2 to: size-1 do: [ :i |
			pointArray at: i put: (x0 @ y0).
			x0 := x0 + (rand nextIntFrom: scale negated to: scale).
			y0 := y0 + (rand nextIntFrom: scale negated to: scale)].
		dList add: ((DisplayPolyline
				offset: ((rand nextIntFrom: inset to: x-inset)
						@(rand nextIntFrom: inset to: y-inset)))
				color: ColorValue random;
				vertices: pointArray)].
	^dList

DisplayList class methodsFor: 'examples'
postScriptExample
	"Create and answer a large display list with a lines, strings, and visuals."
	"DisplayList postScriptExample"

	| dList psRenderer file |
	dList := (DisplayList stringsX: 600 byY: 900) "DisplayList example2".
	file := 'temp.ps' asFilename writeStream.
	psRenderer := PostScriptPrinter new.
	psRenderer file: file; start: nil.
"	psRenderer scale: 10@10."
	dList displayPostScriptOn: psRenderer.
	psRenderer endNoPrint: nil. 		"this prints it."
"	'temp.ps' asFilename edit."

DisplayList class methodsFor: 'examples'
randomExample
	"Create and answer a large display list with a lines, strings, and visuals."
	"(DisplayList randomExample) display"

	| dList rand ext size |
	ext := 1000.
	size := ext / 2.
	dList := DisplayList new.
	rand := Random new.
	10 timesRepeat:
		[ | x y w h |					"add rectangles"
		x := (rand next * size) rounded.
		y := (rand next * size) rounded.
		w := (rand next * size/10) rounded.
		h :=  (rand next * size/10) rounded.
		dList add: ((DisplayRectangle
				offset: (x@y)
				extent: (w@h))
				color: ColorValue random; fill: true)].
	10 timesRepeat:
		[ | pt1 pt2 |					"add lines"
		pt1 := (rand next * size) rounded @ ((rand next * size) rounded).
		pt2 := (rand next * size) rounded @ ((rand next * size) rounded).
		dList add: ((DisplayLine offset: pt2 extent: (pt1 - pt2))
				color: ColorValue random)].
	20 timesRepeat:
		[ | pt |						"add strings"
		pt := (rand next * size) rounded @ ((rand next * size) rounded).
		dList add: ((DisplayString string: (pt printString) 
				offset: pt) color: ColorValue random)].
	10 timesRepeat:
		[ | pt coll |					"add visuals"
		coll := Cursor allInstances.
		pt := (rand next * ext) rounded @ ((rand next * ext) rounded).
		dList add: ((DisplayVisual visual: (coll atRandom image) 
				offset: pt) color: ColorValue random)].
	^dList

DisplayList class methodsFor: 'examples'
rectangleExample
	"Answer a display list with randomly-placed random-color rectangles over the given extent."
	"DisplayList rectangleExample"

	(DisplayList rectanglesX: 600 byY: 600) display

DisplayList class methodsFor: 'examples'
rectanglesX: x byY: y
	"Answer a display list with randomly-placed random-color rectangles over the given extent."
	"(DisplayList rectanglesX: 600 byY: 600) display"

	| dList rand x0 y0 x1 y1 scale w h |
	dList := DisplayList new.
	rand := Random new.
	scale := 20.
	x0 := x - (scale * 2).
	y0 := y - (scale * 2).
	((x/30) + (y/30)) timesRepeat:
		[x1 := scale + (rand next * x0) rounded.
		y1 := scale + (rand next * y0) rounded.
		w := ((rand next * 0.5 * (x0-x1) abs) rounded).
		h :=  ((rand next * 0.5 * (y0-y1) abs) rounded).
		dList add: ((DisplayRectangle
				offset: (x1@y1)
				extent: (w@h))
				color: ColorValue random; fill: true)].
	^dList

DisplayList class methodsFor: 'examples'
stringExample
	"Open a display list view with randomly-placed random-color strings over the given extent."
	"DisplayString stringExample"

	(DisplayList stringsX: 600 byY: 600) display

DisplayList class methodsFor: 'examples'
stringsX: x byY: y
	"Answer a display list with randomly-placed random-color strings over the given extent."
	"(DisplayList stringsX: 600 byY: 600) display"

	| dList rand inset |
	inset := 16.
	dList := DisplayList new.
	rand := Random new.
	((x/10) + (y/10)) timesRepeat:
		[dList add: ((DisplayString
				string: (rand nextIntFrom: 10 to: 100000) printString
				offset: ((rand nextIntFrom: inset to: x-inset)
						@(rand nextIntFrom: inset to: y-inset)))
				color: ColorValue random)].
	^dList

DisplayList class methodsFor: 'examples'
visualsX: x byY: y
	"Answer a display list with randomly-placed random-color visuals over the given extent."
	"(DisplayList visualsX: 600 byY: 600) display"

	| dList rand inset |
	inset := 16.
	dList := DisplayList new.
	rand := Random new.
	((x/10) + (y/10)) timesRepeat:
		[dList add: ((DisplayVisual
				visual: (rand nextIntFrom: 10 to: 100000) printString
				offset: ((rand nextIntFrom: inset to: x-inset)
						@(rand nextIntFrom: inset to: y-inset)))
				color: ColorValue random)].
	^dList

DisplayRectangle class methodsFor: 'examples'
rectangleExample
	"Open a display list view with randomly-placed random-color rectangles over the given extent."
	"DisplayRectangle rectangleExample"

	(DisplayList rectanglesX: 600 byY: 600) display

DisplayPolyline class methodsFor: 'examples'
polylineExample
	"Open a display list view with randomly-placed random-color polylines over the given extent."
	"DisplayPolyline polylineExample"

	(DisplayList polylinesX: 600 byY: 600) display

DisplayString class methodsFor: 'examples'
stringExample
	"Open a display list view with randomly-placed random-color strings over the given extent."
	"DisplayString stringExample"

	(DisplayList stringsX: 600 byY: 600) display

DisplayVisual class methodsFor: 'examples'
visualExample
	"Open a display list view with randomly-placed random-color visuals over the given extent."
	"DisplayVisual visualExample"

	(DisplayList visualsX: 600 byY: 600) display

DisplayListView class methodsFor: 'examples'
classListExample
	"DisplayListView classListExample"

	IndentedListLayoutManager listExample display

DisplayListView class methodsFor: 'examples'
classTreeExample
	"DisplayListView classTreeExample"

	(IndentedTreeLayoutManager listExample) display

DisplayListView class methodsFor: 'examples'
colorClassListExample
	"DisplayListView colorClassListExample"

	IndentedListLayoutManager colorListExample

DisplayListView class methodsFor: 'examples'
example
	"DisplayListView example"

	self onList: DisplayList gridExample

DisplayListView class methodsFor: 'examples'
exampleGridded
	"Open an example of a gridded-background display list view on the example hierarchical display list."
	"DisplayListView exampleGridded"

	DisplayListView onList: (DisplayList exampleHierarchical)
			size: 400@300
			withGrid: 32@32
			inColor: ColorValue lightGray

DisplayListView class methodsFor: 'examples'
exampleHierarchical
	"DisplayListView exampleHierarchical"

	self onList: (DisplayList exampleHierarchical) size: 400@400

DisplayListView class methodsFor: 'examples'
test1
	"DisplayListView test1"

	| window container me wrapper dlist dled |
	window := ScheduledWindow new.
	window label: 'Display List Editor'.
	window minimumSize: 400@300.
	container := CompositePart new.
	dlist := DisplayList example2.
	dled := DisplayListEditor on: dlist.
	me := self on: dled.
	self addButtonOn: me labeled: 'File'
		doing: [:model :value | dled doFile] 
		in: (LayoutFrame new leftFraction: 0.0;		topFraction: 0.0; 
							rightFraction: 0.2;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Edit'
		doing: [:model :value | dled doEdit] 
		in: (LayoutFrame new leftFraction: 0.2;		topFraction: 0.0; 
							rightFraction: 0.4;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Inspect'
		doing: [:model :value | "me inspect." dled doInspect] 
		in: (LayoutFrame new leftFraction: 0.4;		topFraction: 0.0; 
							rightFraction: 0.6;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Display'
		doing: [:model :value | dled doDisplay] 
		in: (LayoutFrame new leftFraction: 0.6;		topFraction: 0.0; 
							rightFraction: 0.8;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Zoom'
		doing: [:model :value | dled doZoom] 
		in: (LayoutFrame new leftFraction: 0.8;		topFraction: 0.0; 
							rightFraction: 1.0;	bottomFraction: 0.1) 
		to: container.
	wrapper := LookPreferences edgeDecorator on: me.
	wrapper useHorizontalScrollBar.
	container add: wrapper
			borderedIn: (0@0.1 extent: 1.0@0.9).
	window component: container.	
	window open

DisplayListView class methodsFor: 'examples'
test3
	"DisplayListView test3"

	| window container me wrapper dlist dled |
	window := ScheduledWindow new.
	window label: 'Display List Editor'.
	window minimumSize: 300@300.
	container := CompositePart new.
	dlist := DisplayList rectanglesX: 600 byY: 600.
	dled := DisplayListEditor on: dlist.
	me := self on: dled.
	self addButtonOn: me labeled: 'File'
		doing: [:model :value | dled doFile] 
		in: (LayoutFrame new leftFraction: 0.0;		topFraction: 0.0; 
							rightFraction: 0.2;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Edit'
		doing: [:model :value | dled doEdit] 
		in: (LayoutFrame new leftFraction: 0.2;		topFraction: 0.0; 
							rightFraction: 0.4;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Inspect'
		doing: [:model :value | "me inspect." dled doInspect] 
		in: (LayoutFrame new leftFraction: 0.4;		topFraction: 0.0; 
							rightFraction: 0.6;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Display'
		doing: [:model :value | dled doDisplay] 
		in: (LayoutFrame new leftFraction: 0.6;		topFraction: 0.0; 
							rightFraction: 0.8;	bottomFraction: 0.1) 
		to: container.
	self addButtonOn: me labeled: 'Zoom'
		doing: [:model :value | dled doZoom] 
		in: (LayoutFrame new leftFraction: 0.8;		topFraction: 0.0; 
							rightFraction: 1.0;	bottomFraction: 0.1) 
		to: container.
	wrapper := LookPreferences edgeDecorator on: me.
	wrapper useHorizontalScrollBar.
	container add: wrapper
			borderedIn: (0@0.1 extent: 1.0@0.9).
	window component: container.	
	window open

BinaryTreeLayoutManager class methodsFor: 'examples'
listExample
	"BinaryTreeLayoutManager listExample display"

	| acc me |
	acc := TreeAccessor subject: BTreeNode treeExample2
			terminalQuery: [ :c | (c isTreeNode not) or: [c children size = 0]]
			childAccessor: #children
			itemGenerator: [ :c | (DisplayString new)
							model: c; 
							string: c printString; 
							color: ColorValue white].
	me := (self new) accessor: acc; xStep: 32; yStep: 64.
	^me displayList

IndentedListLayoutManager class methodsFor: 'examples'
colorListExample
	"IndentedListLayoutManager colorListExample display"

	| acc me |
	acc := TreeAccessor subject: MusicMagnitude
			terminalQuery: [ :c | c subclasses size = 0]
			childAccessor: #sortedSubclasses
			itemGenerator: [ :c | (DisplayString new)
									model: c;
									string: c name;
									color: [c color]].
	me := (self new) accessor: acc; xStep: 16; yStep: 16.
	^me displayList display

IndentedListLayoutManager class methodsFor: 'examples'
listExample
	"IndentedListLayoutManager listExample display"
	"DisplayListView classListExample"

	| acc me |
	acc := TreeAccessor subject: Magnitude
			terminalQuery: [ :c | c subclasses size = 0]
			childAccessor: #sortedSubclasses
			itemGenerator: [ :c | (DisplayString new)
									model: c;
									string: c name;
									color: ColorValue white].
	me := (self new) accessor: acc; xStep: 16; yStep: 16.
	^me displayList

IndentedTreeLayoutManager class methodsFor: 'examples'
listExample
	"IndentedTreeLayoutManager listExample display"
	"DisplayListView classTreeExample"

	| acc me |
	acc := TreeAccessor subject: "View" Magnitude
			terminalQuery: [ :c | c subclasses size = 0]
			childAccessor: #sortedSubclasses
			itemGenerator: [ :c | (DisplayString new)
							model: c; 
							string: c name; 
							color: ColorValue white].
	me := (self new) accessor: acc; xStep: 16; yStep: 12.
	^me displayList

TimeSequenceView class methodsFor: 'examples'
bachExample
	"Open a sequence view on the Bach fugue theme."
	"SequenceView bachExample"

	TimeSequenceView openOn:
		((EventListEditor new) list: (EventList named: #Bach2) copy)

TimeSequenceView class methodsFor: 'examples'
randomExample
	"Open a sequence view on a random event list."
	"SequenceView randomExample"

	TimeSequenceView openOn:
		((EventListEditor new) list: EventList randomExample)

PitchTimeView class methodsFor: 'examples'
bachExample
	"Open a PTView on the event list named Bach2."
	"PitchTimeView bachExample"

	PitchTimeView openOn:
			((EventListEditor new) list: (EventList named: #Bach2) copy)

PitchTimeView class methodsFor: 'examples'
randomExample
	"Open a p-t view on a random event list."
	"PitchTimeView randomExample"

	PitchTimeView openOn:
		((EventListEditor new) list: EventList randomExample)

CMNView class methodsFor: 'examples'
example
	"CMNView example"

	CMNView openOn:
			((EventListEditor new) list: (EventList named: #scale2) copy)

HauerSteffensView class methodsFor: 'examples'
bachExample
	"Open a HSView on the event list named Bach2."
	"HauerSteffensView bachExample"

	HauerSteffensView openOn:
			((EventListEditor new) list: (EventList named: #Bach2) copy)

HauerSteffensView class methodsFor: 'examples'
randomExample
	"Open a HSView on two merged random event lists."
	"HauerSteffensView randomExample"

	HauerSteffensView openOn:
			((EventListEditor new) list: ((EventList newNamed: #pRand)
				addAll: (EventList randomExample);
				addAll: (EventList randomExample)))

HauerSteffensView class methodsFor: 'examples'
randomSWSSExample
	"Open a HSView on two merged random event lists."
	"HauerSteffensView randomSWSSExample"

	HauerSteffensView openOn:
			((EventListEditor new) list: ((EventList newNamed: #sRand)
			addAll: (EventList randomSWSSExample2);
"			addAll: (EventList randomSWSSExample2);"
			addAll: (EventList randomSWSSExample2)))

PhraseView class methodsFor: 'examples'
example
	"PhraseView example"

	PhraseView openOn:
		((EventListEditor new) list: (EventList named: #phrase1) copy)

FunctionView class methodsFor: 'examples'
example
	"FunctionView example"

	FunctionView multiFunctionExample

FunctionView class methodsFor: 'examples'
expSegExample
	"Demonstrate an ExpSeg function with different weights."
	"FunctionView expSegExample"

	FunctionView onFunction: (ExponentialFunction from: #((0 0 3) (0.3 1 5) (0.6 0.3 0) (1 0)))

FunctionView class methodsFor: 'examples'
fileExample
	"Read an extracted envelope as floating-point data from a file."
	"FunctionView fileExample"

	FunctionView onFunction: (Function readFloatsFrom: 'snd/yy/ec/syl/y2.env')
"	FunctionView onFunction: (Function readFloatsFrom: 'snd/yy/ec/syl/y2.2.env')"

FunctionView class methodsFor: 'examples'
linSegExample
	"FunctionView linSegExample"

	FunctionView onFunction: (LinearFunction from: #((0 0) (0.15 1.0) (0.25 0.75) (0.75 0.5) (1 0)))

FunctionView class methodsFor: 'examples'
multiFunctionExample
	"Open a function editor on 4 different functions."
	"FunctionView multiFunctionExample"

	FunctionView 
		onFunction: (LinearFunction from: #((0 0) (0.12 1) (0.17 0.74) 
				(0.35 0.5) (0.9 0.4) (1 0) )) 
		and: (LinearFunction from: #((0 0.1) (0.3 0.5) (0.7 0.3) (1 0))) 
		and: (ExponentialFunction from: #((0 0 5) (0.05 1 -5) (0.2 0.25 -1) (1 0))) 
		and: (SplineFunction from: #((0 0.5) (0.212891 0.429687) (0.35 0.7) (0.65 0.35) (0.845703 0.6875) (1 0.5))) 
		x: 512 y: 256

FunctionView class methodsFor: 'examples'
multiFunctionExample2
	"Open a function editor on 4 different functions."
	"FunctionView multiFunctionExample2"

	FunctionView 
		onFunction: (LinearFunction from: #((0 0) (0.12 1) (0.17 0.74) 
				(0.35 0.5) (0.9 0.4) (1 0) )) 
		and: (Function readFloatsFrom: 'snd/yy/ec/syl/y2.env') 
		and: (ExponentialFunction from: #((0 0 5) (0.05 1 -5) (0.2 0.25 -1) (1 0))) 
		and: (SplineFunction default) 
		x: 384 y: 192

FunctionView class methodsFor: 'examples'
smallFileExample
	"Read an extracted envelope as floating-point data from a file."
	"FunctionView smallFileExample"

	FunctionView smallOnFunction: (Function readFloatsFrom: 'snd/yy/ec/syl/y2.env')
"	FunctionView smallOnFunction: (Function readFloatsFrom: 'snd/yy/ec/syl/y2.2.env')"

FunctionView class methodsFor: 'examples'
smallMultiFunctionExample
	"Open a function editor on 4 different functions."
	"FunctionView smallMultiFunctionExample"

	 
	FunctionView onFunctions: (Array 
			with: (LinearFunction from: #((0 0) (0.12 1) (0.17 0.74) 
					(0.35 0.5) (0.9 0.4) (1 0)))
			with: (LinearFunction from: #((0 0.1) (0.3 0.5) (0.7 0.3) (1 0)))
			with: (ExponentialFunction from: #((0 0 5) (0.05 1 -5) (0.2 0.25 -1) (1 0)))
			with: (SplineFunction default))
		withColors: self defaultColors
		x: 384 y: 192

SoundView class methodsFor: 'examples'
example1
	"Open a sound view on the example sound file."
	"SoundView example1"

"	| fileName |	
	fileName := FillInTheBlank request: 'name of soundfile to edit:'
					initialAnswer: '/usr/stp/snd/test'.
	fileName size = 0 ifTrue: [^self].
	SoundView1 openOn: 
			(SampledSound fromFile: fileName)
"

	SoundView openOn: (SampledSound fileExample)

SoundView class methodsFor: 'examples'
example2
	"Open a sound view on the an empty sound."
	"SoundView example2"

	SoundView openOn: (SampledSound new initialize)

MixView class methodsFor: 'examples'
randomExample
	"Open a MixView on the random mix event list."
	"MixView randomExample"

	MixView openOn: ((EventListEditor new) list: Mix randomExample)

MixView class methodsFor: 'examples'
randomExample2
	"Open a MixView on the random mix event list."
	"MixView randomExample2"

	MixView openOn:
			((EventListEditor new) list: ((Mix newNamed: #mRand)
					addAll: (Mix randomExample);
					addAll: (Mix randomExample)))

Mix class methodsFor: 'examples'
randomExample
	"Create an event list with random data."
	"Mix randomExample"
	"MixView randomExample"
	"(Mix newNamed: #mRand)
			addAll: (Mix randomExample);
			addAll: (Mix randomExample)"

	| rand size arrArray |
	rand := Random new.
	size := 16.
	arrArray := Array new: 7.
	1 to: 7 do: [ :i | arrArray at: i put: (Array new: size)].
	1 to: size do: [ :i | (arrArray at: 1) at: i put: (rand next * 8.0)].
	1 to: size do: [ :i | (arrArray at: 2) at: i put: (rand nextFrom: 1.0 to: 4.0)].
	1 to: size do: [ :i | (arrArray at: 3) at: i put: rand next].
	1 to: size do: [ :i | (arrArray at: 4) at: i put: (rand nextIntFrom: 1 to: 7)].
	1 to: size do: [ :i | (arrArray at: 5) at: i put: (rand nextFrom: 0.1 to: 0.3)].
	1 to: size do: [ :i | (arrArray at: 6) at: i put: (rand nextFrom: 0.1 to: 0.4)].
	1 to: size do: [ :i | (arrArray at: 7) at: i put: 
		(#('y1.2c4' 'y1.4a3b' 'y1.4a1' 'y1.2b2b' 'y1.2b1' 'y1.2c2a' 'y1.2a2' 'y1.4b2') 
				atRandom: rand)].
	^Mix named: 'random1'  
		fromSelectors: #(start: duration: loudness: voice: fadeIn: fadeOut: name:) 
		values: arrArray

Mix class methodsFor: 'examples'
randomExample1
	"Create an event list with random data."
	"Mix randomExample"
	"MixView randomExample"
	"(Mix newNamed: #mRand)
			addAll: (Mix randomExample);
			addAll: (Mix randomExample)"

	| rand size arr1 arr2 arr3 arr4 |
	rand := Random new.
	size := 8.
	arr1 := Array new: size.
	arr2 := Array new: size.
	arr3 := Array new: size.
	arr4 := Array new: size.
	1 to: size do: [ :i | arr1 at: i put: (rand next * 15.0)].
	1 to: size do: [ :i | arr2 at: i put: (rand nextFrom: 1.0 to: 4.0)].
	1 to: size do: [ :i | arr3 at: i put: rand next].
	1 to: size do: [ :i | arr4 at: i put: (rand nextIntFrom: 1 to: 4)].
	^Mix named: 'random1'  
		fromSelectors: #(start: duration: loudness: voice:) 
		values: (Array with: arr1 with: arr2 with: arr3 with: arr4)

BTreeNode class methodsFor: 'examples'
treeExample1
	"BTreeNode treeExample1 inspect"
	"TreeView on: (BTreeNode treeExample1)"

	^(BTreeNode left: (BTreeNode left: 1 right: 2)
				right: (BTreeNode left: 3 
							right: (BTreeNode left: 4 right: 5)))

BTreeNode class methodsFor: 'examples'
treeExample2
	"BTreeNode treeExample2"
	"TreeView on: (BTreeNode treeExample2)"

	^BTreeNode name: #root
		left: (BTreeNode name: #l
				left: (BTreeNode name: #ll left: 0 right: 1)
				right: (BTreeNode name: #lr 
						left: 3
						right: (BTreeNode name: #lrr left: 5 right: 6)))
		right: (BTreeNode name: #r
					left: (BTreeNode name: #rl left: 8 right: 9) 
					right: (BTreeNode name: #rr 
							left: (BTreeNode name: #rrl left: 12 right: 13)
							right: 15))

TRTreeNode class methodsFor: 'examples'
treeExample3
	"TRTreeNode treeExample3"
	"TreeView openOn: TRTreeNode treeExample3"

	| arr |
"	arr := #(6 1 7 4 3 5 2) asOrderedCollection.
"	arr := #(5 7 1 8 4 6 3 9 2 10) asOrderedCollection.
	^TreeEditor new root: (TRTreeNode fromValues: arr copy);
					leaves: arr

LPCFrameData class methodsFor: 'examples'
example
	"Open up a demo LPC frame view"
	"LPCFrameData example"

	LPCFrameView openOn: 
		((LPCFrameData new: 100) 
				readFromFileNamed: 'music/lpc/sampledata/sampledataset.lpc')

LPCFrameView class methodsFor: 'examples'
example
	"Open up a demo LPC frame view"
	"LPCFrameView example"

	LPCFrameView openOn: 
		((LPCFrameData new: 100) 
				readFromFileNamed: 'music/lpc/sampledata/sampledataset.lpc')

PhaseVocFrameData class methodsFor: 'examples'
example
	"Open up a demo LPC frame view"
	"PhaseVocFrameData example"

	PhaseVocFrameView openOn: 
		((PhaseVocFrameData new: 100) 
				readFromFileNamed: '/usr/stp/snd/ec/syl/ywe1a.pv')! !

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