AC Toolbox
A program to assist algorithmic composition. (www.actoolbox.net)
This text contains the documentation for all available help.
The release notes are not included.
(1/f-choice n sequence)
Returns a closure. When applied, one element is chosen from a sequence according to a 1/F distribution. N is the total (estimated) number of values to be chosen using this generator (example 1).
EXAMPLE 1: (for-example (1/f-choice 20 '(a b c d e f g h i)))
(1/f-value n a z &key round (scale 1))
Returns a closure. When applied, it returns a number between A and Z according to a 1/F distribution. The type of the number is determined by the type of A and Z. N is the total number of values (estimated) to be produced with this generator (examples 1-3).
To quantize the result with another unit, bind ROUND to a quantization unit (example 4).
A and Z may vary over time (example 5).
Due to the nature of the algorithm used to produce the values for this generator, values A and Z will probably never be reached. One way to deal with this feature is to use CONVERT to produce a number of values and map them to the range A to Z (example 6).
Another way to change the range of this generator is to bind the keyword SCALE to a value other than 1 (the default). SCALE multiplies the result of the algorithm before it is mapped to the range A to Z. If necessary, the result is clipped to be in the range A to Z (examples 7-8).
EXAMPLE 1: (for-example (1/f-value 20 1 100))
EXAMPLE 2: (for-example (1/f-value 20 1.0 100))
EXAMPLE 3: (plot (1/f-value 200 1.0 100)
:number 200 :min 1 :max 100)
EXAMPLE 4: (for-example (1/f-value 20 1.0 100 :round 0.5))
EXAMPLE 5: (plot (1/f-value 200 (line 200 1.0 100) 100)
:number 200 :min 1 :max 100)
EXAMPLE 6: (plot (convert (1/f-value 128 40 80) 128 40 80))
EXAMPLE 7: (plot (1/f-value 128 40 80)
:min 40 :max 80)
EXAMPLE 8: (plot (1/f-value 128 40 80 :scale 2)
:min 40 :max 80)
(2-masks n outer-mask outer-low outer-high inner-mask inner-low inner-high &optional generator stop)
One mask, OUTER-MASK, is mapped to produce a list with N values chosen randomly between OUTER-LOW and OUTER-HIGH. A second mask, INNER-MASK, is mapped to be in the range between INNER-LOW and INNER-HIGH. The second mask is used to block the choice of values from the first mask. In other words, if the value mapped using the first mask falls within the area of the second mask, the value is rejected and another is generated until one falls outside the inner mask. If that does not happen within STOP number of attempts, an error message is produced (examples 1-5).
The outer and the inner mask can be the same mask but they should not be mapped to the same limits because all values would always be blocked (examples 6-7).
In the standard case, an uniform random distribution is used to choose values between the limits of the outer mask. Another generator which can produce values in the range 0-100 percent can be bound to the optional GENERATOR parameter (example 8). Instead of a generator, a list with percentage values could also be given (example 9).
Optional parameter STOP could be increased to allow for more attempts before stopping but probably the there is an inconsistency in the boundaries which prevents the generation of values (examples 10-11).
If the optional parameter for GENERATOR is bound to t as in the above example, a uniform random distribution is used to pick values between the limits of the mask.
To generate a number of values from a mask without blocking by using another mask, see the tool CONVERT.
EXAMPLE 1: (fill-template specify-mask outer '(50 100 50) '(40 0 20))
EXAMPLE 2: (fill-template specify-mask inner '(100 100) '(0 0))
EXAMPLE 3: (plot outer)
EXAMPLE 4: (plot inner)
EXAMPLE 5: (plot (2-masks 100 outer 1 100 inner 40 60))
EXAMPLE 6: (plot (2-masks 100 inner 1 100 inner 65 80))
EXAMPLE 7: (make-histogram (2-masks 100 inner 1 100 inner 65 80))
EXAMPLE 8: (plot (2-masks 100 outer 1 100 inner 40 60
(beta-value 0.0 100 .1 .1)))
EXAMPLE 8: (plot (2-masks 100 outer 1 100 inner 40 60
'(0 20 40 60 80 100)))
EXAMPLE 10: (plot (2-masks 100 outer 40 80 inner 40 80 t 500))
EXAMPLE 11: (plot (2-masks 100 outer 30 90 inner 40 80))
(a-delay time-in-milliseconds)
Returns an instance of the class SOME-DELAY. It is suitable for use in NOTE STRUCTUREs, NOTE SECTIONs or STRUCTURED SECTIONs. In can be part of a NOTE STRUCTURE such as one constructed with IN-SEQUENCE or IN-PARALLEL.
The TIME-IN-MILLISECONDS represents an actual amount of time for a rest and is not a multiple of a clock time.
Example 1 will wait 1 second in a note structure.
EXAMPLE 1: (fill-template structured-section
section1 200
(in-sequence (a-note 1 60 mf 1) (a-delay 1000)
(a-note 1 67 mf 1)))
(a-note rhythm pitch velocity channel)
Returns an instance of the class SOME-NOTE. It is suitable for use in NOTE STRUCTUREs, NOTE SECTIONs or STRUCTURED SECTIONs. In can be part of a NOTE STRUCTURE such as one constructed with IN-SEQUENCE or IN-PARALLEL.
RHYTHM values are multiples of a clock unit that is specified when a section is made.
PITCH can be MIDI note numbers or a known symbol, such as C3. PITCH can also be a list of note numbers to occur at the same time (a chord).
VELOCITY is a MIDI value (0-127) or a known symbol, such as MF.
CHANNELS are specified between 1-16.
(examples 1-3).
EXAMPLE 1: (fill-template structured-section
section1 200 (a-note 1 60 mf 1))
EXAMPLE 2: (fill-template structured-section
section2 200 (a-note 1 '(c3 e3 g3) mf 1))
EXAMPLE 3: (fill-template structured-section
section3 200
(in-sequence (a-note 1 60 mf 1) (a-note 1 64 mf 1)
(a-note 1 67 mf 1)))
(a-rest rhythm)
Returns an instance of the class SOME-REST. It is suitable for use in NOTE STRUCTUREs, NOTE SECTIONs or STRUCTURED SECTIONs. In can be part of a NOTE STRUCTURE such as one constructed with IN-SEQUENCE or IN-PARALLEL.
RHYTHM values are multiples of a clock unit that is specified when a section is made. When used within another structure, this object represents a rest of a certain length (example 1).
EXAMPLE 1: (fill-template structured-section
section1 200
(in-sequence (a-note 1 60 mf 1)
(a-rest 3)
(a-note 1 67 mf 1)))
ac toolbox
The AC Toolbox is a collection of tools to facilitate the activity commonly known as algorithmic composition.
Several models for defining musical events are included. They can be used by defining objects such as sections, shapes, masks, or note structures.
Menu items are available for defining the various types of objects. It is also possible to play, plot, modify, and examine objects in a number of ways. Extensive online help is available.
In addition to Midi output, the AC Toolbox can produce files suitable for use as data in other programs. Score files for Csound and binary OSC files for SuperCollider can be produced and rendered. Files for formatting musical notation with FOMUS can be written. Floating-point Midi output via a firewire interface to a Capybara or Pacarana (Kyma) is also suported.
Spectral files produced by SPEAR can be used to generate pitch and other data. Midi controllers can control AC Toolbox stream output in real-time.
An important method of creating data in the Toolbox is the use of generators. A number of generators have been included reflecting various approaches to the creation of musical material including tendency masks, stochastic functions, chaotic systems, transition tables, recursive subdivisions, metric indispensabilities, morphological mutations, spectral composition, etc.
The AC Toolbox is implemented in Lisp and input syntax often reflects the conventions of this language. It is also possible for a user to extend the Toolbox by adding Lisp functions. For example, additional generators can be defined in Lisp to use with the Toolbox.
(act-choose-directory-dialog &key path prompt namestring)
This tool is intended for users programming functions that require selecting a folder with a dialog.
PATH is a suggested path expressed as a string.
PROMPT is a string printed on the top of the dialog.
NAMESTRING will return the path as a namestring if it is bound to t.
EXAMPLE 1: (print-result (act-choose-directory-dialog
:prompt "Pick a folder for my object files"))
(act-choose-file-dialog &key path prompt filter namestring operation)
This tool is intended for users programming functions that require selecting files with a dialog.
PATH is a suggested path expressed as a string.
PROMPT is a string printed on the top of the dialog.
FILTER defaults to all file types but types such as :lisp, :text, :sound, and :midi can be used. FILTER controls which types of files are available for selection.
NAMESTRING will return the path as a namestring if it is bound to t.
OPERATION defaults to :open (the selected file). To save to the selected file bind OPERATION to :save.
EXAMPLE 1: (print-result (act-choose-file-dialog))
EXAMPLE 2: (print-result (act-choose-file-dialog
:prompt "Choose a text file"
:filter :text))
(act-if source &rest conditions)
Returns a closure. When applied, it provides a nested series of IFs that understand how to read and produce data with AC Toolbox objects.
Various generators can be chosen based on a value produced from SOURCE. That value is compared, in succession, to the conditions until either a condition is met, in which case another value is generated and returned or if no condition has been met, the final, default result is used.
Conditions are separated by ELSE.
If the initial condition is not met, then the ELSE clause is dealt with. There must be at least one ELSE clause in the expression (example 1).
In this example, if the value from SOURCE > 20, then the generator (rv 100 200) is applied to produce a value. Otherwise, the generator (rv 1 10) will be used. Each time the generator is applied, the next value from SOURCE is compared.
All values, except for the comparison functions, can be generators, stockpiles, lists, or constants. Each time the generator is applied, the next value from the generator, stockpile, etc. will be used.
Any number of ELSE conditions can be used as long as there is a final condition in case none of the above was true. The conditions are examined in sequence. As soon as one condition is true, a result is produced and the generator stops (example 2).
If the value from SOURCE > 20, generator (rv 100 200) returns a value. Otherwise the comparison value = 20 is made. If true, the next value from the list '(50 60 70 80) is returned. Otherwise if value >= 15, 5 is returned. Otherwise the generator (rv 1 10) will be used.
Since SOURCE can be a stockpiile, list, generator, etc., a stockpile will be defined to use as source (examples 3-4).
Comparisons with only one argument can also be used. In that case, the value from SOURCE will be the input for the comparison (example 5).
If the value from the stockpile is even, the generator (rv 1 10) is applied. Otherwise (rv 100 200) will produce the value.
The current value from SOURCE can be returned by using the symbol current. This can only be used for the result of a comparison. Example 6 returns the result of (rv 10 20) if the value from SOURCE is >= 3. Otherwise, the current value from SOURCE is returned.
The opposite situation is also possible (example 7).
Some obvious examples of Lisp functions that can be used to make the comparisons are:
=, <, >, <=, >=, /=, evenp, oddp
These functions can only be used with numbers.
SOURCE is not limited to numbers. If a generator should be chosen based on a symbol, the comparison function could be EQUAL. The symbols being compared should be quoted (example 8).
This generator can be used to establish a relationship between parameters. A stockpile of values used for one parameter could be the input used to determine generators for another parameter. In examples 9-10, pitches below 60 have larger rhythmic values.
The tool ANYTHING can also be used for a comparison (example 11). In this example, pitches between 50 and 65 receive larger duration values.
The comparisons can be combined using the tools CONSTRAINT-AND, CONSTRAINT-OR, CONSTRAINT-NOT. In example 12, CONSTRAINT-AND is used to make a comparison: a value is < 5 and even. See the help for CONSTRAINT-AND for more information about how to use it (example 13).
EXAMPLE 1: (for-example
(act-if '(10 20 30)
> 20 (rv 100 200)
else (rv 1 10)))
EXAMPLE 2: (for-example
(act-if '(10 20 30 15)
> 20 (rv 100 200)
else = 20 '(50 60 70 80)
else >= 15 5
else (rv 1 10)))
EXAMPLE 3: (fill-template specify-stockpile stock1 1 2 3 4)
EXAMPLE 4: (for-example
(act-if stock1
> 2 (rv 100 200)
else (rv 1 10)))
EXAMPLE 5: (for-example
(act-if '(1 2 3 4)
evenp (rv 1 10)
else (rv 100 200)))
EXAMPLE 6: (for-example
(act-if '(1 2 3 4)
>= 3 (rv 10 20)
else current))
EXAMPLE 7: (for-example
(act-if '(1 2 3 4)
>= 3 current
else (rv 1 10)))
EXAMPLE 8: (for-example
(act-if (random-choice '(sax1 flute1))
equal 'sax1 (rv 1 10)
else (rv 1 100)))
EXAMPLE 9: (fill-template generate-stockpile pitches 100
(random-value 40 80))
EXAMPLE 10: (fill-template data-section ds1 100 100
(act-if pitches
< 60 (random-value 4.0 5 :round .25)
else (random-value 1.0 2 :round .25))
pitches
(random-value mf ff) 1 0)
EXAMPLE 11: (fill-template data-section ds2 100 100
(act-if pitches
(anything inside 50 65) (random-value 4.0 5 :round .25)
else (random-value 1.0 2 :round .25))
pitches
(random-value mf ff) 1 0)
EXAMPLE 12: (for-example
(act-if (from 1 10) > 5 (rv 10 20)
else (constraint-and (anything < 5) (anything evenp))
(random-value 100 200)
else 5))
EXAMPLE 13: (show-help 'constraint-and)
(act-sort stockpile function1 &optional value1 logical function2 value2)
Sorts a stockpile or list in various ways. For example, rhythms could be sorted in ascending order or low and high pitches could shifted to the beginning of the stockpile.
The most simple way to sort is by only specifying FUNCTION1 (examples 1-2). The stockpile made in example 1 is sorted in ascending order in example 2.
Numbers satisfying a constraint can be moved to the front of the stockpile. In examples 3-4, a pitch stockpile is made and sorted so that pitches < 60 will come first. VALUE1 should be a number or a symbol such as c4.
Unlike the sort function in Common Lisp, the original order will not be disturbed when the values are moved to the front.This means that values will be moved to the front in the same order in which they occur in the original stockpile.
Example 5 is a section that plays the original stockpiles for rhythm and pitch. Example 6 uses the sorted stockpiles.
Another constraint can be specified with FUNCTION2 and VALUE2. The two constraints are joined by the logical functions AND or OR. Example 7 moves low and high pitches to the front. Example 8 moves pitches within a certain bandwidth to the front.
If a logical function is specified with LOGICAL, values for both FUNCTION2 and VALUE2 should be given. If this is not done, only the first constraint is used.
STOCKPILE can be a stockpile or list.
FUNCTION1 and FUNCTION2 should be functions such as <, <=, >, or >=.
LOGICAL should be AND or OR.
VALUE1 and VALUE2 should be numbers or symbols such as c4.
EXAMPLE 1: (fill-template generate-stockpile
rhythms 20 (random-value 1.0 3))
EXAMPLE 2: (plot (act-sort rhythms <))
EXAMPLE 3: (fill-template generate-stockpile
pitches 20 (random-value 40 80))
EXAMPLE 4: (plot (act-sort pitches < 60))
EXAMPLE 5: (fill-template data-section section1 100
20 rhythms pitches mf 1)
EXAMPLE 6: (fill-template data-section section2 100
20 (act-sort rhythms <)
(act-sort pitches < 60) mf 1)
EXAMPLE 7: (plot (act-sort pitches < 50 or > 70))
EXAMPLE 8: (plot (act-sort pitches > c4 and < B4))
(add-generator-brief name text)
Adds a brief TEXT description for a generator called NAME.
NAME should be symbol and TEXT should be a string (between "").
NAME and TEXT will appear in the table made by the menu item Brief descriptions (example 1).
EXAMPLE 1: (add-generator-brief 'generate-nothing
"Turn something into nothing")
(add-new-generator name text examples &key basic chaos ...)
Adds the symbol NAME to the list of generators which can be accessed with the help function.
TEXT is the text which will appear in the help window.It should be entered as a string.
EXAMPLES is a string containing examples which can be evaluated in the lower pane of the help dialog.
E.g.
(add-new-generator 'my-generator
"(my-generator parameter)
Helps a lot.
"
"
EXAMPLE 1: (for-example (my-generator 10))
")
Keywords can be used to indicate which category the generator might fit into. A generator can be included in more than one category. In the Annotated Index, various categories can be chosen. These categories correspond to the keywords that can be used with ADD-GENERATOR. If the generator could be considered to produce noise, the keyword should be bound to the t.
E.g.
(add-new-generator 'my-generator
"(my-generator parameter)
Makes a lot of noise.
"
"
EXAMPLE 1: (for-example (my-generator 10))
" :noise t)
If the double quote symbol is needed in the text string, precede it with \.
A simple markup system is available to format help texts. The markup characters are inserted directly into the help text (within the strings). The markup commands all start with an at sign and are followed by another character.
h starts a header
/ ends the header
p starts and ends a paragraph
When a window size is changed, the width of the paragraph also changes.
If no examples are to be entered and the lower pane is not desired, use ADD-GENERATOR with the same arguments except for the string of examples.
(add-new-tool name text examples &key basic chaos ...)
Adds the symbol NAME to the list of tools which can be accessed with the help function.
TEXT is the text which will appear in the help window. It should be entered as a string.
EXAMPLES is a string containing examples which can be evaluated in the lower pane of the help dialog.
E.g.
(add-new-tool 'my-tool
"(my-tool parameter)
Does really interesting things.
"
"
EXAMPLE 1: (print-result (my-tool 10))
")
Tools are grouped into various categories. In the Annotated Index, various categories can be chosen. These categories correspond to the keywords that can be used with ADD-TOOL. To include a tool in a category, the keyword should be bound to t.
E.g.
(add-new-tool 'my-tool
"(my-tool parameter)
Does really interesting things.
"
"
EXAMPLE 1: (print-result (my-tool 10))
" :basic t)
A tool can be included in more than category.
If the double quote symbol is needed in the text string, precede it with \.
A simple markup system is available to format help texts. The markup characters are inserted directly into the help text (within the strings). The markup commands all start with an at sign and are followed by another character.
h starts a header
/ ends the header
p starts and ends a paragraph
When a window size is changed, the width of the paragraph also changes.
If no examples are to be entered and the lower pane is not desired, use ADD-TOOL with the same arguments except for the string of examples.
(add-new-transformer name text examples &key basic chaos ...)
Adds the symbol NAME to the list of transformers which can be accessed with the help function.
TEXT is the text which will appear in the help window. It should be entered as a string.
EXAMPLES is a string containing examples which can be evaluated in the lower pane of the help dialog.
E.g.
(add-transformer 'my-transformer
"(my-transformer amount)
Transforms by adding AMOUNT to the parameter being transformed.
"
"
EXAMPLE 1: (show-transformation (my-transformer 10)
'(10 20 30 40))
")
Transformers are grouped into various categories. In the Annotated Index, various categories can be chosen. These categories correspond to the keywords that can be used with ADD-TRANSFORMER. To include a tool in a category, the keyword should be bound to t.
E.g.
(add-transformer 'my-transformer
"(my-transformer amount)
Transforms by adding AMOUNT to the parameter being transformed.
"
"
EXAMPLE 1: (show-transformation (my-transformer 10)
'(10 20 30 40))
" :pitch t)
If the double quote symbol is needed in the text string, precede it with \.
To show the results of a transformation in a help window, the tool SHOW-TRANSFORMATION is often used. See its help for a description.
A simple markup system is available to format help texts. The markup characters are inserted directly into the help text (within the strings). The markup commands all start with an at sign and are followed by another character.
h starts a header
/ ends the header
p starts and ends a paragraph
When a window size is changed, the width of the paragraph also changes.
If no examples are to be entered and the lower pane is not desired, use ADD-TRANSFORMER with the same arguments except for the string of examples.
(add-to number1 number2)
Returns a closure that adds two numbers. The numbers may come from
constants, lists, stockpiles, generators, etc.
If NUMBER2 is a list, each value from the list is added in turn
to NUMBER1 (example 1).
If NUMBER2 is a generator, a new value is chosen each time and added to NUMBER1 (example 2).
Both numbers can change also over time (examples 3-6).
EXAMPLE 1: (for-example (add-to 60 '(0 2 4 5 7 9 11 12)))
EXAMPLE 2: (for-example (add-to 60 (random-value -12 12)))
EXAMPLE 3: (for-example (add-to (random-choice '(c2 c4 c6)) (rv -3 3)))
EXAMPLE 4: (plot (add-to (line 100 40 80) (rv -3 3)))
EXAMPLE 5: (plot (add-to (group (rv 40 80) 10) (rv -3 3)))
EXAMPLE 6: (for-example (midi->notename (add-to '(c4 d4 e4 f4) '(-12 12))))
(add-tool-brief name text)
Adds a brief TEXT description for a tool called NAME.
NAME should be symbol and TEXT should be a string (between "").
NAME and TEXT will appear in the table made by the menu item Brief descriptions (example 1).
EXAMPLE 1: (add-tool-brief 'useless
"Perform a useless task")
(add-transformer-brief name text)
Adds a brief TEXT description for a transformer called NAME.
NAME should be symbol and TEXT should be a string (between "").
NAME and TEXT will appear in the table made by the menu item Brief descriptions (example 1).
EXAMPLE 1: (add-transformer-brief 'make-uglier
"Make something uglier")
(adjust-internal-representation section)
Destructively adjusts a section. This tool gathers notes that occur at the same time in a section into the internal representation of one chord. The longest duration occuring at that start time is assigned to the chord. Note that the destructive change is irreversible.
The basic time to use this tool is if a section has been read in from a midi file, chords occur, and you want to extract pitches from that section, e.g. for a transition table.
Another use would be to create chords within a parallel section so that they can be extracted as a group of pitches.
If a section S1 exists, example 1 would do the adjustment.
The effect of using this tool can be seen in the output produced by section info (example 2).
EXAMPLE 1: (adjust-internal-representation s1)
EXAMPLE 2: (show-text s1)
(alea low high)
Returns a uniformly distributed random number between LOW and HIGH (inclusive). If both LOW and HIGH are integers, the result is an integer (example 1). If one or both of the arguments is a real number, the result is a real number (example 2). If one or both of the arguments is a ratio (e.g. 1/2), a real number is also returned.
ALEA is not a generator. For a generator that does this, see RANDOM-VALUE.
EXAMPLE 1: (print-result (alea 500 1000))
EXAMPLE 2: (print-result (alea 500.0 1000))
(all-intervals elements &key number)
Returns a list of all combinations of the numbers in ELEMENTS in which each interval (distance between numbers) occurs once (example 1).
The possible intervals with the elements 1, 2, 3, 4 are 1, 2, and 3. In the solution in example 1, each of these intervals occurs one time.
The values in ELEMENTS should be numbers. AC Toolbox symbols for pitch, such as c3, can also be used. ELEMENTS may be a list or stockpile (examples 2-3).
For larger numbers of elements, the calculation time can be quite long (from one to several minutes depending on the speed of the computer) (example 4).
To limit the number of solutions, bind the keyword NUMBER to a smaller value (example 5).
Note that the calculation of the all-interval lists will always produce the same series of results if the elements are entered in the same order. To get the output in a different order, change the order of the elements (examples 6-8).
To produce one all-interval list with some largish number of elements, shuffle the elements and then produce only one list. This speeds up the process when only one list is desired (example 9).
A list of intervals can be chosen with a CHOICE generator (examples 10-12).
The values from an all-interval list can be read using READ-PERMUTATION. This will read permutations and return each element one at a time. To randomly choose which permutation to read, bind keyword RANDOM to t (examples 13-14)
If a stockpile contains results of ALL-INTERVALS, that one stockpile can be saved as an environment and reloaded for subsequent use. This eliminates the need to recalculate a stockpile containing lists of all possible all-interval lists.The menu item File > Save Some Objects can be used to save just one object (the stockpile) (example 15).
Many common music theoretical constraints on examining all intervals have not been implemented.
EXAMPLE 1: (for-example (all-intervals '(1 2 3 4)))
EXAMPLE 2: (for-example (all-intervals '(c3 c#3 d3 d#3)))
EXAMPLE 3: (for-example
(stockpile->notename (all-intervals '(c3 c#3 d3 d#3))))
EXAMPLE 4: (for-example
(all-intervals (from 0 11))
:number-per-line 1)
EXAMPLE 5: (for-example
(all-intervals (from 0 11)
:number 10)
:number-per-line 1)
EXAMPLE 6: (for-example (all-intervals '(1 2 3 4)))
EXAMPLE 7: (for-example (all-intervals '(3 4 1 2)))
EXAMPLE 8: (for-example
(all-intervals (rearrange-stockpile'(1 2 3 4) 'shuffle)))
EXAMPLE 9: (for-example
(all-intervals
(rearrange-stockpile (from 0 11) 'shuffle)
:number 1))
EXAMPLE 10: (for-example (series-choice (all-intervals '(1 2 3 4))))
EXAMPLE 11: (fill-template construct-stockpile ints
(all-intervals (from 1 6)))
EXAMPLE 12: (for-example (random-choice ints))
EXAMPLE 13: (for-example
(read-permutation (all-intervals (from 1 5))))
EXAMPLE 14: (for-example
(read-permutation (all-intervals (from 1 5))
:random t))
EXAMPLE 15: (fill-template construct-stockpile all
(all-intervals (from 0 11)))
(allow-interval generator interval-or-list &key pitch-class stop)
Returns a closure. When applied, a value is returned by applying GENERATOR. After the first value has been returned, the next value is limited to a distance of one of the intervals specified in INTERVAL-OR-LIST. GENERATOR is applied until a value with an allowed interval is found.
Example 1 only allows an interval of 1.
Example 2 allows repetitions and an interval of 1.
Interval refers to the numeric interval created by two adjacent values.
The user is responsible for GENERATOR being able to produce an allowed interval. If the generator has not been able to do that after STOP number of attempts, the execution will abort and an error message will appear. The default value for STOP is 100 attempts (example 3).
If the values produced by GENERATOR are to be considered pitches and, for instance, both unisons and octaves should be blocked, the values produced by generator should be reduced to their pitch-class before the intervals are calculated. Binding the keyword PITCH-CLASS to t will do this (example 4).
If quartertone intervals are desired, the generated pitches should be rounded off to units of 0.5. Example 5 should how floating point pitch values are rounded to quartertones. Example 6 shows how quartertones could be used together with ALLOW-INTERVAL.
EXAMPLE 1: (for-example
(allow-interval (random-value 1 5) 1))
EXAMPLE 2: (for-example
(allow-interval (random-value 1 5) '(0 1)))
EXAMPLE 3: (for-example
(allow-interval (random-value 1 5)
'(0 1 2 3 4) :stop 500))
EXAMPLE 4: (for-example
(midi->notename
(allow-interval
(random-value c3 c5)
'( 1 3 4) :pitch-class t)))
EXAMPLE 5: (for-example
(ro (random-value 60.0 72) 0.5))
EXAMPLE 6: (for-example
(allow-interval (ro (random-value 60.0 72) 0.5)
'(1 2.5 3 3.5 4)))
(allow-larger-quantization-stack)
This tool is only useful when writing a FOMUS file (File>Write FOMUS File) and the quantization option has been chosen. A large section may cause a stack overflow error message. Additional space can be allocated for that stack with this tool (example 1).
Each time the tool is evaluated, the stack size will be increased the next time that a section is quantized. Increasing the stack size too often may limit the effectiveness of the program. There may also be a limit on how much space is available for the stack.
EXAMPLE 1: (print-result (allow-larger-quantization-stack))
(always value)
Returns a closure that always returns a copy of VALUE (example 1).
EXAMPLE 1: (for-example (always 10))
amadeus
Amadeus is an inexpensive sound editor for the Macintosh (example 1).
Spectral output in a text file can be read in the AC Toolbox using READ-SPECTRUM-FILE.
The menu item Analyze>Spectrum can be used to produce the analysis. Save this to a file in the format TEXT (not importable).
EXAMPLE 1: (open-url "http://www.hairersoft.com/Amadeus.html")
(anchor shape n desired-first desired-last lower upper &key round)
Returns a list of values made by mapping a shape. The starting and end point for the shape are specified. If necessary, the shape is adjusted to make the starting and end point possible.
ANCHOR will map either a shape, a list, a stockpile, or a generator to be a list with N values starting with DESIRED-FIRST and ending with DESIRED-LAST.
LOWER and UPPER are used to initially scale the shape, etc. to be between these values (just as is the case with CONVERT). LOWER and UPPER represent lower and upper limits for the shape. This intermediate result is rescaled to force the shape to start and end with the specified values DESIRED-FIRST and DESIRED-LAST. This rescaling process may cause the mapped version of the shape to contain values outside of the range of LOWER and UPPER or to fall short of those values. The aim is insure that the list which is returned will start and end with the desired values. Values in between are adjusted to make this happen and still keep some relation to the shape being mapped.
In examples 1-2, the default shape sine-shape is mapped to be 10 values between 40 80. The beginning and end values are 60.
The shape can be distorted by the choice of DESIRED-FIRST and DESIRED-LAST. In example 3, DESIRED-FIRST is set to 40.
The values in the list are returned as integers if DESIRED-FIRST, DESIRED-LAST, LOWER, and UPPER are all integers. If one or more of these values is a real number, real numbers are returned in the list (example 4).
The choice of values for DESIRED-FIRST and DESIRED-LAST has a strong influence on the result of this function and the range and shape the values assume. Displaying the outcome of the process is an useful way to inform yourself of the result.
Keyword ROUND can be bound to a quantization factor (example 5).
EXAMPLE 1: (for-example (anchor sine-shape 10 60 60 40 80))
EXAMPLE 2: (plot (anchor sine-shape 100 60 60 40 80))
EXAMPLE 3: (plot (anchor sine-shape 100 40 60 40 80))
EXAMPLE 4: (for-example (anchor sine-shape 10 60 60 40 80.0))
EXAMPLE 5: (for-example
(anchor sine-shape 10 60 60 40 80.0 :round 0.5))
(anything function &rest values)
ANYTHING produces a function appropriate for use with WITH, WITHOUT, or FILTER-STOCKPILE. The first argument should be the name of a function. Zero, one, or two additional arguments are accepted.
Example 1 filters out any value < 60.
Example 2 filters out any value = 5.
Example 3 only allows values in the range 60-72.
Example 4 only allows values outside the range 60-72.
Example 5 only allows the values 60, 64, 67, and 69.
ANYTHING is an alternative name for the tool PREDICATE (example 6). Additional examples of using PREDICATE can be found in its documention (example 7).
EXAMPLE 1: (for-example
(without (anything < 60) (1/f-value 128 40 80)))
EXAMPLE 2: (for-example
(without (anything = 5) '(1 5 2 5 3 5)))
EXAMPLE 3: (for-example
(with (anything inside 60 72) (random-value 40 80)))
EXAMPLE 4: (plot
(with (anything outside 60 72) (random-value 40 80)))
EXAMPLE 5: (for-example
(with (anything member '(60 64 67 69))
(random-value 40 80)))
EXAMPLE 6: (for-example
(with (predicate < 60) (random-value 40 80)))
EXAMPLE 7: (show-help 'predicate)
(apply-function function &rest args)
Returns a closure. When applied, FUNCTION is applied to one result of each of the arguments. ARGS may be generators, stockpiles, lists, constants, etc.
Any number of arguments may be used. Each time the generator is applied, each argument will be asked for a new value. FUNCTION should be preceded by a function quote: #' (examples 1-2).
See generator ON-THE-FLY for an alternative way of doing something similar.
EXAMPLE 1: (for-example
(apply-function #'+ '(10 20 30) '(40 50 60)
'(100 200 300 400)))
EXAMPLE 2: (plot
(apply-function #'+ (convert line-shape 100 1 100)
(random-value -5.0 5)))
(apply-object object)
Intended for use with controllers and schemes.
If OBJECT is a controller, one value is produced by the controller's closure. That value is also added to the controller's history.
If OBJECT is a scheme, the entire scheme-of-variations is executed, i.e. all objects included in the scheme are destructively redefined, in the same order they are included in the scheme.
(arc number-of-steps start finish &key (curve 2) round)
ARC is a shortcut (abbreviation for EXPONENTIAL-MOTION (examples 1-2).
It returns the next point on a curve. After NUMBER-OF-STEPS values, it starts at the beginning again.
See the help for EXPONENTIAL-MOTION for more information (example 3).
EXAMPLE 1: (plot (arc 100 0.0 100))
EXAMPLE 2: (plot (arc 100 0.0 100 :curve 4))
EXAMPLE 3: (show-help 'exponential-motion)
(at-csound-time parameter transformer start end ...)
This tool transforms events in a Csound score file that start between the specified START and END times. There can be more than one set of START and END times specified. A new file will be written for the transformed data.
START and END are specified in the units used in the original Csound score file.
PARAMETER should be the number of the parameter in the score file. Parameters start at 1.
TRANSFORMER can be any transformer that does not specifically require note data. For example, this excludes TRANSFORM-IF, TRANSFORM-AND, and TRANSFORM-OR.
AT-CSOUND-TIME should be used in the Listener or in an edit window. It is not suitable for use in the dialog for transforming csound files.
Example 1 is a score object which will make a score file that can be transformed. It should be rendered using the orchestra in the the folder Support/FileExamples (test csound.orc).
Example 2 transforms parameter 5 (frequency in the orchestra which was used) for events starting between time 4 and 8 seconds.
Example 3 transforms parameter 5 for events starting either between time 3-4 seconds or between time 7-8.5 seconds.
EXAMPLE 1: (fill-template csound-score-object
score1 "f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1 (until-time 10) 1
0
(random-value 0.1 0.2)
0.4
(random-value 500.0 1000))
EXAMPLE 2: (at-csound-time 5 (transpose 1000) 4 8)
EXAMPLE 3: (at-csound-time 5 (transpose 1000) 3 4 7 8.5)
(at-osc-time arg transformer start end ...)
This tool transforms events in an OSC file that start between the specified START and END numbers. There can be more than one set of START and END times specified. A new file will be written for the transformed data.
START and END are specified in seconds.
ARG should be a valid argument in the OSC file, e.g. "freq". The actual argument depends on the SynthDef.
TRANSFORMER can be any transformer that does not specifically require note data. For example, this excludes TRANSFORM-IF, TRANSFORM-AND, and TRANSFORM-OR.
AT-OSC-TIME should be used in the Listener or in an edit window. It is not suitable for use in the dialog for transforming OSC files.
Example 1 is an OSC score object which will make a file that can be transformed. The SynthDef sine1 can be
found in the folder Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
Example 2 transforms the freq argument for events starting between time 4 and 8 seconds.
Example 3 transforms the freq argument for events starting between time 3-4 seconds or between time 7-8.5 seconds.
EXAMPLE 1: (fill-template osc-score-object osc1 (until-time 10) "sine1"
nil nil nil 1
0
"dur" (rv 0.01 0.02)
"amp" 0.2
"freq" (rv 500.0 1000))
EXAMPLE 2: (at-osc-time "freq" (transpose 1000) 4 8)
EXAMPLE 3: (at-osc-time "freq" (transpose 1000) 3 4 7 8.5)
(attacks interval &key low high number)
This tool returns a list of attack times mapped to be between LOW and HIGH. LOW defaults to 0.0 and HIGH to 100.0 making it convenient for use in a density section using a function. With other values for HIGH (and/or LOW) it could be useful in calculating start times for a Csound object or OSC score.
NUMBER defaults to (from-number), e.g. the number specified in a section, Csound object or OSC score.
ATTACKS starts with 0.0 and adds a value produced by INTERVAL to that value. A new value from INTERVAL is added to that result. This continues until NUMBER values have been produced. The resulting list is then mapped to be between LOW and HIGH (example 1).
INTERVAL can be a generator, stockpile, constant, etc.
There are two important points regarding this tool.
1) The new value is added to the previous result. This means that with positive interval values, the list will be in ascending order.
2) The whole list is scaled to be between LOW and HIGH.
These two points suggest that the absolute values produced by INTERVAL are less important than the relationships of successive intervals. The intervals in examples 2-3 have different values but the same relationship. They will therefore produce the same result.
In a density section with a function, attack times between 0 and 100% are mapped to fill a time value in seconds. ATTACKS can produce a list suitable for the attack parameter of a density section. Since NUMBER defaults to (from-number), the number specified in the dialog will be the number of values created by attacks (example 4).
The object produced in example 4 uses a time interval created with exponential-value. This is similar to the idea used by Xenakis in his Stochastic Music Program where a probabilistic function was used to create time intervals between events.
If ATTACKS is not used, the function for the attack parameter will produce absolute start times as percentage values. If exponential-value is used to generate those values, the result is start times clustered near the beginning of the section (since exponential-value tends to produce values near its lower threshold) (example 5).
In example 6, a smaller upper threshold is used for exponential-value. This may decrease the size of the intervals in the result since it decreases the maximum possible (relative) interval size. Compare this with ATTACK1.
Other generators, such as PRIME-NUMBER and FIBONACCI can also be used to determine attack times (example 7).
Start values for a Csound score can be generated with this tool. In this context, LOW and HIGH refer to a duration in seconds (rather than a percentage of a duration as is the case with a density section). The value for HIGH will be the actual attack time for the last event in the score.
Example 8 should be rendered using the instrument definition in 'test csound.orc' found in 'Support/FileExamples'. This can be specified in the Csound File Options dialog. ATTACKS creates the start times for the events. HIGH was set to 20 which means that the last attack time will be at 20 seconds.
Example 9 does something similar with an OSC score. Synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd). It should be compiled (once) in the SuperCollider language application.
ATTACKS should not be used in a dialog which uses UNTIL-TIME to specify the number of events.
EXAMPLE 1: (for-example
(attacks (exponential-value 0.1 .1 100) :number 10))
EXAMPLE 2: (for-example
(attacks '(2 1) :number 10))
EXAMPLE 3: (for-example
(attacks '(4 2) :number 10))
EXAMPLE 4: (fill-template density-section attack1 20 15
(attacks (exponential-value 0.0 0.1 100))
100 (rv 40 80) mf 1)
EXAMPLE 5: (fill-template density-section attack1b 20 15
(exponential-value 0.0 0.1 100)
100 (rv 40 80) mf 1)
EXAMPLE 6: (fill-template density-section attack2 20 15
(attacks (exponential-value 1.0 0.1 10))
100 (rv 40 80) mf 1)
EXAMPLE 7: (fill-template density-section attack3 20 10
(attacks (prime-number))
100 (rv 40 80) mf 1)
EXAMPLE 8: (fill-template csound-score-object attack-csound
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1 100 1
(attacks (exponential-value 1.0 0.1 30) :high 20)
(rv 0.1 0.2) 0.1 (rv 100.0 1000))
EXAMPLE 9: (fill-template osc-score-object attack-osc
100 "sine1" nil nil nil 1
(attacks (exponential-value 1.0 0.1 30) :high 20)
"dur" (rv 0.1 0.2) "amp" 0.2 "freq"
(rv 100.0 1000))
audacity
Audacity is an open source sound editor (example 1).
Spectral output in a text file can be read in the AC Toolbox using READ-SPECTRUM-FILE.
To make the spectral text file:
select the sound to be analyzed
produce a spectrum with Analyze>Plot Spectrum
click on the Export button and save as a text file.
EXAMPLE 1: (open-url "http://audacity.sourceforge.net/")
(average thing &optional number)
Returns the average value of THING if it is a list or stockpile containing numbers (example 1).
The average value of a beta distribution is a/(a+b). This could be tested (example 2-3).
In example 2, both a and b are .2, therefore a/(a+b) = .2/.4 The average result produced above should be about .5
If THING is a generator, it is applied NUMBER of times and the average value is returned (example 4).
The value of NUMBER is 100. To increase the number of applications of the generator, provide NUMBER with a new value (example 5).
EXAMPLE 1: (print-result (average '(1 2 3 4)))
EXAMPLE 2: (fill-template generate-stockpile beta-stock 1000
(beta-value 0.0 1 .2 .2))
EXAMPLE 3: (print-result (average beta-stock))
EXAMPLE 4: (print-result (average (beta-value 0.0 1 .2 .2)))
EXAMPLE 5: (print-result (average (beta-value 0.0 1 .2 .2) 1000))
(backwards object)
Backwards returns a copy of object, but with the elements in reverse order. Backwards is an operator which works on AC Toolbox objects, such as shapes, masks, sections, communities, stockpiles and note structures.
It is the same operator which is available using the Menu item Methods (examples 1-2).
EXAMPLE 1: (plot expo-shape)
EXAMPLE 2: (plot (backwards expo-shape))
(band-pass low high)
This tool is intended to be used as a filter for WITH, WITHOUT, FILTER-STOCKPILE, FILTER-AND, FILTER-IF, FILTER-OR, etc.
It allows values which are >= LOW and <= HIGH (example 1).
LOW and HIGH can change over time.
EXAMPLE 1: (for-example
(with (band-pass 40 60)
(1/f-value 100 1 100)))
(band-reject low high)
This tool is intended to be used as a filter for WITH, WITHOUT, FILTER-STOCKPILE, FILTER-AND, FILTER-IF, FILTER-OR, etc.
It allows values which are < LOW or > HIGH (example 1).
LOW and HIGH can change over time.
EXAMPLE 1: (plot
(with (band-reject 40 60)
(random-value 1 100)))
(band-pass low1 high1 low2 high2 ...)
This tool is intended to be used as a filter for WITH, WITHOUT, FILTER-STOCKPILE, FILTER-AND, FILTER-IF, FILTER-OR, etc.
It is a bank of band-pass filters. It allows values >= LOW1 and <= HIGH1 or >= LOW2 and <= HIGH2 (example 1). There can be any number of filters (low high pairs) included in the bank.
The boundaries for LOW and HIGH can change over time.
EXAMPLE 1: (plot
(with (bank 10 20 40 60 80 100)
(random-value 1 100)))
(basic-error-message string)
The basic template for printing (error) messages in a message dialog (example 1). The intended use of this tool is to add error messages to functions that a user may choose to add to the AC Toolbox.
EXAMPLE 1: (basic-error-message "This does not work.")
(beta a b)
This function will produce a value between 0 and 1 according to a beta distribution when it is applied. A and B should be > 0 and < 1. The smaller the value of A is, the greater the probability that a result near 0 will be produced. The smaller the value of B is, the greater the probability that a result near 1 will be produced (examples 1-2).
A check has been included to prevent A or B from being set to 0 (since this would cause divide by 0 errors). In this case, a minimum value of 0.0001 is used.
See BETA-VALUE for an application of this tool to produce values between specified limits.
See BETA-CHOICE for aan application of this tool to select values from a list or stockpile.
EXAMPLE 1: (for-example (generate (beta .3 .3)))
EXAMPLE 2: (for-example (generate (beta .1 .1)))
(beta-choice sequence a b)
Returns a closure. When applied, a value is chosen from the sequence according to a beta distribution. This distribution tends to choose values near its two limits. A and B should be > 0 and < 1. The smaller the value of A, the greater the probability that an element near the beginning of the sequence will be chosen. The smaller the value of B, the greater the probability that an element near the end of the sequence will be chosen (examples 1-2).
A and B can change over time (example 3).
EXAMPLE 1: (for-example (beta-choice '(a b c d e f g h) .5 .5))
EXAMPLE 2: (for-example (beta-choice '(a b c d e f g h) .1 .1))
EXAMPLE 3: (for-example (beta-choice '(a b c d e f g h)
(line 20 .5 .1) .1))
(beta-tendency-choice sequence mask1 ...)
Returns a closure. When applied, chooses an element from SEQUENCE according to a tendency mask. Similar to the closure returned by TENDENCY-VALUE except that the random choice between the changing boundaries is made with a beta function.
The mask values are: (N A1 A2 Z1 Z2 A B). A and B are the parameters for the beta function. A1, A2, Z1, Z2 should be expressed in percentages (0-100) (example 1).
See the help for the generator TENDENCY-CHOICE and for the tool BETA for more information.
EXAMPLE 1: (for-example
(beta-tendency-choice '(a b c d e f g h i)
'(20 0 20 80 100 .2 .2)))
(beta-tendency-value mask1 ...)
Returns a closure. When applied, produces a numerical result in a way similar to the closure returned by TENDENCY-VALUE. The difference is that the random-choice between the moving boundaries is made with a beta function instead of an uniform random distribution as is the case with an ordinary tendency mask. See the help for the generator TENDENCY-VALUE for a discussion of the parameters of a tendency mask. See the help for the tool BETA for a discussion of the parameters of the beta function.
A mask should contain (N A1 A2 Z1 Z2 A B) where A and B are the parameters for the beta function (examples 1-2).
Any number of masks may be used (example 3). The type of the returned values is determined by the type (integer or real) of the mask boundaries (A1 A2 Z1 Z2).
Another way of realizing this concept is to define a mask object and use the tool CONVERT to produce a list of values within this mask. BETA-VALUE could be used as a generator with CONVERT to produce the values. See CONVERT.
EXAMPLE 1: (for-example (beta-tendency-value
'(20 1 100 90 100 .2 .2)))
EXAMPLE 2: (plot (beta-tendency-value
'(100 1 100 90 100 .2 .2)))
EXAMPLE 3: (plot (beta-tendency-value
'(50 1 100 90 100 .1 .1)
'(50 1 100 100 1 .1 .1)))
(beta-value low high a b &key round)
Returns a closure. When applied, it will produce a number between LOW and HIGH according to a beta distribution. A beta distribution tends to concentrate values near LOW and HIGH, depending on the values of A and B. A and B should be > 0 and < 1. The smaller the value of A, the greater the probability that a value near LOW will result. The smaller the value of B, the greater the probability that an element near HIGH will result. The type of the output (integer or real) is determined by the type of LOW and HIGH (examples 1-6).
To quantize the result, bind ROUND to a quantization unit (example 7).
LOW, HIGH, A, and B can vary over time (examples 8-9).
The average value of a beta distribution is a/(a+b) (example 10).
The shortcut for BETA-VALUE is BV (example 11).
EXAMPLE 1: (for-example (beta-value 60 72 .5 .5))
EXAMPLE 2: (for-example (beta-value 60 72 .1 .1))
EXAMPLE 3: (for-example (beta-value 0.0 100 .2 .2))
EXAMPLE 4: (make-histogram (beta-value 1 100 .5 .5))
EXAMPLE 5: (make-histogram (beta-value 1 100 .2 .2))
EXAMPLE 6: (plot (beta-value 1 100 .2 .2))
EXAMPLE 7: (for-example (beta-value 40.0 80 .2 .2 :round 0.25))
EXAMPLE 8: (plot (beta-value (line 100 1.0 50)
(line 100 10.0 60) .2 .2))
EXAMPLE 9: (plot
(beta-value 1 100 (line 100 .5 .1) .2))
EXAMPLE 10: (print-result (average (beta-value 0.0 1 .2 .2) 1000))
EXAMPLE 11: (plot (bv 1 100 .2 .2))
(block-interval generator interval-or-list &key pitch-class stop previous)
Returns a closure. When applied, a value is returned by applying GENERATOR. The value will not create an interval that is blocked. Blocked intervals are included in INTERVAL-OR-LIST.
To prevent a value from being repeated, block 0 (example 1).
To prevent a value from forming an interval of size 0 or 1 (example 2).
The blocking refers to the numeric interval created by two adjacent values.
The user is responsible for GENERATOR being able to produce a non-blocked interval. If the generator has not been able to do that after STOP number of attempts, the execution will abort and an error message will appear. The default value for STOP is 100 attempts (example 3).
Sometimes the reason that the generator cannot produce an appropriate value is that after the first value is chosen, no allowed intervals are possible. A dummy value for the first previous value can be bound to the keyword PREVIOUS (example 4).
If the values produced by GENERATOR are to be considered pitches and for instance, both unisons and octaves should be blocked, the values produced by generator should be reduced to their pitch-class before the intervals are calculated. Binding the keyword PITCH-CLASS to t will do this (example 5).
To block intervals from a generator that produces chords, use CLEANUP-CHORD (example 6).
EXAMPLE 1: (for-example
(block-interval (random-value 1 5) 0))
EXAMPLE 2: (for-example
(block-interval (random-value 1 5) '(0 1)))
EXAMPLE 3: (for-example
(block-interval (random-value 1 5)
'(0 1 2 3 4) :stop 500))
EXAMPLE 4: (for-example (block-interval (random-value 1 5)
'(0 1 2 3) :previous 1))
EXAMPLE 5: (for-example
(block-interval
(random-choice
'(c3 c#3 d3 d#3 e3 f3 c4 c#4 d4 d#4 f4))
'(0 1) :pitch-class t))
EXAMPLE 6: (show-help 'cleanup-chord)
(bpm number)
Converts a NUMBER of beats per minute into a value in milliseconds that is appropriate to use as a clock unit in a section specification (examples 1-2).
It can also be used for some Midi objects and streams.
When used with streams, NUMBER can change over time (example 3). This example controls the clock value using stream slider 1. Stream sliders can be accessed with the menu item Tools>Stream Sliders.
EXAMPLE 1: (print-result (bpm 125))
EXAMPLE 2: (fill-template data-section my-section (bpm 140) 20
1 c2 ff 1 0)
EXAMPLE 3: (fill-template data-stream stream1
(bpm (slider-value 1 120 600))
1 (rv 40 80) f 1)
(bundle time message)
Bundle is intended for use with OSC score objects. It contains a time value in seconds for sending the message and a message to be send.
Bundles can be specified in the Include edit item of an OSC Score Object. Bundles can also be specified in a OSC Score Bunch Object (menu item Bunch of Bundles).
The message should be specified using the tool message. The message can contain any number of valid SuperCollider Server commands.
Each bundle can only contain one message.
In both the Include edit item and the OSC score bunch object, one or more bundles can be specified (example 1).
This bundle would send a message at time 0 to allocate buffer space and read a sound file into that buffer.
Example 2 uses this in a OSC score object with synthdef filteredbuf.
It is also possible to test synthdefs by writing a file with SuperCollider Server commands though it is probably more sensible to do this using the SuperCollider language application or a OSC score object.
Example 3 starts synthdef sine1 and assigns values to the dur and freq arguments. The c_set message is the final one to allow the synthdef time to sound.
SuperCollider Server commands can be found in the SuperCollider documentation.
The source for the synthdefs sine1 and filteredbuf can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
EXAMPLE 1: (print-result
(bundle 0 (message "/b_allocRead" 0 "sounds/a11wlk01-44_1.aiff")))
EXAMPLE 2: (fill-template osc-score-object osc2 1 "filteredbuf"
(gather-bundles (bundle 0 (message "/b_allocRead" 0 "sounds/a11wlk01-44_1.aiff")))
nil nil 1 0 "dur" 2 "freq" 500 "amp" 1 "rq" 0.5)
EXAMPLE 3: (fill-template osc-score-bunch bunch2 "(bundle 0 (message \"s_new\" \"sine1\" -1 1 0 \"dur\" 5 \"freq\" 800))
(bundle 6 (message \"c_set\" 0 0))")
(bv low high a b &key round)
BV is a shortcut (abbreviation) for BETA-VALUE (example 1).
See the help for BETA-VALUE for more information (example 2).
EXAMPLE 1: (make-histogram (bv 40 80 .2 .2))
EXAMPLE 2: (show-help 'beta-value)
(cal object1 operator1 object2 &rest expressions)
Calculates arithmetic expressions using infix notation. Objects may be constants, lists, stockpiles, or generators. Operators are Lisp functions such as + or *. A number or a list of numbers is returned depending on the input (examples 1-7).
CAL returns a list of values if a list or stockpile is used in an expression. Otherwise, a single number is returned.
In examples 4-5, two lists are added. If the lists are not the same size, the result will have as many values as the longest list.
Several operations can be used. They will be evaluated from left to right, as is the case with Supercollider and unlike the normal custom of mathematics (example 8).
A generator that is similar is ON-THE-FLY. CAL wil produce a fixed number of results. ON-THE-FLY will produce a new result each time it is applied (examples 9).
EXAMPLE 1: (print-result (cal 10 + 2))
EXAMPLE 2: (print-result (cal '(1 2 3) * 10))
EXAMPLE 3: (print-result (cal '(10 20 30) + (rv -1.0 1)))
EXAMPLE 4: (print-result (cal '(10 20 30) + '(5 6 7)))
EXAMPLE 5: (print-result (cal '(10 20 30) + '(5 6 7 8)))
EXAMPLE 6: (fill-template construct-stockpile
stock (from 1 10))
EXAMPLE 7: (for-example (cal stock + (rv -1.0 1)))
EXAMPLE 8: (print-result (cal 3 + 2 * 2))
EXAMPLE 9: (for-example (on-the-fly '(10 20 30) + (rv -1.0 1)))
capybara/pacarana
A Capybara and a Pacarana are hardware sound computation engines produced by the Symbolic Sound Corporation. They both are rodents.
For more information see example 1.
If a Capybara or Pacarana is available, Midi output can be routed to it via Midi Setup.
EXAMPLE 1: (open-url "http://www.symbolicsound.com")
(cauchy-choice stockpile alpha)
Returns a closure. When applied, a value is chosen from the stockpile according to a Cauchy distribution. STOCKPILE can be a list, stockpile, etc.
Cauchy spreads values symmetrically around a point. In this generator, the Cauchy distribution is used to generate index values to read the stockpile. Values are spread around the index for the middle of the stockpile. ALPHA controls the amount of the spread. Half of the values will be within the interval -ALPHA to +ALPHA (examples 1-3).
EXAMPLE 1: (for-example (cauchy-choice '(a b c d e f g h i j k) 2))
EXAMPLE 2: (for-example (cauchy-choice '(a b c d e f g h i j k) 5))
EXAMPLE 3: (plot (cauchy-choice (from 1 100) 10))
(cauchy-value threshold alpha &optional lower upper round)
Returns a closure. When applied, a value reflecting a Cauchy distribution is returned. Cauchy spreads values symmetrically around the threshold value. ALPHA controls the width of the spread. About half of the values are within the interval -ALPHA to +ALPHA (example 1).
There is no limit to the values that are produced. To discard results that are too small or too large, optional values for LOWER and UPPER can be provided. If a value is smaller than LOWER or larger than UPPER, it wll be discarded and the generator will try again to produce a boundary within the specified limits (examples 2-3).
When values for LOWER and UPPER are provided, care should be taken when specifying values. If the generator has trouble finding values in the interval between LOWER and UPPER, an error message will occur.
THRESHOLD, ALPHA, LOWER, and UPPER may vary over time (example 4).
The type of the result is determined by the type of THRESHOLD (example 5). If THRESHOLD is an integer, the result is truncated to be an integer.
To quantize the result with another unit, bind ROUND to a quantization unit (example 6).
EXAMPLE 1: (plot (cauchy-value 0 10))
EXAMPLE 2: (plot (cauchy-value 0 10 -50 50))
EXAMPLE 3: (plot (cauchy-value 60 5 30 90))
EXAMPLE 4: (plot (cauchy-value (line 100 30 60)
5 20 90))
EXAMPLE 5: (for-example (cauchy-value 60 10 40 80))
EXAMPLE 6: (for-example (cauchy-value 60.0 10 40 80 0.5))
(cg generator low high)
This generator is a shortcut for CLIP-GENERATOR.
It clips values produced by GENERATOR to be within the limits LOW and HIGH (see example 1).
If LOW is NIL and HIGH is included, the value is allowed if it is < HIGH (example 2).
If HIGH is NIL (or omitted), the value is allowed if it is > LOW (example 3).
See the documentation for CLIP-GENERATOR for more information and examples (example 4).
EXAMPLE 1: (for-example (cg (line 20 1 20) 10 15))
EXAMPLE 2: (for-example (cg (line 20 1 20) nil 15))
EXAMPLE 3: (for-example (cg (line 20 1 20) 10))
EXAMPLE 4: (show-help 'clip-generator)
(change-object-order)
This tools opens a list panel with the names of all of the objects in the order in which they were made. Default objects are not included in this list (example 1).
The order of the objects can be changed by dragging them to a different position.
When the SET button is pressed, the order will be changed.
This tool is useful when saving objects as examples in a specific order.
EXAMPLE 1: (change-object-order)
(change-octave new-octave)
Returns a closure that presumably should be applied to pitch. When applied, the MIDI note number of the pitch is adjusted to reflect the octave specified by NEW-OCTAVE. Octave reflects the current preference for middle C (either c3 or c4). If c4 is the preference, octaves should range from -1 to 9. For c3, use -2 to 8. The preference is specified in the Preferences dialog.
NEW-OCTAVE can change over time and may be a constant, list, generator, etc. (examples 1-2).
EXAMPLE 1: (show-transformation (change-octave 2)
'(60 64 67))
EXAMPLE 2: (show-transformation (change-octave (random-value 0 4))
'(60 64 67))
changing stockpiles in a generator
There are essentially two options to use different stockpiles with a -choice generator, such as series-choice.
1. Generator SELECT-STOCKPILES allows stockpiles to be changed every NUMBER of times (examples 1-2).
2. Several generators with stockpiles can be created and a selection made among them with SELECT-GENERATOR (examples 3-4).
ACT-IF is another way to select among a set of generators (examples 5-6).
EXAMPLE 1: (plot
(select-stockpiles (rv 5 10) random-choice
(series-choice (list (from 1 10) (from 50 100)))))
EXAMPLE 2: (show-help 'select-stockpiles)
EXAMPLE 3: (plot
(select-generator
(random-choice (list
(random-choice (from 1 20))
(random-choice (from 50 80))))
(rv 5 10)))
EXAMPLE 4: (show-help 'select-generator)
EXAMPLE 5: (plot (act-if (group (rv 1 4) 10)
= 1 (rc '(1 5 10 20 30))
else = 2 (rc '(100 120 140 150 165))
else = 3 (rc (from 200 250))
else (rc (from 300 350))))
EXAMPLE 6: (show-help 'act-if)
(changing-weights number value1 weight1 value2 weight2 ...)
Returns a closure. When applied, a value is chosen from a group of possibilities according to a specified weight. The weight reflects the possible frequency of occurance for the corresponding value.
This generator is similar to ratio-choice except that the weights can vary over time. The syntax is also different.
Any of the parameters may be bound to a constant, list, generator, etc. and therefore can vary over time.
NUMBER is the number of values chosen before the next group of weights is used. In example 1, 10 values are chosen using the weight 5 for value 1 and 1 for value 2. After 10 results have been chosen, 10 more are chosen with the weight 5 for 1 and 2 for 2. After 10 results have been chosen, 10 more are chosen with the weight 5 for 1 and 3 for 2. Etc.
When the process has been exhausted, it starts again from the beginning.
NUMBER could change over time by being a list, generator, etc. (example 2).
Values and their weights could also be specified using generators. In example 3, the number of choices before the weights change is determined by a generator: (random-value 5 10). Each time a number if needed, the generator is applied.
The weight for value 1 is determined by a generator: (random-value 1 5). Each time a new weight is needed, the generator is applied. The weight for value 2 is read from a list: '(1 2 3 4 5). Each time a new weight is needed, the next value from the list is read. The last value is determined by a generator: (series-value 3 5). Its weight is a constant: 1. One value is chosen with the generator each time a new stockpile of values is filled according to the weights.
A weight of 0 is allowed. To have a value available at the beginning of the selection process but not at the end, the weight could move to 0 (example 4).
EXAMPLE 1: (for-example
(changing-weights 10
1 5
2 '(1 2 3 4 5))
:number 50)
EXAMPLE 2: (for-example
(changing-weights '(6 7 8 9 10)
1 5
2 '(1 2 3 4 5))
:number 40)
EXAMPLE 3: (for-example
(changing-weights (random-value 5 10)
1 (random-value 1 5)
2 '(1 2 3 4 5)
(series-value 3 5) 1)
:number 40)
EXAMPLE 4: (for-example
(changing-weights 10
60 '(5 4 3 2 1 0)
61 '(5 4 3 2 1 0)
62 '(5 5 5 5 1 1))
:number 60)
(chaotic-notes &key function number x y z rhythm pitch velocity channel plot defaults)
Returns a lists of note objects which have been created by mapping a chaotic function. This list is suitable for use as the notes in a note section.
In example 1, only default values were used. To see a list of the default parameters printed in a window, use example 2.
By default, a henon generator is used. It will produced a two-dimensional series of values.
To plot the results (in two dimensions) bind the keyword :plot to t (example 3).
The chaotic function used to create the notes must have at least 2 dimensions and no more than 3 dimensions. For example, with 2 dimensions, one dimension could be mapped to be pitch and the other could be mapped to be rhythm. X, Y, and possibly Z can be mapped to PITCH, RHYTHM, VELOCITY, or CHANNEL.
By default, X is mapped to pitches between c3 and c6, Y to rhythms between 1.0 and 3, and Z to velocities between 50 and 90. If only a 2-dimensional result is being mapped, then by default, only X and Y will be mapped.
To use a different function, use the keyword FUNCTION (examples 4-5).
The number of notes produced by the chaotic function is controlled with the NUMBER keyword. The default value is 200 (example 6).
With a generator which produces two-dimensional output such as henon and when X is mapped to pitch and Y to rhythm, velocity and channel both need values. They both have defaults values which can be replaced by other constant value, list, or generator (example 7).
In S4, X will be mapped to pitch (default), Y will be mapped to rhythm (default), velocity will be generated with (random-value 40 70).
In example 8, the channels for the notes will be 1 2 3 in succession. (The first note will be in channel 1, the second in channel 2, the third in channel 3, the fourth in channel 1, etc.).
If X should be mapped to pitch, but in the range of c3 to c4 instead of in the default range, see example 9.
To create pitch values that are real numbers, use at least one real number when specifying the range to map the pitches (example 10).
The keywords X, Y, and Z (if a three-dimensional list is produced), should be bound to a form with the parameter, lower boundary, and upper boundary, e.g.
:x (assign-to 'pitch c2 c5).
If X should be mapped to pitch and Y to velocity, rhythm will be assigned the default value (example 11).
Instead of using the default rhythmic value as in the example 11, rhythm will be the result of generator (random-value 1.0 2) in example 12.
With a three-dimensional generator, X, Y, and Z can be mapped. The default is X to pitch, Y to rhythm, and Z to velocity. To map X to rhythm, Y to velocity, and Z to pitch (example 13).
EXAMPLE 1: (fill-template note-section s1 100 200 (chaotic-notes) 0)
EXAMPLE 2: (chaotic-notes :defaults t)
EXAMPLE 3: (chaotic-notes :plot t)
EXAMPLE 4: (chaotic-notes :function (henon 0 0 1.4 0.2 1 :xy t)
:plot t)
EXAMPLE 5: (fill-template note-section s2 100 200
(chaotic-notes
:function (lorenz 0.1 0.1 0.1 10 28 3/8 1 :xyz t)
:plot t)
0)
EXAMPLE 6: (fill-template note-section s3 100 400
(chaotic-notes
:function (henon 0 0 1.4 0.2 1 :xy t)
:number 400)
0)
EXAMPLE 7: (fill-template note-section s4 100 200
(chaotic-notes
:function (henon 0 0 1.4 0.2 1 :xy t)
:velocity (random-value 40 70))
0)
EXAMPLE 8: (fill-template note-section s5 100 200
(chaotic-notes
:function (henon 0 0 1.4 0.2 1 :xy t)
:channel '(1 2 3))
0)
EXAMPLE 9: (fill-template note-section s6 100 200
(chaotic-notes
:x (assign-to 'pitch c3 c4))
0)
EXAMPLE 10: (fill-template note-section s7 100 200
(chaotic-notes
:x (assign-to 'pitch 60.0 72))
0)
EXAMPLE 11: (fill-template note-section s8 100 200
(chaotic-notes
:x (assign-to 'pitch c3 c4)
:y (assign-to 'velocity 50 90))
0)
EXAMPLE 12: (fill-template note-section s9 100 200
(chaotic-notes
:x (assign-to 'pitch c3 c4)
:y (assign-to 'velocity 50 90)
:rhythm (random-value 1.0 2))
0)
EXAMPLE 13: (fill-template note-section s10 100 200
(chaotic-notes
:function (lorenz 0.1 0.1 0.1 10 28 3/8 1 :xyz t)
:plot t
:x (assign-to 'rhythm 1.0 3)
:y (assign-to 'velocity 50 90)
:z (assign-to 'pitch c3 c5))
0)
(choice-generator stockpile generator)
Returns a closure. This is a general means to use a generator to look up values in stockpile. The generator should produce values in the range 0 - 100 % that can be translated to indices for reading in the stockpile (or list). This generator is useful if a choice generator has not been defined for a particular algorithm (example 1).
EXAMPLE 1: (for-example (choice-generator
'(1 2 3 4 5 6 7 8 -8 -5 -3 -2 -1)
(map/time (henon 0 0 1.37 0.3 1)
-1.28 1.27 0.0 100)))
(choose-interpolation chooser thing1 thing2 ...)
Returns a closure. When applied, it chooses between values from two adjoining things. The choice could be between a value from THING1 or THING2, or a value from THING2 or THING3, etc. There can be an indefinite number of things from which to choose.
The choice is made using the value of CHOOSER. If CHOOSER is 1 (or less), a choice will be made from THING1. If CHOOSER is 2, a choice will be made from THING2. If CHOOSER is 1.5, there is a 50-50 chance to choose from THING1 or THING2. If CHOOSER is 1.2, there is a greater chance to choose from THING1 than from THING2.
If three things are specified, a value of 2.5 for CHOOSER would cause a choice between THING2 and THING3 to be made.
CHOOSER can vary over time.
THING1, THING2, etc. can be lists, stockpiles, generators, etc.
This generator is similar to the generator INTERPOLATE. The difference is that INTERPOLATE changes over time based on a shape. CHOOSE-INTERPOLATION could change over time if the value of CHOOSER changed over time.
If a choice is made from values from two lists, the choice is between the first value from THING1 and the first value from THING2. Then the choice is between the second value from THING1 and the second value from THING2. Etc. (examples 1-3).
Lists do not need to have the same length. The generator will loop through them to find the next value (example 4).
The things to be interpolated can be generators (example 5).
If the value for CHOOSER should be derived from a shape or mask, it can be converted using CONVERT (example 6).
EXAMPLE 1: (for-example
(choose-interpolation 1.5 '(a b c) '(1 2 3)))
EXAMPLE 2: (for-example
(choose-interpolation 2.2 '(a b c) '(1 2 3) '(x y z)))
EXAMPLE 3: (for-example
(choose-interpolation
(line 20 1.0 3) '(a b c) '(1 2 3) '(x y z)))
EXAMPLE 4: (for-example
(choose-interpolation 1.5 '(a b c) '(1 2)))
EXAMPLE 5: (for-example
(choose-interpolation
(line 20 1.0 2)
(random-value 20 30)
(random-value 50 60)))
EXAMPLE 6: (for-example
(choose-interpolation
(convert sine-shape 20 1.0 2)
'(a b c) '(1 2 3)))
(chord-multiplication chord1 chord2 &key name)
Returns a closure. When applied, a chord (expressed as a list of Midi notenumbers) is returned. The chord contains for each pitch of CHORD1, a chord based on the interval structure of CHORD2.
Chords are expressed as a list of Midi notenumbers. They could also be derived from a list of chords, a stockpile, a generator, etc.
Example 1 produces a chord based on notenumber 50 using the intervals of CHORD2: 4 and 7. That result is 50 54 57. A chord based on notenumber 52 is also produced. Again the intervals of CHORD2 are used. That result is 52 56 59. The list produced by the generator contains both of these chords.
CHORD1 and CHORD2 may contain any number of pitches (example 2).
Both CHORD1 and CHORD2 may vary over time (examples 3-4).
Keyword NAME controls whether pitches are printed as numbers or as note names. When it is bound to T, note names are printed (example 5).
Chords can be filtered for repetitions and other intervals with CLEANUP-CHORD (example 6).
Chords can be combined into one chord with JOIN->CHORD (example 7).
Chords can be converted to a different range with CONVERT2 (example 8).
EXAMPLE 1: (for-example
(make (chord-multiplication '(50 52) '(60 64 67))))
EXAMPLE 2: (for-example
(make (chord-multiplication '(c3 e3 g3) '(c3 d3))))
EXAMPLE 3: (for-example
(chord-multiplication
(make-chord (random-value c2 b2) 3)
'(60 64 67))
:number 5 :number-per-line 1)
EXAMPLE 4: (for-example
(chord-multiplication
'(60 64 67)
(make-chord (random-value c2 b2) 3))
:number 5 :number-per-line 1)
EXAMPLE 5: (for-example
(make (chord-multiplication '(50 52)
'(60 64 67)
:name t)))
EXAMPLE 6: (show-help 'cleanup-chord)
EXAMPLE 7: (show-help 'join->chord)
EXAMPLE 8: (show-help 'convert2)
(chromatic start)
Returns a closure. When applied, a note number corresponding to the next value in a chromatic scale is generated. The first value in the series is START. The series could continue indefinitely (examples 1-2).
EXAMPLE 1: (for-example (chromatic 60))
EXAMPLE 2: (for-example (chromatic c2) :number 13)
(clean-up-blanks section)
Destructively adjusts a section. Some transformers, in particular remove-successive, may result in section events having no pitch. While this is not a problem in terms of the functioning of the Toolbox, it results in the number of events being higher than the number played, displayed, printed, etc. For this reason, anal retentive users might want to clean out events with no pitch. This tool does that.
Note that the change is irreversible.
Example 1 defines a section.
Transform this section with remove-successive to remove repetitive notes in successive chords (example 2).
Show the text version of the sections ds4 and ds4t. Notice that there is an empty spot for pitch in ds4t (examples 3-4).
Clean-up-blanks removes the event with no pitch from section ds4t (examples 5-6).
EXAMPLE 1: (fill-template data-section ds4 200 4 1
'((60 64 67) (60 64 67) (60 60 65) (60 65 67))
mf 1)
EXAMPLE 2: (fill-template transform ds4t ds4 :pitch (remove-successive))
EXAMPLE 3: (show-text ds4)
EXAMPLE 4: (show-text ds4t)
EXAMPLE 5: (clean-up-blanks ds4t)
EXAMPLE 6: (show-text ds4t)
(cleanup-chord chords &key (intervals 0) pitch-class)
Returns a closure. When applied, a chord returned by CHORDS is filtered. By default, pitch repetitions in a chord are filtered. Other intervals within the chord can also be filtered. Optionally, the intervals can be examined using pitch classes.
Example 1 filters chords which are represented as a list. The repetitions in the chord are removed. INTERVALS has a default value of 0. This means that values a distance of 0 from another value are removed.
Example 2 filters chords produced by a generator. INTERVALS may be bound to a constant value or to a list of values. The intervals of 0, 1, and 4 are filtered in this example.
Example 3 prints a chord generated by HARMONIC-CHORD. Example 4 binds PITCH-CLASS to t. Pitch values are reduced to pitch classes before being filtered. When INTERVALS is 0 and PITCH-CLASS is t, all repetitions of a pitch and its octaves are removed. In this case, octaves of C3 (48) are removed: 60, 72, 84. Octaves of G4 (67) are removed: 79, 91. And finally, an octave of E5 (76) is removed: 88.
This tool is useful if chords (lists of pitches) have been produced by generators such as JOIN->CHORD, FM-CHORD, HARMONIC-CHORD, FREQUENCY-SHIFT-CHORD, MIX-CHORDS, SPECTRUM->CHORD, and RING-MODULATE-CHORD. Generator MAKE-CHORD includes a mechanism to filter intervals.
CHORDS can be a generator, list of chords, or a stockpile.
EXAMPLE 1: (for-example
(cleanup-chord '((60 64 67 60) (60 64 64 66 67 67)))
:number-per-line 1 :number 2)
EXAMPLE 2: (for-example
(cleanup-chord (join->chord '(36 38) (make-chord (rv 40 60) 3))
:intervals '(0 1 4))
:number-per-line 1)
EXAMPLE 3: (for-example
(harmonic-chord c3 (from 1 12))
:number-per-line 1 :number 1)
EXAMPLE 4: (for-example
(cleanup-chord (harmonic-chord c3 (from 1 12))
:pitch-class t)
:number-per-line 1 :number 1 :recycle nil)
(clear-preference-file
Clears the current preference file and blocks the AC Toolbox from storing a new one when the application is closed. This allows the AC Toolbox to start with all of the default preferences for window positions, etc. (example 1).
Clearing the preference file only takes effect when the application is restarted. It only effects the next restart. Subsequent restarts will store the preference file and use it on restart.
EXAMPLE 1: (clear-preference-file)
(clip &optional low high)
Returns a closure that can be used as a transformer. If the value to be transformed is lower than LOW, LOW is used. If the value to be transformed is higher than HIGH, HIGH is used. Otherwise no change occurs (example 1).
LOW and HIGH may vary over time using generators, etc.
If LOW is specified without a value for HIGH, LOW is returned if the value is < LOW (example 2).
If LOW is nil and HIGH is specified, HIGH is returned if the value is > HIGH (example 3).
CLIP should not be confused with CLIP-GENERATOR which is NOT a transformer but functions as a generator.
EXAMPLE 1: (show-transformation (clip 0 10)
'(5 10 15 2 -1 0))
EXAMPLE 2: (show-transformation (clip 0)
'(5 10 15 2 -1 0))
EXAMPLE 3: (show-transformation (clip nil 10)
'(5 10 15 2 -1 0))
(clip-generator generator &optional low high)
Returns a closure. When applied, the value produced by GENERATOR is clipped to be in the range LOW-HIGH. If the value is < LOW, LOW is returned. If it is > HIGH, HIGH is returned (examples 1-2).
If LOW is NIL and HIGH is included, the value is allowed if it is < HIGH (example 3).
If HIGH is NIL (or omitted), the value is allowed if it is > LOW (example 4).
GENERATOR can be a generator, stockpile, list, etc.
LOW and HIGH can vary over time (example 5).
If LOW > HIGH, the values for LOW and HIGH are switched (example 6).
CLIP-GENERATOR can be abbreviated to CG (example 7).
CLIP-GENERATOR should not be confused with CLIP. CLIP is a transformer and only works with the transform method or with functions such as TRANSFORM/TIME.
EXAMPLE 1: (for-example (1/f-value 20 1 100))
EXAMPLE 2: (for-example
(clip-generator (1/f-value 20 1 100) 50 65))
EXAMPLE 3: (for-example
(clip-generator (line 20 1 50) nil 30))
EXAMPLE 4: (for-example
(clip-generator (line 20 1 50) 20))
EXAMPLE 5: (for-example
(clip-generator (line 20 1 20)
1 (line 20 20 10)))
EXAMPLE 6: (for-example
(clip-generator (line 20 1 20) 15 5))
EXAMPLE 6: (for-example (cg (line 20 1 50) 10 20))
(clock->mm 50)
Converts a clock unit in milliseconds to a metronome indication. This tool can be used to determine an appropriate tempo value when exporting a MIDI file (examples 1-3).
EXAMPLE 1: (print-result (clock->mm 100))
EXAMPLE 2: (print-result (clock->mm 50))
EXAMPLE 3: (print-result (clock->mm 10))
closure
A closure is a type of function. AC Toolbox generators return a closure which is later applied to get a value.
For most purposes, it is not necessary for a user to understand the difference between a closure and a 'regular' function.
code object
A code object contains Lisp code which must be evaluated before it can be used. A code object is included in the environment when the environment is saved. This allows the code to be saved together with objects which may use it.
Lisp code evaluated in the Lisp editor is not saved with the environment but can be saved as a separate text file.
(collect-things closure-or-symbol closure-or-symbol ...)
Returns a list of values. If an element is a closure, it is applied to produce a value. If the element is not a closure, it is returned as is (example 1).
This tool can also be used as part of a rule stockpile specification. See the help for REWRITE for additional examples.
EXAMPLE 1: (for-example (collect-things (random-value 1 10)
(random-choice '(a b c d))
(random-choice '(e f g h)) 5))
(combine object1 object2 &key function)
Returns a closure. When applied, one result from object1 is combined with one result from object2 according to FUNCTION. By default, FUNCTION is +. The objects may be constants, lists, stockpiles, or generators as is customary in the AC Toolbox (examples 1-2).
The keyword FUNCTION can be used to provide another way of combining the two objects. The function should be preceded with a function quote: #' (example 3).
To combine more than two objects, use the generator APPLY-FUNCTION. ON-THE-FLY allows the combination of several objects using infix notation.
EXAMPLE 1: (for-example (combine '(1 2 3 4 5 6 7 8 9 10)
(random-value 1.0 2))
:number 10)
EXAMPLE 2: (plot (combine (convert line-shape 100 1 100)
(random-value -5 5.0)))
EXAMPLE 3: (for-example (combine '(1 2 3 4 5 6 7 8 9 10)
'(1 2)
:function #'*))
(combine-all stockpile1 stockpile2 &key function)
Returns a list combining each value from STOCKPILE1 with each value from STOCKPILE2. The combination is done with FUNCTION. By default, function is #'+ (examples 1-3).
STOCKPILE1 and STOCKPILE2 may be lists or stockpiles.
Example 4 using another function for the combination.
EXAMPLE 1: (for-example (combine-all '(1 2 3 4) '(10 20 30)))
EXAMPLE 2: (for-example (combine-all '(f3 f#3 g3 a3) '(0 1 2 4)))
EXAMPLE 3: (for-example (stockpile->notename
(combine-all '(f3 f#3 g3 a3) '(0 1 2 4)))
:number-per-line 4)
EXAMPLE 4: (for-example (combine-all '(1 2 3 4) '(1 2 3)
:function #'*))
(combine-mutation source target index
&key first second
clumping start offset override
low high))
Returns a closure. When applied, one value of a combined mutation is returned.
COMBINE-MUTATION combines two morphological mutations in sequence. These mutation functions are discussed in the help for MUTATE. All parameters, except for FIRST and SECOND, have the same meaning as the parameters with same name in MUTATE.
FIRST designates which mutation function should be applied first. As in MUTATE, these functions have types 1,2,3 or LCM,IUIM, ISIM or CONTOUR, SOME-SOURCE, SOME-TARGET. The default for FIRST is type 1.
SECOND designates which mutation function should be used next. The default value is type 2.
The combination of a type 1 mutation, followed by a type 2 mutation, has the property that the target is reached when the index is 1 (examples 1-4).
Maarten van Walstijn contributed code for this generator.
EXAMPLE 1: (print-result (produce 8
(combine-mutation
'(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0)))
EXAMPLE 2: (print-result (produce 8
(combine-mutation
'(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
.3)))
EXAMPLE 3: (print-result (produce 8
(combine-mutation
'(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
.7)))
EXAMPLE 4: (print-result (produce 8
(combine-mutation
'(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1)))
community
A community is a group of sections, midi objects or other communities joined in name only. A community can provide a mechanism for manipulating objects as a group.
compatibility
Environments that were made in previous (non-Universal) versions of the AC Toolbox can be read with the current version. Environments saved on either a PPC or an Intel machine can be read on the other platform.
Environments saved in the New Format (as specified in the Preferences dialog) cannot be read in older, non-Universal versions. Environments saved in the Old Format will not remember size and position information and can be read in older versions.
(compose function ...)
Returns a lexical closure representing the composition of an unlimited number of functions (example 1). (See Paul Berg, Elements of Design for a discussion of function composition.)
Compose can be used to combine two or more transformers (example 2).
In example 2, the values are first transposed, then the double values are removed.
EXAMPLE 1: (print-result (funcall (compose #'first #'rest) '(1 2 3 4 5)))
EXAMPLE 2: (show-transformation
(compose (remove-doubles) (transpose 12))
'(60 (60 64 60 60)))
(compress factor middle-line)
Returns a closure. FACTOR is expressed as a percentage value, from 0 - 100. MIDDLE-LINE is a number. The value being transformed is compressed toward the middle line by FACTOR. If compressed 100%, the value becomes the value of the MIDDLE-LINE. If compressed 0%, the value does not change (examples 1-4).
FACTOR and MIDDLE-LINE may vary over time.
EXAMPLE 1: (show-transformation (compress 25 50)
'(0 20 40 50 60 75 80 100))
EXAMPLE 2: (show-transformation (compress 100 50)
'(0 20 40 50 60 75 80 100))
EXAMPLE 3: (show-transformation (compress 0 50)
'(0 20 40 50 60 75 80 100))
EXAMPLE 4: (show-transformation (compress 50 50)
'(0 20 40 50 60 75 80 100))
(constraint-and &rest functions)
CONSTRAINT-AND produces a function appropriate for use with WITH, WITHOUT, FILTER-STOCKPILE, and ACT-IF. It allows the results of several constraints (filters) to be examined. If all of the functions return a true value, then CONSTRAINT-AND will also be true.
Example 1 returns values if they are less than 70 and belong to pitch class 0 (C).
Example 2 does the opposite. It filters values < 70 which belong to pitch class 0.
Example 3 applies the constraint to the results produced by a generator.
CONSTRAINT-OR (example 4) and CONSTRAINT-NOT (example 5) are also available.
EXAMPLE 1: (for-example
(with (constraint-and (anything < 70) (pitch-class 0))
'(40 48 60 64 72 80)))
EXAMPLE 2: (for-example
(without (constraint-and (anything < 70) (pitch-class 0))
'(40 48 60 64 72 80)))
EXAMPLE 3: (for-example
(with (constraint-and (anything outside 60 70)
(pitch-class 0 1 4 6 7 11))
(random-value 40 80)))
EXAMPLE 4: (show-help 'constraint-or)
EXAMPLE 5: (show-help 'constraint-not)
(constraint-not function)
CONSTRAINT-NOT produces a function appropriate for use with WITH, WITHOUT, FILTER-STOCKPILE, and ACT-IF. It negates the value of the constraint to which it is applied. This is useful when constraints are combined with CONSTRAINT-AND or CONSTRAINT-OR.
Example 1 returns values that are < 70 and do not belong to pitch class 0 (C).
CONSTRAINT-AND (example 2) and CONSTRAINT-OR (example 3) are also available.
EXAMPLE 1: (for-example
(with (constraint-and
(anything < 70)
(constraint-not (pitch-class 0)))
'(40 44 45 48 60 64 72 80)))
EXAMPLE 2: (show-help 'constraint-and)
EXAMPLE 3: (show-help 'constraint-or)
(constraint-or &rest functions)
CONSTRAINT-OR produces a function appropriate for use with WITH, WITHOUT, FILTER-STOCKPILE, and ACT-IF. It allows the results of several constraints (filters) to be examined. If one or more of the functions return a true value, then CONSTRAINT-OR will also be true.
Example 1 returns values if they are less than 60 or belong to pitch class 0 (C).
Example 2 does the opposite. It filters values < 60 or belonging to pitch class 0.
Example 3 applies the constraint to the results produced by a generator.
CONSTRAINT-AND (example 4) and CONSTRAINT-NOT (example 5) are also available.
EXAMPLE 1: (for-example
(with (constraint-or (anything < 60) (pitch-class 0))
'(40 48 60 64 72 80)))
EXAMPLE 2: (for-example
(without (constraint-or (anything < 60) (pitch-class 0))
'(40 48 60 64 72 80)))
EXAMPLE 3: (for-example
(with (constraint-or (band-pass 60 70)
(anything member '(44 46 48 72 74)))
(random-value 40 80)))
EXAMPLE 4: (show-help 'constraint-and)
EXAMPLE 5: (show-help 'constraint-not)
controller
A controller is used to control parameter values on a larger scale. A controller exists outside the boundaries of a section or any other object. See the tutorial for a detailed example of the use of controllers.
controller features
In the 'Show Objects' dialog, when the popup menu for Controllers is chosen, buttons labeled history and reset are available.
History will be produce a window of the recent values produced by this controller. There is a maximum length to this history to prevent memory from being clogged if the controller is used a lot. Once this maximum length has been reached, history is erased and starts again.
Example 1 shows how long history is.
Example 2 changes the length of history.
Reset will remake the controller and erase its history. It will behave as if it was made for the first time.
EXAMPLE 1: (print-result *history-length-limit*)
EXAMPLE 2: (setf *history-length-limit*
(* *history-length-limit* 2))
(controller-filter parameter filter)
Since the filter template has no button for filtering MIDI controller values that may be in a midi-controller-object or a midi-section, a filter definition will have to be produced if you want to filter MIDI controller values.
Choose OTHER as the filter type then use CONTROLLER-FILTER to produce an appropriate filter definition.
PARAMETER can be:
VALUE
NUMBER
CHANNEL
VALUE is the controller value while NUMBER is the controller number such as 7 for volume. CHANNEL is the MIDI channel.
FILTER can be a Lisp expression reflecting the available filter types:
(low-pass threshold)
(high-pass threshold)
(band-pass low high)
(band-reject low high)
(bank low1 high1 low2 high2 ...)
(shot-gun percentage)
If Midi controller object CONT1 exists, it can be filtered with example 1.
Click on SET PARAMETERS to see the filter definition. A low-pass filter for midi-controller values will be produced.
EXAMPLE 1: (fill-template filter cont2 cont1
(other (controller-filter 'value (low-pass 60)))
'whatever nil)
(controller-transform parameter transformer)
This transformer builds another transformer that can be used with the WHATEVER parameter (and only with the WHATEVER parameter) to transform MIDI controller commands. MIDI controller commands are only found in midi-controller-objects or midi-sections.
CONTROLLER-TRANSFORM 'encapsulates' the other transformer and makes it suitable for use with MIDI controller commands.
The available values for PARAMETER are:
value
number
channel
VALUE would build a transformer to transform the controller values.
NUMBER would transform the controller number (such as 7 for volume).
CHANNEL transforms the MIDI channel assignment for the controller commands.
The parameter values should be quoted.
TRANSFORMER can be any available transformer such as TRANSPOSE.
If object midi1 exists, it can be transformed with example 1.
EXAMPLE 1: (fill-template transform midi2 midi1
:whatever (controller-transform 'value (transpose -12)))
(convert object n low high &optional generator interval-or-list pitch-class stop previous round)
Returns a list of values.
CONVERT is a mapping function which will map either a shape, a mask, a list, a stockpile, or a generator to be a list with N values within certain limits.
The optional parmeters, e.g. GENERATOR, are only used for mapping masks.
If LOW or HIGH is a real number, the list will contain real numbers. Otherwise, integers are returned.
IF THE OBJECT IS A SHAPE:
A shape will be mapped into a list with N values ranging from LOW to HIGH (example 1).
IF THE OBJECT IS A LIST OR STOCKPILE:
The list (or stockpile values) will be expanded or contracted to produce N values between LOW and HIGH (example 2). If the list or stockpile contains lists (e.g. chords), the length of the list can be shortened but not expanded.
IF THE OBJECT IS A GENERATOR (FUNCTION):
The closure will be applied N times and the results will be scaled to be between LOW and HIGH and returned as a list (example 3) This also works with generators that produce chords (example 4).
QUANTIZING VALUES
The keyword ROUND can be used to round values to the specified unit. All of the optional parameters before ROUND will need to receive a value, e.g. nil (example 5).
To quantize the output, it may be more convenient to use CONVERT2 which is similar except the optional parameters are expressed as keywords. This means that you only need to bind a value to ROUND if that is what you want to use (example 6).
IF THE OBJECT IS A MASK:
Returns a list of values between LOW and HIGH. The type of LOW and HIGH determine the type of the result.
The mask is divided into N segments. Each time a new value is needed, the appropriate boundaries are determined. A generator is applied to determine a value between the boundaries.
By default, the generator used for determining a value between the boundaries is RANDOM-VALUE. Other generators could be used. They should produce a percentage value between 0 and 100.
Define a mask named MASK1. This can be done either by drawing, specifying, or generating a mask using the corresponding menu item or by evaluating example 7. Example 8 plots MASK1.
Examples 9-10 produce 50 values between 40 and 80 using mask1.
Examples 11-12 use a different generator to produce the values with a mask.
GENERATOR could also be a list of values. CONVERT will loop through the values. The values should be percentages (example 13).
Note that the generator should produce values between 0 and 100 (percent). In the case of the beta-value generator, values will tend to concentrate near the lower and upper mask limits.
The other options for converting a mask relate to the possibility of blocking certain intervals from following each other. INTERVAL-OR-LIST can a single value or a list of values to be blocked (i.e. the next value chosen should not form that interval with the previous value).
To prevent the repetition of the same value, block 0 (example 14).
Note that a value for the optional parameter GENERATOR needs to be entered if any of the other optional parameters are to be used. T will signify that the default generator, (random-value 0.0 100) should be used. Instead of T, another generator could be specified.
To prevent the repetition of the same value or one which is one step higher or lower, use the list (0 1). (example 15).
If the values produced are to be considered pitches and both unisons and octaves should be blocked, the values should be reduced to their pitch-class before being compared. Binding the optional parameter PITCH-CLASS to T will do this (example 16).
The user is responsible for CONVERT being able to produce a non-blocked interval. If CONVERT has not been able to do that after STOP number of attempts, the execution will abort and an error message will appear. The default value for STOP is 100 attempts. The value for this parameter could be increased. Sometimes the shape of a mask may be so narrow at a particular point that an unblocked interval is seldom possible. In that case, the user can either try again until an entire list is produced, or not block any intervals, or change the mask.
Sometimes the reason that CONVERT cannot produce an appropriate value is that after the first value is chosen, no allowed intervals are possible. A dummy value for the first previous value can be bound to the optional parameter PREVIOUS.
The help for the generator BLOCK-INTERVAL can be consulted for more examples of the use of these parameters when blocking intervals.
SOME OTHER POSSIBILITIES TO CONVERT OBJECTS
CONVERT2 is similar to CONVERT except it works with keywords instead of optional parameters (example 6).
ANCHOR is a tool for mapping a shape. With it, the first and last value can be specified.
SPRAY is a generator for converting a shape, etc. An object is converted and a random deviation is added.
CONVERT/TIME is a generator for converting a shape, mask, etc. It works similarly to CONVERT but it does not return a list. Instead, one value is returned each time the generator is applied. This uses less memory than CONVERT.
2-MASKS creates values using two masks. One mask is used to generate values while another mask is used to block values from a portion of the mask.
EXAMPLE 1: (for-example (convert sine-shape 100 40 80))
EXAMPLE 2: (for-example (convert '(0 100 50) 50 10 20))
EXAMPLE 3: (for-example (convert (random-value 1 5) 50 40 60))
EXAMPLE 4: (for-example
(convert (fm-chord (chromatic c4) c3 5) 10 50 70)
:number-per-line 1)
EXAMPLE 5: (for-example (convert sine-shape 100 40 80.0 nil nil nil nil nil 0.5))
EXAMPLE 6: (for-example (convert2 sine-shape 100 40 80.0 :round 0.5))
EXAMPLE 7: (fill-template specify-mask mask1 '(20 100) '(1 80))
EXAMPLE 8: (plot mask1)
EXAMPLE 9: (for-example (convert mask1 50 40 80))
EXAMPLE 10: (plot (convert mask1 50 40 80))
EXAMPLE 11: (for-example
(convert mask1 50 40 80
(beta-value 0.0 100.0 .2 .2)))
EXAMPLE 12: (plot
(convert mask1 50 40 80
(beta-value 0.0 100.0 .2 .2)))
EXAMPLE 13:(plot
(convert mask1 50 40 80
'(0 20 40 60 80 100)))
EXAMPLE 14: (for-example (convert mask1 50 40 80 t 0))
EXAMPLE 15: (for-example (convert mask1 50 40 80 t '(0 1)))
EXAMPLE 16: (for-example (convert mask1 50 40 80 t 0 t))
(convert-stockpile stockpile low high &key chord round)
Returns a list made by mapping STOCKPILE to the range LOW to HIGH. STOCKPILE may be a list or stockpile (example 1).
If either LOW or HIGH is a real number, the output is a real number (example 2).
This tool differs from CONVERT in that there is no number parameter. In CONVERT the number of values in the resulting list can vary. In CONVERT-STOCKPILE, the output list always has the same number of elements as the input stockpile.
If the stockpile contains lists, e.g. chords, each value in the chord is converted (example 3).
If the stockpile contains lists representing the result of a multi-dimensional function, such as lists with the XY values of a chaotic function, it is possible to convert the X and Y values separately. In this case, a list with the low values for each parameter should be used as well as a list with high values for each parameter. The keyword CHORD should be bound to nil to do this. Note that all elements of stockpile should have the same length.
In examples 4-5, X values are mapped to the range 60-80. Y values are mapped between 20-30.
Output can be quantized by binding keyword ROUND to a unit (example 6).
EXAMPLE 1: (for-example (convert-stockpile '(1 2 3 4 5) 10 100))
EXAMPLE 2: (for-example (convert-stockpile '(1 2 3 4 5) 10.0 100))
EXAMPLE 3: (for-example
(convert-stockpile '((60 62) (60 64 67) (69 72 76))
30 40))
EXAMPLE 4: (fill-template generate-stockpile stockpile1 20
(henon 0.0 0.0 1.4 .3 1 :xy 1))
EXAMPLE 5: (for-example (convert-stockpile stockpile1
'(60 20) '(80 30) :chord nil))
EXAMPLE 6: (for-example
(convert-stockpile (produce 10 (rv 1.0 10))
1 20.0 :round 0.5))
(convert-to-lookup-table object low-key high-key low-value high-value &key round)
Intended to make a lookup table to use with generator LOOKUP.
A lookup table contains pairs of keys and values. LOOKUP looks up a key in the table and the value is returned.
CONVERT-TO-LOOKUP-TABLE makes a lookup table by converting an object such as a shape into the values for the table. The object is mapped to be between LOW-VALUE and HIGH-VALUE.
The table contains entries for keys ranging from LOW-KEY to HIGH-KEY. Each of these keys is associated with a value mapped from the OBJECT.
E.g. (convert-to-lookup-table line-shape 1 10 40 80)
would produce a lookup table with the following pairs of keys and values:
KEY VALUE
1 40
2 44
3 49
4 53
5 58
6 62
7 67
8 71
9 76
10 80
To use the lookup table, you could construct a stockpile, and then use the table with the generator LOOKUP (examples 1-2).
In addition to converting shapes, anything else that can be converted with the tool CONVERT, such as masks, functions, and lists, can also be used as the object in CONVERT-TO-LOOKUP-TABLE (examples 3-4).
If both LOW-VALUE and HIGH-VALUE are integers, the table will contain integer values. Otherwise it will contain real numbers (example 5).
Values (not keys) in the lookup table can be quantized by binding a unit to ROUND. In example 6, values in the table are rounded to units of 0.5.
For help on the way that CONVERT deals with masks or lists, see CONVERT. For a different method of constructing a lookup table, see MAKE-LOOKUP-TABLE.
EXAMPLE 1: (fill-template construct-stockpile table
(convert-to-lookup-table sine-shape
1 10 40 80))
EXAMPLE 2: (for-example (lookup '(1 2 3 4 5 6 7 8 9 10) table)
:number 10)
EXAMPLE 3: (fill-template construct-stockpile table2
(convert-to-lookup-table
(henon 0.0 0.0 1.4 .3 1)
1 10 40 80))
EXAMPLE 4: (for-example (lookup '(1 2 3 4 5 6 7 8 9 10)
table2)
:number 10)
EXAMPLE 5: (for-example (lookup (from 1 20)
(convert-to-lookup-table
sine-shape 1 20 40 50.0)))
EXAMPLE 6: (for-example (lookup (from 1 20)
(convert-to-lookup-table
sine-shape 1 20 40 50.0 :round 0.5)))
(convert/time object n low high
&optional generator interval-or-list pitch-class stop previous round)
Returns a closure. When applied, one value is returned which has been mapped from an object, such as a shape, mask, list or stockpile. It does not map generators.
This generator is similar to the tool CONVERT which will map an object into a list with N values within certain limits.
CONVERT/TIME does NOT return a list. Instead, each time the closure is applied, the next value is returned. For this reason, it makes more efficient use of memory than CONVERT. This can be important if an object is to be converted into a large number of values (e.g. tens of thousands of values which might happen when generating granular score data for Csound or when controlling an external device using streams.) The increase in efficiency primarily occurs with masks.
If LOW or HIGH is a real number, the result will be a real number. Otherwise, integers are returned.
LOW and HIGH can vary over time. For shapes, this has no effect on the amount of memory used. For masks, changing these parameters over time severely limits efficiency though it is still more effecient than using CONVERT.
IF THE OBJECT IS A SHAPE:
A shape will be mapped so that N applications of this generator will return N values ranging from LOW to HIGH (example 1).
IF THE OBJECT IS A LIST OR STOCKPILE:
The list (or stockpile values) will be expanded or contracted so that N applications of this generator will produce N values between LOW and HIGH (example 2).
QUANTIZING
Keyword ROUND can be bound to a quantization unit. The results wil be rounded using that unit (example 3). Values must be entered for all of the optional values before ROUND. Nil can be used to do this.
A more convenient way to round values is with CONVERT/TIME2. This uses keywords instead of optional parameters (example 4).
IF THE OBJECT IS A MASK:
N applications of the generator produce N values between LOW and HIGH. The type of LOW and HIGH determine the type of the result.
The mask is divided into N segments. Each time a new value is needed, the appropriate boundaries are determined. A generator is applied to determine a value between the boundaries.
The mask in examples 5-6 can be used to produce values between 40 and 80 (example 7).
By default, the generator used for determining a value between the boundaries is RANDOM-VALUE. Other generators could be used. They should produce a percentage value between 0 and 100 (example 8).
GENERATOR could also be a list of values between 0 and 100 percent. In that case, CONVERT will loop through the values (example 9).
The remaining parameters for CONVERT/TIME (INTERVAL-OR-LIST, PITCH-CLASS STOP, and PREVIOUS) only work with masks. The usage is identical with their use in CONVERT. See the help for CONVERT for an extended description of these parameters.
CONVERT/TIME is primarily useful when dealing with masks. The gain in speed and memory efficiency is dramatic compared to CONVERT. This gain is achieved when LOW and HIGH do not change over time. If either or both of these parameters change over time, the efficiency gains are much less.
With shapes, speed decreases though there is some gain in reduced memory allocation. For shapes, the primary benefit is that LOW and HIGH can vary over time.
EXAMPLE 1: (for-example (convert/time line-shape 20 40 80))
EXAMPLE 2: (for-example (convert/time '(0 100 50) 20 10 20))
EXAMPLE 3: (for-example (convert/time sine-shape 20 40 80.0 nil nil nil nil nil 0.5))
EXAMPLE 4: (for-example (convert/time2 sine-shape 20 40 80.0 :round 0.5))
EXAMPLE 5: (fill-template specify-mask mask1 '(20 100) '(1 80))
EXAMPLE 6: (plot mask1)
EXAMPLE 7: (plot (convert/time mask1 100 40 80))
EXAMPLE 8: (plot
(convert/time mask1 100 40 80
(beta-value 0.0 100 .2 .2)))
EXAMPLE 9: (plot
(convert/time mask1 100 40 80
'(0 20 40 60 80 100)))
(convert/time2 shape n low high &key generator block pc stop previous round)
Returns a closure. When applied, one value is returned which has been mapped from an object, such as a shape, mask, list, or stockpile. It does not map generators (examples 1-4).
If a large number of values are converted, it may be more efficient that CONVERT2. Large in this case means thousands.
This generator is essentially the same as CONVERT/TIME. The difference is that keywords are used instead of optional parameters. This makes using ROUND much easier example 5. The equivalent expression for CONVERT/TIME is example 6.
BLOCK can be used to block the use of certain intervals. It may be a number or a list of numbers. This only is available when converting masks. Example 7 blocks repetitions. Example 8 blocks repetitions and intervals of 1.
If PC (for pitch class) is bound to t, the blocking mechanism will first reduce the values to their pitch class before testing their acceptability (example 8).
For a discussion of the meaning of the other keywords, see the help for CONVERT (example 9).
EXAMPLE 1: (for-example (convert/time2 line-shape 20 40 80))
EXAMPLE 2: (for-example (convert/time2 '(0 100 50) 20 10 20))
EXAMPLE 3: (fill-template specify-mask mask1 '(20 100) '(1 80))
EXAMPLE 4: (plot (convert/time2 mask1 100 40 80))
EXAMPLE 5: (for-example (convert/time2 sine-shape 20 40.0 80 :round 0.5))
EXAMPLE 6: (for-example (convert/time sine-shape 20 40.0 80 nil nil nil nil nil 0.5))
EXAMPLE 7: (for-example (convert/time2 mask1 20 40 50 :block 0))
EXAMPLE 8: (for-example (convert/time2 mask1 20 40 80 :block '(0 1) :pc t))
EXAMPLE 9: (show-help 'convert)
(convert2 object n low high &key generator block pc stop previous round)
Returns a list of values: OBJECT is converted to N values between LOW and HIGH. Shapes, masks, functions, lists, and stockpiles can be converted.
CONVERT2 is essentially the same function as CONVERT. The optional parameters are replaced with keywords. This is relevant when converting masks. With optional parameters, you need to enter arguments in order. With key words, that is not necessary. This makes it easier to use some arguments (e.g. block) without having to enter a placeholder for the preceding argument (generator).
If LOW or HIGH are integers, the result will be integers. Otherwise the result will be real numbers (depending on the value of the keyword ROUND).
Example 1 converts a shape to a list of N integers between LOW and HIGH.
Example 2 converts a shape to a list of N real numbers.
Example 3 converts a shape to a list of N real numbers rounded to units of 0.5. If this list were used as pitch values, these units would be quarter tones.
Example 4 converts a list to be N values between LOW and HIGH. It will, if necessary, adjust both the number of values and their range. If a list or stockpile contains lists (chords), N can be smaller than the number of elements in the list but not larger. In that case, only the elements in the original list are converted.
Example 5 converts a function. It is applied N times and mapped to be in the range LOW and HIGH. This is convenient for functions, such as chaotic functions, where the limits are not yet known. Functions that produce chords, e.g. FM-CHORD, can also be converted (example 6).
Example 7 defines a mask. The remaining examples deal with masks.
Example 8 maps a mask. The mask is divided into N segments. A value is chosen randomly between the value of LOW and HIGH for each of the segments.
Example 9 uses a different generator to pick values in a mask. The generator should produce values in the range 0 to 100 percent.
Example 10 blocks a value from being repeated. The interval 0 is blocked. If the range is too narrow to find a non-repeating value, an error message occurs.
Example 11 blocks the intervals 0 and 1.
Example 12 binds PC to t. If the list is considered pitches and both unisons and octaves are to be blocked, this will reduce values to their pitch class before being compared.
BLOCK can contain real numbers. If both ROUND and BLOCK are used, values are quantized with ROUND before they are tested if they should be blocked (example 13).
STOP can be used to change the number of attempts CONVERT2 makes to find an allowed value before it stops.
PREVIOUS could be an imaginary previous value for calculating intervals.
A further discussion of the basic functionality can be found in the help for CONVERT. Some other conversion possibilities are mentiond there (example 14).
EXAMPLE 1: (for-example (convert2 sine-shape 20 40 80))
EXAMPLE 2: (for-example (convert2 sine-shape 20 40.0 80))
EXAMPLE 3: (for-example
(convert2 sine-shape 20 40.0 80 :round .5))
EXAMPLE 4: (for-example (convert2 '(5 1 10 12) 20 40 80))
EXAMPLE 5: (for-example
(convert2 (henon 0.0 0.0 1.4 .3 1) 20 40 80))
EXAMPLE 6: (for-example
(convert2 (fm-chord (chromatic c4) c3 5) 10 50 70)
:number-per-line 1)
EXAMPLE 7: (fill-template specify-mask mask1 '(20 100) '(1 50))
EXAMPLE 8: (plot (convert2 mask1 100 40 80))
EXAMPLE 9: (plot
(convert2 mask1 100 40 80
:generator (beta-value 0.0 100 .2 .2)))
EXAMPLE 10: (for-example
(convert2 mask1 100 50 60 :block 0))
EXAMPLE 11: (for-example
(convert2 mask1 100 40 60 :block '(0 1)))
EXAMPLE 12: (for-example
(convert2 mask1 100 40 60 :block '(0 1) :pc t))
EXAMPLE 13: (for-example
(convert2 mask1 100 40 60.0 :block '(0 0.5 1) :round 0.5))
EXAMPLE 14: (show-help 'convert)
(create type number generator)
Creates an object of the desired type (if a method has been defined for that type) containing the results of NUMBER of applications of the GENERATOR.
Methods for lists (example 1) and vectors (example 2) exist in any case.
EXAMPLE 1: (print-result (create 'list 10 (random-value 1 10)))
EXAMPLE 2: (print-result (create 'vector 10 (random-value 1 10)))
(create-sequence n generator)
Creates an object of the type SOME-SEQUENCE that is suitable for use as input to a STRUCTURED SECTION, a NOTE SECTION, or a NOTE STRUCTURE. The sequence contains N objects that were created or chosen by applications of GENERATOR. This is equivalent to doing
(in-sequence object1 object2 ... objectN)
Assuming section S1 exists, a section containing a sequence with 5 random choices from section S1 can be made (example 1).
EXAMPLE 1: (define s3
(make-structured-section
100
(create-sequence 5 (random-choice s1))))
(create-text-file header-string
foot-string
number
&rest to-generate-parameters)
Produces a text file as output. This tool is useful to use the facilities provided in the AC Toolbox (such as generators) to produce a text file which might be used as input for another program, e.g. a Max coll object.
The HEADER-STRING is printed at the beginning of the file. Then a NUMBER of lines in the text file contain the results of using all of the parameters which are gathered into TO-GENERATE-PARAMETERS. These parameters can be symbols, numbers, lists, stockpiles, or generators. The values will be produced in the customary AC Toolbox manner, i.e. with the generator DO-THE-NEXT-THING.
NUMBER is the number of lines in the file. Each line contains the result of using all of the parameters which are gathered in TO-GENERATE- PARAMETERS.
The FOOT-STRING is printed at the end of the file (example 1).
Commas can be written to a file by specifying character #\,. Semicolons are #\;.
To write a text file in a format usable in a Max Coll object see example 2.
CREATE-TEXT-WINDOW can be used to write to a window instead of a file.
EXAMPLE 1: (create-text-file "Data for some program"
"; end of data"
20 (from 1 20) (random-value 1 100) (random-value 50.0 70))
EXAMPLE 2: (create-text-file "" "" 20 (from 1 20)
#\, (random-value 1 100) (random-value 50 70)#\;)
(create-text-window header-string
foot-string
number
&rest to-generate-parameters)
Prints the values produced by several generators, etc. to a window. Each line will contain results from all of the specified generators. This tool may be a convenient way to produce sets of data for perusal.
The HEADER-STRING is printed at the beginning of the window.
NUMBER is the number of lines to be printed to the window.
Each line contains the result of using all of the parameters which are gathered in TO-GENERATE- PARAMETERS. These parameters can be symbols, numbers, lists, stockpiles, or generators. The values will be produced in the customary AC Toolbox manner.
The FOOT-STRING is printed at the end of the window.
This tool is similar to CREATE-TEXT-FILE except that the information is printed to a window instead of a file (example 1).
EXAMPLE 1: (create-text-window "Some Data"
"" 10 (random-choice '(a b c d))
(random-value 1 100) '(500 1000)
20 (random-value 1 5))
csound
A widely-available software synthesis program originally designed by Barry Vercoe. More information can be found at the url in example 1.
The AC Toolbox works with Csound5 or higher. See the installation instructions for details.
EXAMPLE 1: (open-url "http://www.csounds.com")
csound files: filtering
Csound csd files can be filtered using the dialog produced by Methods>Filter>Csound File. The result of the filtering operation is a new file. The original file is not changed.
Select a Csound file by clicking on the 'Select' button.
It is possible to filter up to four parameters in the file using this dialog. If a parameter is to be filtered, select the parameter number. Select a filter type for that parameter using the corresponding popup menu. Parameters, such as a threshold value for a low-pass filter must be specified. To do this, click the button 'Set Parameters' and fill in the appropriate value(s).
If the filter type is 'None', the corresponding parameter will not be filtered.
When a file is filtered, only note statements are examined. Function statements, etc. are ignored. When filtering a file, if a line of note information is allowed to pass, it is copied to a new file. If the line is filtered away, it is not copied.
If more than one filter have been specified, a choice must be made on how to combine the results of the filters to determine if a line should be copied or not. If 'Or' is selected, a line is copied if one ore more of the filters would allow it to be copied. If 'And' is selected, it is copied only if all of the filters would allow it to be copied.
For example, imagine two filters have been specified for P5: a low-pass filter with a threshold of 200 and a high-pass filter with a threshold of 1000. Combining the filters with 'Or' would result in a file containing only those lines with P5 values <= 200 or with P5 values >= 1000. If those filters were combined with 'And', the resulting file would have no note statements, since it is not possible for P5 to be both <= 200 and >= 1000.
Combining filters with 'And' can be useful when filtering different parameters, e.g. when selecting only those lines where P3 is below a certain value and P5 is above another value.
An example of writing a Lisp expression to use for a filter of type 'Other' is given in Help>Lisp>Your Own.
The filtered file is rendered or not according to the various choices made in the Csound File Options dialog. Note that the orchestra is not replaced when a file is filtered. The rendering options are changed to what is current in the Csound File Options dialog.
csound files: transforming
Csound csd files can be transformed using the dialog produced by Methods>Transform>Csound File. The result of the transformation is a new file. The original file is not changed.
Select a Csound file by clicking on the 'Select' button.
It is possible to transform up to four parameters in the file using this dialog. If a parameter is to be transformed, set the parameter number. In the corresponding dialog box, fill in a transformer expression such as (transpose 500) which would add 500 to the value of the corresponding P parameter. Available transformers can be found in the Annotated Index (Help>Annotated Index).
A transformer is applied to the specified parameter of every note statement in the Csound score file. Function statements, etc. are not changed.
The transformed file is rendered or not according to the various choices made in the Csound File Options dialog. Note that the orchestra is not replaced when a file is transformed. The rendering options are changed to what is current in the Csound File Options dialog.
The transformation can be limited to be only between specified start times. This is done with the tool AT-CSOUND-TIME.
csound object
A Csound object contains the specification to generate a Csound score file.
(csound-frame-size frequency &optional sr)
Calculates the minimum frame size to capture a specified frequency in a phase vocoder analysis (pvanal) for Csound.
The result of evaluating this tool in the For Example dialog, a Listener, or an edit window can be used to select the frame size for pvanal in the Csound Analysis dialog.
FREQUENCY is the desired frequency. SR is the sample rate that defaults to 44100 (examples 1-2).
EXAMPLE : (print-result (csound-frame-size 50))
EXAMPLE : (print-result (csound-frame-size 50 96000))
(csound-table-size seconds &optional sr)
Returns the table size in samples which is appropriate for use with the Csound gen1 statement. This tool can be evaluated in the For Example dialog, a Listener, or an edit window. It should not be directly used in the definition of a Csound score. The outcome of using this function should be entered.
SECONDS is the desired duration of the table. SR is the sample rate that defaults to 44100.
Csound expects the table size for gen 1 to be a power of 2 or a power of 2 plus one. This tool returns a power of 2.
Example 1 calculates the number of samples needed for 10 seconds.
Example 2 calculates for 10 seconds with a sample rate of 96000.
The resulting value could be used in a header such as this:
f1 0 524288 -1 42 0 0 1
EXAMPLE 1: (print-result (csound-table-size 10))
EXAMPLE 2: (print-result (csound-table-size 10 96000))
csound: parallel objects
Csound score objects can be combined in parallel in 2 ways. The groups of objects can be specified by name or the group can be generated using a generator etc. to determine the order of the available scores. In both cases, each time another score object is applied, it is generated anew.
To specify a group of score objects to be joined in parallel, use the 'Parallel Scores' menu item. In the space for score objects, the names of score objects can be entered.
Scores used in a parallel score should have been specified or applied before using them in a definition.
For the examples in this help, the instruments defined in test csound.orc will be used (examples 1-3)
As many objects as desired can be entered. The objects can be Csound score objects, sequential score objects, or parallel score objects.
The start of an object can be delayed by a time specified as a number (in seconds). If no offset is desired, no number need be entered. The time offset is not the time between objects (as is the case with a sequential score) but the time since the beginning of the parallel score object (example 4).
In example 4, score1 and score2 will start at the same time. The second instance of score1 will start 3 seconds later. Note that the two applications of score1 may result in different score files (depending on the way that score1 was specified). If score1 contains generators with random aspects, the files will probably be different.
To generate a group of score objects to occur in parallel, use the menu item 'Generate Parallel Scores'.The number of scores to be generated, something to produce an offset value (from the beginning of the parallel object), and a generator etc. to choose the group of scores should be entered (example 5).
The offset value can be a constant, list, generator, etc. If the offset is 0, all scores will start at the same time. In any case, the first score always starts at time 0. The offset is applied to the start time of the remaining scores.
If the total amplitude of the result of a parallel section is too large, the amplitude values in the score text can be transformed with the transform method for Csound files. If the transformer (stretch .7) is applied to P4 (if that is the amplitude parameter), the P4 parameter of the selected score file will be rescaled. See the help for 'Csound Files: Transforming' for more information on transforming Csound files.
The scores can be chosen with a generator as in example 5. A list could be given in which case the scores occur in the same order as they occur in the list (example 6).
The name of a single score could be used (example 7).
Note that F statements in the score object headers are not changed by a parallel combination. It is the responsibility of the user to ensure that function definitions are appropriate.
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 100 1
(random-value 0.0 10)
(rv .05 .1)
(rv 0.1 0.2)
(rv 1000.0 1500))
EXAMPLE 2: (fill-template csound-score-object score2
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 3 100 1 0
(random-value 0.05 0.1)
(scale-by-layers 0.5)
(walk 440.0 (random-value -20.0 20) 100 1000))
EXAMPLE 3: (fill-template parallel-score-object parallel-score1
score1 score2)
EXAMPLE 4: (fill-template parallel-score-object parallel-score2
score1 score2 3 score1)
EXAMPLE 5: (fill-template generate-parallel-score-object
generate-parallel-score1 5
(random-value 0.0 2)
(random-choice '(score1 score2)))
EXAMPLE 6: (fill-template generate-parallel-score-object
generate-parallel-score2 5
(random-value 0.0 2)
'(score1 score2))
EXAMPLE 7: (fill-template generate-parallel-score-object
generate-parallel-score3 5
(random-value 0.0 5)
score1)
csound: score objects
A Csound score object can be used to specify an algorithm to generate a Csound score file. When an object is specified, the algorithm is saved but no file is generated. When an object is applied, the specification is saved and a file for Csound is generated.
When a Csound score object is written to a file, the result wil be in the unified file format (extension .csd) which contains both orchestra and score data as well as some options.
Csound score objects can be joined in sequence or in parallel which means that when applied, several scores will be generated as part of one score.
Sequential Csound objects are described in the help for Csound: Sequential Objects.
Parallel Csound objects are described in the help for Csound: Parallel Objects.
The remainder of this document describes the use of the dialog box for a Csound score object.
HEADER
The header is printed at the beginning of the file. Typically this would contain function statements, etc.
LAYERS
In the score file, one or more layers can be produced. Layers are parallel combinations of outputs. The parameter LAYERS may be a constant, list, generator, etc.
NUMBER
Number is the number of events in a layer. It may be a constant, list, generator, etc.
INSTRUMENT, START, DURATION
Instruments should be referred to by a number, such as 1. Each line will use the next value from instrument.
If start is a constant number, the first start-time in the score will be this value. Subsequent values for the start-time of events will be the previous value plus the previous duration. If start is a generator, list, etc., the values for all of the actual start-times will be produced with it.
Duration is the length of an event. Negative values will cause a rest. The remaining parameter values for that line of the score file will be lost. By default, one beat is one second.
The instrument, start, and duration parameters may be a constant, list, generator, etc. Each score object must have values for these three parameters.
EXAMPLE
The examples in this help text will use the instrument definitions of 'test csound.orc' found in 'Support/FileExamples'. In the Csound File Options dialog, select this file as the orchestra. Also select a sound directory (for writing the output files) and a sample directory (to read sample files if requested).
In example 1, a score object was made with only three parameters specified: instrument, start-time, and duration, (p1 - p3). When the specify button is used, the information in this dialog is saved as an object. When the apply button is used, the information is saved and a Csound score file with ten score lines is produced. There is 1 layer.
Each line of the score file may contain additional parameters. For each desired parameter, include a constant, list, generator, etc. to produce the next value.
If score1 is rendered, no sound is produced since no frequency, duration, or waveform information was provided.
HEADER
In example 2, the header specifies function generation methods. Function 1 will be one period of a sine wave and is used by instrument 1 as the waveform for an oscillator. Function 2 produces a Hanning window which is used as the envelope in instrument 1. Ten score lines will be produced. The score starts at time 0. Each duration is 1.
In instrument 1 (in test csound.orc), P4 is the parameter for amplitude, P5 for frequency. In score2, each p4 is 0.8. Amplitude values for instrument 1 can vary between 0 and 1. P5 contains random values between 220 and 880.
RESTS
Negative durations produce rests. The values produced for the other parameters are lost (if there is a rest). This produces 'gaps' in the score file as if holes had been shot in it. The file will only contain the score lines which are not rests (example 3).
UNTIL-TIME
UNTIL-TIME can be used to determine the number of values to be calculated. UNTIL-TIME indicates that events should be generated until a certain length of time in seconds has been reached. It can only be used if START is a constant value.
When the score file in example 4 is made, events will be generated until 10 seconds have been filled. The last event is not truncated to fit within the 10 seconds but is allowed its full duration. This could mean that the total length of the score is longer than 10 seconds.
The use of UNTIL-TIME assumes that duration is expressed in seconds and that no additional Csound tempo indications will be used.
In example 4, FROM-NUMBER was used to convert expo-shape for P4. (from-number) returns the number of events calculated to fill 10 seconds.
USING A GENERATOR FOR START
Example 5 uses a generator for start.
The start-times of the events are randomly chosen between 0.0 and 10 beats. Note that the events are no longer generated in chronological order. If the other parameters are in random order, this does not really matter. See the section below on shapes and masks for an example of how to generate start-times when the order matters.
USING A SHAPE TO DETERMINE THE DENSITY
DENSITY-OF-START-TIMES makes a list of start times by mapping a shape to represent varying density between a minimum and maximum density.
In example 6, LINE-SHAPE represents a linearly increasing density that is mapped between 1 event per second to 30 events per second in the course of 10 seconds.
The NUMBER parameter is related to the number of events generated by the DENSITY-OF-START-TIMES expression by using (from-start-times) as input.
SEVERAL LAYERS
For each layer, generators are made again. This means that they forget their history and start at the beginning (though not necessarily with the same results). In this example, P5 (frequency) uses the WALK generator. The walk for each layer will start at 440. The amplitude parameter P4 uses SCALE-BY-LAYERS. This scales the value produced by the number of layers specified (example 7).
SHAPES OR MASKS
If one of the parameters is to be derived from a shape or a mask, it is important that the start-times be in ascending order. If a constant value is used for start-time, then there is no problem. If a generator is used for start-time, it is possible that the order of the shape or mask is destroyed after Csound sorts the start-times. To prevent this, you should sort the start-times using the tool MAKE&SORT.
Ten values made by the generator RANDOM-VALUE are sorted and returned in a list in examples 8-9.
EXTRA
The dialog for extra may contain generators, etc. for additional parameters, starting with p11. Data for an unlimited number of parameters can be included in this dialog (example 10).
Note that this score object cannot be rendered with the example orchestras since none of them uses 11 parameters.
PER LAYER
This box can be used to indicate which (if any) objects that have already been defined should be remade before each layer is calculated. When an object is remade, the input specification is used to make a new output which replaces the previous output of that object.
For example, the mask (examples 11-12) could be converted to produce frequency values (P5) in example 13.
In example 13, all layers used the same mask.
If the mask is remade for each layer, the values for P5 will be defined per layer (example 14).
This example produces 3 layers. MASK1 is remade for each layer so that P5 has different values in each layer.
Several objects can be remade per layer. Even if only 1 layer is specified, the objects are remade before the first layer is calculated.
PER SCORE
This box can be used to indicate which (if any) objects that have already been defined should be remade before each score object is calculated. When an object is remade, the input specification is used to make a new output which replaces the previous output of that object.
When an object is remade per score, this would allow all layers to use the same object but each time the score is applied, a new object would be made for use in all layers (example 15).
Remaking objects per score is useful if sequential or parallel scores are made. If, for example, a sequential score is generated, the input specification of an existing score is used to generated several scores which are joined in sequence. Each time a new object would be generated per score. All layers within one score would share the same mask. Each new score in the sequence would use a new mask (example 16).
SOUNDFILE NAMES
Csound unit generators such as soundin require either the number of a soundfile (e.g. 20 for file soundin.20) or a name enclosed in double quotes (a string). A string in the AC Toolbox Csound score dialog will be inaccurately represented in the score except if the tool SF-NAME or the generator GENERATE-SF-NAME is used.
This example uses instrument 3 in test csound.orc. It reads a fragment from a sample file and multiplies it with an amplitude envelope. The sample file should be in available in the sample file directory which is chosen in the Csound File Options dialog (example 17).
If a choice is to be made between several names, GENERATE-SF-NAME could be used. Note that the sample files should be available in the sample file directory (example 18).
See the help for GENERATE-SF-NAME for an example of relating soundfile names to different durations.
OVERLAPPING START TIMES
The generator OVERLAP can be used to guarantee that start times for adjacent events will overlap. The amount of overlap can be a time value in seconds (example 19).
The amount can also be expressed as a percentage of the previous duration (example 20).
Note the use of FROM-OVERLAP for the duration parameter when the generator OVERLAP is used.
MISCELLANEOUS
Files created from a Csound score object can be plotted using the dialog produced by the menu item 'Tools>Plot >Csound File'.
A histogram of a Csound score object can be made using the dialog produced by the menu item 'Tools>Histogram>Csound File'.
Files created from a Csound score object can be filtered or transformed using items in the Methods menu. These processes are described in the help item for 'Csound Files: Filtering' and 'Csound Files: Transforming'
The tools FROM-NUMBER,FROM-LAYERS, SCALE-BY-LAYERS may be useful when specifying Csound score objects. See their respective help texts for a description.
The generator PAR allows a Csound score object to read the values of other parameter fields when the object is applied. The help text contains examples.
EXAMPLE 1: (fill-template csound-score-object score1
"" nil nil 1 10 1 0
(random-value 0.1 1))
EXAMPLE 2: (fill-template csound-score-object score2
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 10 1
0 1 0.8 (random-value 220 880))
EXAMPLE 3: (fill-template csound-score-object score3
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 10 1 0
(random-choice '(-1 1)) 0.8
(walk 220 100))
EXAMPLE 4: (fill-template csound-score-object score4
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1
(until-time 10) 1 0
(random-value .5 1)
(convert expo-shape
(from-number) 0.01 0.8)
(random-value 220 880))
EXAMPLE 5: (fill-template csound-score-object score5
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 100 1
(random-value 0.0 10)
(rv .1 .2)
(rv 0.1 0.2)
(rv 1000.0 1500))
EXAMPLE 6: (fill-template csound-score-object score6
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1
(from-start-times) 1
(density-of-start-times
10
line-shape 1 30)
(random-value 0.1 .2)
(convert line-shape
(from-number) 0.1 0.2)
(random-value 1000.0 1500))
EXAMPLE 7: (fill-template csound-score-object score7
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 3 100 1 0
(random-value 0.1 0.2)
(scale-by-layers 0.6)
(walk 440.0 (random-value -20.0 20) 100 1000))
EXAMPLE 8: (for-example
(make&sort 10 (random-value 0.0 10)))
EXAMPLE 9: (fill-template csound-score-object score8
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1 20 1
(make&sort 20 (random-value 0.0 10))
(random-value 0.1 0.2) 0.2
(convert line-shape 20 200.0 500))
EXAMPLE 10: (fill-template csound-score-object score9
"" nil nil 1 10 1 0 2 1
(random-value 220 880)
.1 .2 .3 (random-value 1.0 2)
5 6 3 2 (random-value 1.0 10) 4)
EXAMPLE 11: (fill-template generate-mask
mask1 4 (rv 1 100)
(rv 1 100))
EXAMPLE 12: (plot mask1)
EXAMPLE 13: (fill-template csound-score-object score10
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 3 100 1 0
(random-value 0.05 0.1)
(scale-by-layers 0.4)
(convert mask1 (from-number) 600.0 1000.0))
EXAMPLE 14: (fill-template csound-score-object score10b
"f1 0 8193 10 1
f2 0 8193 20 2 1" '(mask1) nil 3 100 1 0
(random-value 0.05 0.1)
(scale-by-layers 0.4)
(convert mask1 (from-number) 600.0 1000.0))
EXAMPLE 15: (fill-template csound-score-object score11
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil '(mask1) 3 100 1 0
(random-value 0.05 0.1)
(scale-by-layers 0.4)
(convert mask1 (from-number) 600.0 1000.0))
EXAMPLE 16: (fill-template generate-sequential-score-object
score12 4 (rv 0.5 1.5) score11)
EXAMPLE 17: (fill-template csound-score-object score13
"" nil nil 1 30 3 0
(random-value 0.1 0.2)
(sf-name "roscoe.aiff")
(rv 0.0 5) 1 0.01 0.01)
EXAMPLE 18: (fill-template csound-score-object score14
"" nil nil 1 30 3 0
(random-value .1 .2)
(generate-sf-name
(random-choice '("roscoe.aiff" "partch")))
0 1 .01 .01)
EXAMPLE 19: (fill-template csound-score-object score15
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 100 1
(overlap 0
(random-value 0.05 0.1)
0.01)
(from-overlap) 0.4
(random-value 100.0 1000))
EXAMPLE 20: (fill-template csound-score-object score16
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 100 1
(overlap 0
(random-value 0.05 0.1)
50 :percent t)
(from-overlap) 0.4
(random-value 100.0 1000))
csound: sequential objects
Csound score objects can be combined in sequence in 2 ways. The sequence of objects can be specified by name or the sequence can be generated using a generator etc. which will choose from among available scores. In both cases, each time another score object is applied, it is generated anew.
To specify a sequence of score objects, use the 'Sequential Scores' menu item. In the space for score objects, the names of score objects can be entered.
Scores used in as sequential score should have been specified or applied before using them in a definition.
For the examples in this help, the instruments defined in test csound.orc will be used (examples 1-3).
As many objects as desired can be entered. The objects can be csound score objects, sequential score objects, or parallel score objects.
A time delay between objects can be specified as a number (in seconds). If no delay is desired, no number need be entered.
In the example 4, a gap of 3 seconds will occur between the end of score2 and the beginning of score1. Note that the two applications of score1 may result in different score files (depending on the way that score1 was specified). If score1 contains generators with random aspects, the files will probably be different.
To generate a sequence of score objects, use the menu item 'Generate Sequential Scores'.
The number of scores to be generated, something to produce an offset value (between the scores), and a generator etc. to choose the sequence of scores should be entered (example 5).
The offset value can be a constant, list, generator, etc. If the offset is 0, there will be no time gap between the end of one score and the beginning of another. The first score always starts at time 0.
The scores can be chosen with a generator as in example 5. A list could be given in which case the scores occur in the same order as they occur in the list (example 6).
The name of a single score could be used (example 7).
Note that the calculation in any F statements in the header is not changed by a sequential combination. It is the responsibility of the user to ensure that function definitions are appropriate.
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8192 10 1
f2 0 8192 20 2 1"
nil nil 1 100 1
(random-value 0.0 10)
(rv .1 .2)
(rv 0.1 0.2)
(rv 1000.0 1500))
EXAMPLE 2: (fill-template csound-score-object score2
"f1 0 8192 10 1
f2 0 8192 20 2 1"
nil nil 3 100 1 0
(random-value 0.1 0.2)
(scale-by-layers 0.5)
(walk 440.0 (random-value -20.0 20) 100 1000))
EXAMPLE 3: (fill-template sequential-score-object sequential-score1
score1 score2)
EXAMPLE 4: (fill-template sequential-score-object sequential-score2
score1 score2 3 score1)
EXAMPLE 5: (fill-template generate-sequential-score-object
generate-sequential-score1 5
(random-value 0.0 2)
(random-choice '(score1 score2)))
EXAMPLE 6: (fill-template generate-sequential-score-object
generate-sequential-score2 5
(random-value 0.0 2)
'(score1 score2))
EXAMPLE 7: (fill-template generate-sequential-score-object
generate-sequential-score3 5
(random-value 1.0 3)
score1)
(current function argument generator-or-thing)
(current function generator-or-thing)
(current generator-or-thing)
This tool is intended to be used as part of the specification for the generator SELECT-GENERATOR-BY-CONDITION.
The tool exists in the three forms listed above. An example of each form:
(current #'= 1 (random-value 1 10))
(current #'evenp (random-value 20 40))
(current (random-value 1 100))
These examples and their usage are explained in the help for SELECT-GENERATOR-BY-CONDITION
(custom-density-choice shape stockpile)
Returns a closure. When applied, a value is randomly chosen from STOCKPILE. The probability density function of the random value which is used as an index for reading the stockpile reflects the curve of SHAPE mapped between the first and last index value of STOCKPILE.
This generator allows the user to create any desired random distribution. The larger the number of values chosen with this generator, the closer the desired probability density function is approximated.
SHAPE should be a shape object or a list representing a shape.
STOCKPILE may be a list, stockpile object, etc. (example 1).
The basic algorithm for this generator was published in:
Dodge, C. and T. Jerse. (1997). Computer Music: Synthesis, composition, and performance. 2nd edition. New York: Schirmer Books.
EXAMPLE 1: (make-histogram
(custom-density-choice expo-shape (from 1 100)))
(custom-density-value shape low-value high-value &key round)
Returns a closure. When applied, a random value between LOW-VALUE and HIGH-VALUE is returned. The probability density function of this random distribution reflects the curve of SHAPE mapped between LOW-VALUE and HIGH-VALUE.
This generator allows the user to create any desired random distribution. The larger the number of values chosen with this generator, the closer the desired probability density function is approximated.
SHAPE should be a shape object or a list representing a shape. If LOW-VALUE and HIGH-VALUE are integers, the result is an integer. Otherwise the result is a real number.
LOW-VALUE and HIGH-VALUE cannot vary over time (examples 1-2).
To quantize the result with another unit, bind ROUND to a quantization unit (example 3).
The basic algorithm for this generator was published in:
Dodge, C. and T. Jerse. (1997). Computer Music: Synthesis, composition, and performance. 2nd edition. New York: Schirmer Books.
EXAMPLE 1: (make-histogram (custom-density-value expo-shape 1 100))
EXAMPLE 2: (make-histogram (custom-density-value '(50 100 1) c1 c5))
EXAMPLE 3: (for-example
(custom-density-value expo-shape 1.0 100 :round 0.25))
data section
A section where the input for each of the parameters (rhythm, pitch, velocity, and channel) is specified separately.
dealing with parentheses
It is important to have the appropriate number of parentheses in an expression. When entering data for objects or other text input panes, there are three ways to determine if the parentheses are balanced properly.
1. Place the cursor after a right parenthesis or before a left one. Use the menu item Edit>Balance () or its keyboard shortcut CMD-0 (that is a zero not an O). The cursor will move to the corresponding parenthesis. Use the menu item again to return the cursor to its original position.
2. Place the cursor in or after an expression. Use the menu item Edit>Select () or its keyboard shortcut cmd-( to select everything between parentheses.
3. Pressing return in most text input panes will open a mini-editor. This can also be done by pressing the check box near such an input pane. In the mini-editor, corresponding parentheses are highlighted when the cursor is placed at a parenthesis. This same balancing mechanism occurs in the Listener and the Lisp editor.
default objects
A few objects have been included with the AC Toolbox. These are the default objects. Among them are three shapes (line-shape, sine-shape, and expo-shape), a note-structure called WILHELMUS, and a stream named TESTING.
When ALL is selected in the OBJECTS dialog, these objects can be seen in the table. They can be examined or played as appropriate. They cannot be removed.
The three shapes have been included for convenience when using tools that require shapes. Many of the examples in the help windows use one or more of these shapes (example 1).
The WILHELMUS can be used to make a structured section (example 2).
WILHELMUS (and other note-structures) can be used with -CHOICE generators, e.g. RANDOM-CHOICE, BETA-CHOICE, etc. to produce notes in a note-section (example 3).
TESTING can be used to test if the Midi connections have been setup right. TESTING will produce an endless series of events with Midi note number 60 in channel 1 when played. To play TESTING, select ALL or STREAMS in the OBJECTS dialog.
The options for the OBJECTS dialog provide a mechanism to hide the default objects.
EXAMPLE 1: (for-example (convert sine-shape 20 40 80))
EXAMPLE 2: (fill-template structured-section wil-section 150
wilhelmus)
EXAMPLE 3: (fill-template note-section my-song 150 62
(random-choice wilhelmus) 0)
(define name object &optional comment size position)
DEFINE is used to associate objects with names. The primary use is with the text version of the toolbox. Any AC Toolbox object (such as a section, community, shape, etc.) can be defined with this tool. Occasionally, objects in help files are also defined with it (example 1).
See the Help menu for Lisp for examples of using it in Lisp code.
COMMENT is an optional parameter which can be used to associate a comment with an object. It should be a string (example 2).
A comment can be accessed by applying GET-COMMENT to the object (example 3).
The optional parameters for SIZE and POSITION are used by the program to save the size and position of the dialogs which make the object definition. The values should be valid values for window sizes and positions (example 4).
To see the dialog for specifying stockpile2, choose the Input button in the Objects dialog.
EXAMPLE 1: (define section1
(make-data-section
10 50 1
(random-value 40 80) mf 1))
EXAMPLE 2: (define stockpile1
(specify-stockpile 1 2 3 4)
"This is a stupid stockpile.")
EXAMPLE 3: (print-result (get-comment stockpile1))
EXAMPLE 4: (define stockpile2 (specify-stockpile 1 2 3 4)
"" '(400 200) '(100 100))
(define-scale interval-list)
Returns a closure that expects one input parameter that should be a number. INTERVAL-LIST is a series of intervals that are added to the previous output of the closure. This tool is convenient for defining functions that generate scales (examples 1-2).
DEFINE-SCALE can be evaluated in the examples pane of a help window, within a pane for a Lisp Editor (File > Text > New), or within a Listener.
EXAMPLE 1: (define my-scale (define-scale '(1 2 2 1)))
EXAMPLE 2: (for-example (my-scale c4) :number 8)
(density time shape minimum-density maximum-density
&key (function (random-value 0 100)) (unit 1))
This tool is a shortcut for DENSITY-OF-START-TIMES.
It can be used when generating Csound or OSC score files.
Its purpose is to calculate a list of start times for events using a shape (or mask) to determine the density of events per some UNIT of time.
TIME is the total amount of time in the score.
SHAPE is the name of the shape or mask to use to determine the varying density. SHAPE is mapped to produce values between MINIMUM-DENSITY and MAXIMUM-DENSITY.
The default for UNIT is 1 seconds (example 1).
See the documentation for DENSITY-OF-START-TIMES for more information and examples (example 2).
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1
(from-start-times) 1
(density 10 line-shape 1 10)
(random-value 0.5 1)
0.1
(random-value 220 880))
EXAMPLE 2: (show-help 'density-of-start-times)
density section
A section where time is the most important parameter. An amount of time is specified and later filled with a specified number of notes.
This is different from other section specifications where the total length of the section is the sum of the lengths of all of the notes.
(density-of-start-times time shape
minimum-density maximum-density
&key (function (random-value 0 100))
(unit 1))
This tool can be used when generating Csound or OSC score files.
Its purpose is to calculate a list of start times for events using a shape (or mask) to determine the density of events per some UNIT of time.
TIME is the total amount of time in the score or note list.
SHAPE is the name of the shape to use to determine the varying density. The shape is mapped to produce values between MINIMUM-DENSITY and MAXIMUM-DENSITY.
The default for UNIT is 1 second.
In example 1, a list of start-times filling 10 seconds is produced. The shape will be mapped to determine the density per 1 second (the default value for UNIT).
Note that in this example, there is one start time between 0 and 1 seconds, two start-times between 1 and 2 seconds, 3 start-times between 2 and 3 seconds, etc. The density is increasing linearly because line-shape increases linearly.
Note also that the start-times are sorted to be in ascending order.
This tool should be used as input for the START parameter when generating Csound or OSC files. In that case, the input for NUMBER should be (from-start-times).
Example 2 is a dialog for generating Csound score files using this tool.
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
A binary OSC file could be written with this object using synthdef sine1 (example 3).
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
To change the unit of time for the density calculation, the keyword UNIT should be used. The default value is 1. It is expressed in seconds. Example 4 produces twice as many values. Instead of starting with a density of 1 per second, the density is 1 per .5 second.
The keyword FUNCTION determines where within a time interval the start-time will occur. The default function is (random-value 0 100). The arguments refer to percentages: 0 percent of the available time interval to 100 percent of the available time interval. The default function causes the start-times to be more or less uniformly spread within the interval. A different function would spread them differently. BETA-VALUE would tend to group events near the begin and end of a time unit which per default is 1 second (example 5).
The shortcut for DENSITY-OF-START-TIMES is DENSITY (example 6).
EXAMPLE 1: (for-example
(density-of-start-times 10 line-shape 1 10))
EXAMPLE 2: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1
(from-start-times) 1
(density-of-start-times
10 line-shape 1 10)
(random-value 0.5 1)
0.1
(random-value 220 880))
EXAMPLE 3: (fill-template
osc-score-object osc-score1
(from-start-times) "sine1" nil 'nil 'nil 1
(density-of-start-times 10 line-shape 1 10)
"dur" (random-value 0.5 1) "amp" 0.1
"freq" (random-value 220 880))
EXAMPLE 4: (for-example
(density-of-start-times
10 line-shape 1 10 :unit .5))
EXAMPLE 5: (for-example
(density-of-start-times
10 line-shape 1 10
:function (beta-value 0 100 .1 .1)))
EXAMPLE 6: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1
(from-start-times) 1
(density
10 line-shape 1 10)
(random-value 0.5 1)
0.1
(random-value 220 880))
(derive-transition-table source order &key key)
This tool constructs a transition table which can be used with the generator TRANSITION (see transition's help window using example 1).
SOURCE should be a list, stockpile, note structure, or section containing the material from which the transition table will be made. If SOURCE is a section, the notes of a section will be used in their order of occurence but without reference to any simultaneities or overlappings.
ORDER refers to the order of the transition table. Order 0 considers 0 previous values. Order 1 considers 1 previous value, etc. (examples 2-5)
KEY is by default #'GET-ELEMENT which selects an element from the source. If the source is a list of numbers, the default KEY returns one number. If a note-structure or section contains notes, the default KEY returns the input description of the note. For dealing with note structures or sections, the selectors NOTE-PITCH, NOTE-RHYTHM, and NOTE-VELOCITY are available. They make a table from a list of pitches, rhythms, or velocities (example 6).
Example 7 uses TRANSITION and DERIVE-TRANSITION-TABLE in the definition of a note section.
If SOURCE is a section with more than one note starting at the same time, the simultaneous pitches can be gathered into a list (using the key CHORD-PITCH) or returned as part of a note (CHORD-NOTE) when the table is derived. Example 8 defines a section with one layer. Example 9 makes a section with four layers. Example 10 makes a first-order table for pitches with pitches that start at the same time gathered into a list. Example 11 makes a note section with a table without simultaneous pitches gathered together. In example 12, they are gathered together using CHORD-NOTE.
EXAMPLE 1: (show-help 'transition)
EXAMPLE 2:
(for-example (derive-transition-table '(a b c d e a b c) 0))
EXAMPLE 3:
(for-example (derive-transition-table '(a b c d e a b c) 1)
:number-per-line 1)
EXAMPLE 4:
(for-example (derive-transition-table '(a b c d e a b c) 2)
:number-per-line 1)
EXAMPLE 5:
(for-example (derive-transition-table wilhelmus 0)
:number-per-line 1)
EXAMPLE 6:
(for-example
(derive-transition-table wilhelmus 1 :key #'note-pitch)
:number-per-line 1)
EXAMPLE 7:
(fill-template note-section another-wil 150 100
(transition (derive-transition-table wilhelmus 2)))
EXAMPLE 8:
(fill-template data-section s1 150 40
(plus-min (rv 1 3) .3) (rv c3 c7) (rc '(pp mf ff)) 1)
EXAMPLE 9:
(fill-template new-generate-parallel-section
s2 4 0 s1 nil nil nil nil)
EXAMPLE 10:
(for-example (derive-transition-table s2 1 :key #'chord-pitch)
:number-per-line 1)
EXAMPLE 11:
(fill-template note-section s3 150 100
(transition
(derive-transition-table s2 1)))
EXAMPLE 12:
(fill-template note-section s4 150 100
(transition
(derive-transition-table s2 1 :key #'chord-note)))
display
has been renamed PLOT.
(do-the-next-thing object)
Returns a closure. When applied, it will produce the next element (or thing) from the object.
If the OBJECT is a function, it is returned as is since the function will return the next thing when it is applied (example 1). If the OBJECT is a sequence or stockpile, it is encapsulated in a loop-through closure that, upon application, will produce the next value of the sequence (example 2). If the object is a constant, it will be repeated each time the generator is applied (example 3).
DO-THE-NEXT-THING is useful when programming generators, etc. in Lisp.
EXAMPLE 1: (for-example (do-the-next-thing (random-value 1 10)))
EXAMPLE 2: (for-example (do-the-next-thing '(1 2 3)))
EXAMPLE 3: (for-example (do-the-next-thing 143))
(duffing x y A B G omega giant &key eye xy (stepsize 0.01) first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x'=y
y'=-Ay-Bx^3+Gcos(omega*t)
The default output variable is X. By using the keyword EYE the variable Y is returned. Both variables will be returned in a list by using the keyword XY.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
The system is a driven oscillator with a non-linear compliance term (Bx^3).
By setting G and OMEGA to zero, the system is non-driven (example 1).
The driven oscillator can behave in a chaotic way (example 2).
If the damping is large, the transient part of the oscillation will soon fade away (example 3).
It is not easy to predict the maximum and minimum of the output values. To map the output of this function to useful values, use CONVERT (example 4).
The initial values for X and Y are not returned. If the initial values should be returned as the first result of the generator, keyword FIRST should be bound to t (examples 5-6).
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (duffing 1.0 1.0 0.0 1.0 0.0 0.0 10)
:number 300)
EXAMPLE 2: (plot (duffing 1.0 1.0 0.1 5.6 0.7 pi 10)
:number 600)
EXAMPLE 3: (plot (duffing 4.0 4.0 5.6 8.7 9.0 0.7 10)
:number 300)
EXAMPLE 4: (for-example
(convert (duffing 1.0 1.0 0.1 5.6 0.7 pi 10) 100 c2 c5))
EXAMPLE 5: (for-example
(duffing 1.0 1.0 0.0 1.0 0.0 0.0 10))
EXAMPLE 6: (for-example
(duffing 1.0 1.0 0.0 1.0 0.0 0.0 10 :first t))
(duplicates &key diversity pitch-class)
Duplicates produces a function appropriate for use with WITHOUT. It will return a function that will disallow any value that has already occurred (example 1).
A problem will arise with the use of DUPLICATES if the generator is not able to produce a value that has not already occurred (example 2).
This could be addressed by binding a value to the keyword DIVERSITY. This value defines how many new values have to be chosen before all values are again available to be chosen (example 3).
Example 4 chooses groups of three unique values from all available values.
The value bound to the keyword DIVERSITY can be a constant, list, generator, etc. If the value is not a constant, a new value for diversity will be chosen each time all values are again available to be chosen. Example 5 chooses 3 unique values, then 4 unique values, then 5 unique values, etc.
Keyword PITCH-CLASS can expand the concept of duplicates to include any member of the same pitch-class. In example 6, the three-note groups must contain values from different pitch-classes. The result is converted with MIDI->NOTENAME to make it easier to verify the accuracy of the results.
EXAMPLE 1: (for-example
(without (duplicates)
(random-value 1 20)))
EXAMPLE 2: (for-example
(without (duplicates)
(random-value 1 10)))
EXAMPLE 3: (for-example
(without (duplicates :diversity 10)
(random-value 1 10)))
EXAMPLE 4: (for-example
(without (duplicates :diversity 3)
(random-value 1 10))
:number 21 :number-per-line 3)
EXAMPLE 5: (for-example
(without (duplicates :diversity '(3 4 5))
(random-value 1 5)))
EXAMPLE 6: (for-example
(midi->notename
(without (duplicates :diversity 3 :pitch-class t)
(rc '(c3 c4 c5 d2 d3 d4 g#4 f#4 a4))))
:number 21 :number-per-line 3)
editing objects
Some objects can be edited by selecting the 'Edit' button in the Objects dialog.
The objects that can be edited are: sections, midi objects, stockpiles, shapes, and masks. Shapes and masks are edited by drawing. The other objects are edited by changing text values.
To edit a section, select it in the Objects dialog and click on the 'Edit' button. A window will open with the values for the section events printed in a fashion somewhat similar to a spreadsheet. Each line of text is an event. The first column is an index value, starting with 1. Time and duration are expressed in milliseconds. Channels are numbered starting with 1. Velocity and pitch are represented as midi numbers.
Values for the parameters can be changed by replacing the current text value with another one. Pitch and velocity could also have one of the predefined input symbols such as pp or c4 entered. To remove an entire event, the entire line should be erased. To add a new event, copy an existing line and change the values. It is important that the order of the columns be kept as is.
When all changes have been made, click on the 'Make' button to store the new events. If the same name is used as the original object, the events of that object will be replaced. If a new name is given, a new object with the edited events will be made and the original object is not changed. In both cases, the input description of the original object is used as the input description for the object.
If a comment had been added to the original object, it will be presented in the comment location in the editor. The comment may also be edited. The edited comment will be used as the comment for the original object (if the name of the object is not changed) or as the comment for the new object.
Midi objects are edited in a similar fashion.
When a stockpile is edited, the values of the stockpile are presented left to right, top to bottom. Values can be replaced or added. The input specification of the original stockpile is used as the specification for the new object.
Shapes and masks are edited by drawing. Even if the shape was made by specifying or generating values, the result is presented in a window similar to 'Draw Shape'. The shape can be edited by changing the drawing. A similar process is used for masks. The original input specification is stored as the input for the new object.
element
has been renamed CURRENT.
environment
Various types of objects can be created with the Toolbox. These include sections, shapes, masks, stockpiles, etc. Objects are stored as part of the current Environment. The Environment contains a list of all objects which have been defined by a user during a session. The dialog for OBJECTS has a popup menu to list the objects according to their various types. Choosing the menu item ALL will show a list of definitions made in a session.
OBJECTS allows you to get information about the objects created. For all objects it is possible to see the input specification. TOOLS > REMOVE OBJECTS allows you to remove an object from the environment. TOOLS > REMOVE ALL OBJECTS allows you to remove all objects in the environment at once.
All objects included in the Environment are saved to a disk file when the FILE > SAVE ALL OBJECTS is chosen. When the menu item REPLACE ALL OBJECTS is chosen, the current Environment is replaced with one that has been previously saved in a file. The menu item LOAD OBJECTS adds the contents of an Environment file to the current Environment.
Environments saved in this version of the AC Toolbox cannot be read in version 4.3.x or earlier unless 'Old Format' is chosen in the Preferences dialog.
Environments saved in earlier versions of the AC Toolbox can be read in this version.
environment does not load
If an environment gives as error message upon loading, this could be caused by some arcane dependency of the objects being loaded and the order in which this happens. This is a very rare occurence and mostly involves streams.
If the error message was similar to this:
Unbound variable: CONT1
this might be solved by evaluating the following expression in the Listener but substituting the name of the unbound variable for CONT1.
(setf cont1 nil)
The environment file should be loaded again. If this does not solve the problem and there are no more messages of this type and you recognize the name of the offending object, define it again (or a very simple version of it) and then reload the environment. An easy way to define an object is to pick one from the dialog examples and make it with the appropriate name.
If the environment will still not load, then you could open the file with the 'File>Text>Open' menu item and maybe you can figure out what to delete. Maybe not. Good luck.
In any case, at least part of the environment was probably read in before the error occurred.
errors
When the AC Toolbox catches errors, a message dialog containing the error message is placed on the screen. These errors include things such as not filling all the boxes of a dialog, using undefined objects, etc. The message should help you fix the problem.
Errors missed by the Toolbox but noticed by the underlying Lisp environment are also printed in a dialog. These messages tend to be about obscure things such as divide by zero. The message may or may not help you fix the problem.
In very exceptional cases, an underlying Lisp error could cause a message to be printed in a window of the Terminal application.
In that case, type :a in the Terminal window.
If that doesn't help, type :top.
If that doesn't help, try :top or :a again.
If the Terminal window presents options, type :c 1 if you want to do option 1,
:c 2 if you want to do option 2, etc.
If a message appears in the Terminal concerning stack overflow, choose :c 2 to extend the stack. This may need to be done a couple of times.
If an object with many events is to be plotted, and the pizza wheel of death spins for a long time and a Terminal window opens, try typing :c to force a list of options, then choose :c 2 to extend the stack.
There have been reports that the printing in the Terminal window may be followed by a message from the system that the AC Toolbox crashed. Close the Terminal Window, click on Reopen in the crash message, and you may be able to continue working where you left off in the AC Toolbox.
(ev threshold gamma &optional upper-boundary round)
EV is a shortcut for EXPONENTIAL-VALUE.
It returns values chosen with an exponential distribution with THRESHOLD being the lowest possible value (examples 1-2).
GAMMA controls the spread of values. The larger the value for GAMMA, the greater the probability of producing values near THRESHOLD (examples 3-4).
See the documentation for EXPONENTIAL-VALUE for more information (example 5).
EXAMPLE 1: (make-histogram (ev 0.0 .1))
EXAMPLE 2: (make-histogram (ev 10.0 .1))
EXAMPLE 3: (make-histogram (ev 0 .01))
EXAMPLE 4: (make-histogram (ev 0 .1))
EXAMPLE 5: (show-help 'exponential-value)
(ex controller-number low high &key round)
EX is a shortcut (abbreviation) for EXTERNAL-VALUE.
When the closure is applied, it returns the value of a Midi controller which has been mapped to the range LOW - HIGH. CONTROLLER-NUMBER is the number of the Midi controller.
See the help for EXTERNAL-VALUE for more information (example 2).
EXAMPLE 1: (fill-template
make-midi-data-stream stream1 100 1
(rv (ex 1 40 80) (ex 2 40 80))
f 1)
EXAMPLE 2: (show-help 'external-value)
(expand factor middle-line)
Returns a closure. FACTOR is a percentage from 0 to infinity. MIDDLE-LINE is a number. Expanding a value to 0% of its value makes it equal to the MIDDLE-LINE. Expanding 100% is its original value (examples 1-4).
FACTOR and MIDDLE-LINE may vary over time.
EXAMPLE 1: (show-transformation (expand 50 50)
'(0 20 40 50 60 75 80 100))
EXAMPLE 2: (show-transformation (expand 0 50)
'(0 20 40 50 60 75 80 100))
EXAMPLE 3: (show-transformation (expand 100 50)
'(0 20 40 50 60 75 80 100))
EXAMPLE 4: (show-transformation (expand 200 50)
'(0 20 40 50 60 75 80 100))
(expcurve-choice stockpile &key (curve 2))
Returns a closure. When applied, one value from STOCKPILE is chosen using an exponential distribution (as described for EXPCURVE-VALUE). With the default value for CURVE it favors choosing values near the beginning of the STOCKPILE (example 1).
STOCKPILE may be a list, stockpile, etc.
If CURVE is > 1 (default is 2), higher values for CURVE results in more choices from the beginning of the stockpile (examples 2-3).
If CURVE is between 0-1, more values near the end of the stockpile are chosen (examples 4-5).
The generators EXPONENTIAL-CHOICE and EXPRAND-CHOICE also make exponential choices. For a discussion of the differences in their algorithms, evaluate example 6.
EXAMPLE 1: (for-example (expcurve-choice (from 1 20)))
EXAMPLE 2: (for-example (expcurve-choice (from 1 20) :curve 5))
EXAMPLE 3: (for-example (expcurve-choice (from 1 20) :curve 10))
EXAMPLE 4: (for-example (expcurve-choice (from 1 20) :curve .5))
EXAMPLE 5: (for-example (expcurve-choice (from 1 20) :curve .1))
EXAMPLE 6: (show-help "exponential generators")
(expcurve-value low high &key (curve 2) round)
Returns a closure. When applied, one exponentially-distributed value between LOW and HIGH is produced. Values will always be between LOW and HIGH (examples 1-2).
CURVE determines if lower or higher values are favored. If CURVE is > 1, more lower values are produced than higher ones. The higher the value for CURVE (> 1), the more lower values are chosen (examples 3-4). The default value for CURVE is 2.
If CURVE is between 0-1, higher values are favored (examples 5-6). The lower the value for CURVE (between 0-1), the more higher values are chosen.
The exact boundaries for the behavior of CURVE are a bit tricky to determine. Negative values are not allowed (the absolute value of a negative value for CURVE will be used instead).
If LOW or HIGH is a real number, the result is a real number (example 7). Otherwise the result is an integer (example 8).
To quantize a real result with another unit, bind ROUND to a quantization unit (example 9).
LOW, HIGH, and CURVE can vary over time (examples 10-11).
EXPCURVE-VALUE can be abbreviated as XCV (example 12).
Exponentially-distributed values can also be produced using EXPONENTIAL-VALUE or EXPRAND-VALUE. A discussion of the differences between the generators that produce exponential distributions can be found via example 13.
EXAMPLE 1: (make-histogram (expcurve-value 1 100))
EXAMPLE 2: (for-example (expcurve-value 40 50))
EXAMPLE 3: (make-histogram (expcurve-value 1 100 :curve 5))
EXAMPLE 4: (make-histogram (expcurve-value 1 100 :curve 10))
EXAMPLE 5: (make-histogram (expcurve-value 1 100 :curve .1))
EXAMPLE 6: (make-histogram (expcurve-value 1 100 :curve .5))
EXAMPLE 7: (for-example (expcurve-value 60.0 72))
EXAMPLE 8: (for-example (expcurve-value 60 72))
EXAMPLE 9: (for-example (expcurve-value 60.0 72 :curve 3 :round .5))
EXAMPLE 10: (plot (expcurve-value (line 100 40 70) 80))
EXAMPLE 11: (plot (expcurve-value 40 80 :curve (line 100 2.0 10)))
EXAMPLE 12: (plot (xcv 40 80))
EXAMPLE 13: (show-help "exponential generators")
exponential generators
A few different random generators are available that produce exponential distributions in slightly different ways.
EXPONENTIAL-VALUE uses a classic mathematical formula and is therefore the most 'accurate' of the available exponential generators. No theoretical upper limit exists for this distribution (example 1).
The distribution is controlled by the second argument, GAMMA, which produces more low values as it becomes larger (example 2).
A third, optional argument is an upper limit. This makes the generator more practical to use. Depending on the value for GAMMA, the upper limit may distort the mathematical properties of the function (example 3).
Example 4 opens the help for EXPONENTIAL-VALUE.
EXPRAND-VALUE is a modified form of the algorithm found in SuperCollider. The advantage of that algorithm is that the value will always be between LOW and HIGH (example 5).
A feature of that algorithm is that in the SuperCollider implementation, the shape of the distribution is dependent on the ratio of HIGH to LOW. This means that the shape of the distribution for values between 1-100 will be different than for values in the range 100-200. In the Toolbox version, RATIO is a separate parameter. Higher values for RATIO produce more lower values in the output (example 6).
The calculation is: RATIO is raised to the power of a random number in the range 0-1 and then mapped to LOW-HIGH.
Example 7 opens the help for EXPRAND-VALUE.
EXPCURVE-VALUE always produces values between LOW and HIGH. The shape of the distribution is controlled by CURVE. If CURVE is > 1 (default is 2), the higher the value the more lower numbers are produced (examples 8-9).
This generator can also produce more higher than lower values. If CURVE is between 0-1, the lower the value the more higher numbers are produced (examples 10-11).
The calculation is: a random number in the range 0-1 is raised to the power of CURVE and then mapped to the range LOW-HIGH.
Example 12 opens the help for EXPCURVE-VALUE.
The corresponding choice generators (EXPONENTIAL-CHOICE, EXPRAND-CHOICE, EXPCURVE-CHOICE) display similar behavior as the value generators. The algorithms used for the value generators will pick the index value to read from the stockpile in the choice generators.
EXAMPLE 1: (make-histogram (exponential-value 1 .01))
EXAMPLE 2: (make-histogram (exponential-value 1 .2))
EXAMPLE 3: (make-histogram (exponential-value 1 0.2 10))
EXAMPLE 4: (show-help 'exponential-value)
EXAMPLE 5: (make-histogram (exprand-value 60 72))
EXAMPLE 6: (make-histogram (exprand-value 60 72 :ratio 500))
EXAMPLE 7: (show-help 'exprand-value)
EXAMPLE 8: (make-histogram (expcurve-value 40 80))
EXAMPLE 9: (make-histogram (expcurve-value 40 80 :curve 5))
EXAMPLE 10: (make-histogram (expcurve-value 40 80 :curve .5))
EXAMPLE 11: (make-histogram (expcurve-value 40 80 :curve .1))
EXAMPLE 12: (show-help 'expcurve-value)
(exponential-choice sequence gamma)
Returns a closure. When applied, one element of the sequence is returned. The index of the element was chosen with an exponential distribution. GAMMA determines the spread of the distribution and should be > 0. The larger the value of GAMMA, the greater the probability of producing values near 0 (in this case, picking the first element of the sequence) (examples 1-5).
GAMMA may vary over time.
The generators EXPRAND-CHOICE and EXPCURVE-CHOICE also make exponential choices. For a discussion of the differences in their algorithms, evaluate example 6.
EXAMPLE 1: (for-example
(exponential-choice '(a b c d e f g h i) .01))
EXAMPLE 2: (for-example
(exponential-choice '(a b c d e f g h i) .1))
EXAMPLE 3: (for-example
(exponential-choice '(a b c d e f g h i) .2))
EXAMPLE 4: (for-example
(exponential-choice '(a b c d e f g h i) .5))
EXAMPLE 5: (for-example
(exponential-choice '(a b c d e f g h i)
(line 20 .01 .2)))
EXAMPLE 6: (show-help "exponential generators")
(exponential-motion n start finish &key (curve 2) round)
Returns a closure. When applied, it returns the next of the N values describing an exponential movement from START to FINISH. The type of result is determined by START and FINISH (examples 1-5).
Keyword CURVE controls the shape of the curve. Any positive value may be used. Values > 2 increase the 'sharpness' of the curve (examples 6-7).
To quantize the result with another unit, bind ROUND to a quantization unit (example 8).
The shortcut ARC can be used for EXPONENTIAL-MOTION (example 9).
EXAMPLE 1: (for-example (exponential-motion 20 0 100))
EXAMPLE 2: (for-example (exponential-motion 20 100 0))
EXAMPLE 3: (for-example (exponential-motion 20 0.0 100))
EXAMPLE 4: (plot (exponential-motion 100 0.0 100))
EXAMPLE 5: (plot (exponential-motion 100 100.0 0))
EXAMPLE 6: (plot (exponential-motion 100 0.0 100 :curve 4))
EXAMPLE 7: (plot (exponential-motion 100 100.0 0 :curve 8))
EXAMPLE 8: (for-example (exponential-motion 20 0.0 100 :round 0.25))
EXAMPLE 9: (plot (arc 100 0.0 100 :curve 8))
(exponential-value threshold gamma &optional upper-boundary round)
Returns a closure. When applied, a random value with an exponential distribution is returned. This distribution favors lower values (near THRESHOLD).
The number returned is >= THRESHOLD. If THRESHOLD is an integer, the result from this generator will also be an integer (example 1). If THRESHOLD is a real number, the result is a real number (example 2).
GAMMA determines the spread of the distribution and should be > 0. The larger the value of GAMMA, the greater the probability of producing values near THRESHOLD (examples 3-5).
There is no theoretical upper limit. If the optional UPPER-BOUNDARY is supplied, the number will be <= to it (example 6).
THRESHOLD, GAMMA, and UPPER-BOUNDARY may vary over time. In example 7, THRESHOLD varies over time.
To quantize the result with another unit, bind ROUND to a quantization unit (example 8). Note that ROUND is an optional parameter (not a key word) and therefore there must be a value specified for UPPER-BOUNDARY. If no UPPER-BOUNDARY is desired, nil can be entered for it.
The average value for this distribution is 1/gamma (example 9).
EXPONENTIAL-VALUE can be abbreviated to EV (example 10).
Exponentially-distributed values can also be produced using EXPRAND-VALUE or EXPCURVE-VALUE. A discussion of the differences between the generators that produce exponential distributions can be found via example 11.
EXAMPLE 1: (for-example (exponential-value 0 .1))
EXAMPLE 2: (for-example (exponential-value 0.0 .1))
EXAMPLE 3: (make-histogram (exponential-value 0 .1))
EXAMPLE 4: (make-histogram (exponential-value 0 .5))
EXAMPLE 5: (plot (exponential-value 0.0 .5))
EXAMPLE 6: (for-example (exponential-value 40 .1 80))
EXAMPLE 7: (plot
(exponential-value (line 100 30 50) .1 80))
EXAMPLE 8: (for-example (exponential-value 0.0 .1 nil 0.25))
EXAMPLE 9: (print-result (average (exponential-value 0.0 .1) 10000))
EXAMPLE 10: (make-histogram (ev 0 .1))
EXAMPLE 11:(show-help "exponential generators")
(exprand-choice stockpile &key ratio)
Returns a closure. When applied, one value from STOCKPILE is chosen using an exponential distribution. This distribution favors values with a lower index (examples 1-3).
STOCKPILE may be a list, stockpile, etc.
RATIO controls the spread. The default value is 100 (examples 4-5). Lower values increase the spread. RATIO can change over time.
The generators EXPONENTIAL-CHOICE and EXPCURVE-CHOICE also make exponential choices. For a discussion of the differences in their algorithms, evaluate example 6.
EXAMPLE 1: (make-histogram (exprand-choice (from 0 500 :step 5)))
EXAMPLE 2: (plot (exprand-choice (from 0 500 :step 5)))
EXAMPLE 3: (for-example (exprand-choice '(a b c d e f g h i j k)))
EXAMPLE 4: (plot (exprand-choice (produce 40 (major c2))))
EXAMPLE 5: (plot (exprand-choice (produce 40 (major c2)) :ratio 10))
EXAMPLE 6: (show-help "exponential generators")
(exprand-value low high &key ratio round)
Returns a closure. When applied, one exponentially-distributed value between LOW and HIGH is produced. This distribution favors low values.
This generator is related to EXPONENTIAL-VALUE. In EXPRAND-VALUE, a different algorithm is used to produce the value and values will always be in the range LOW to HIGH.
It can be considered a quick and easy way to get something like an exponential distribution in a desired range (examples 1-4). It is less mathematically conventional than EXPONENTIAL-VALUE.
RATIO controls the spread of the distribution. The default value is 100. Lower values result in a greater spread of values (examples 5-6).
To quantize the result with another unit, bind ROUND to a quantization unit (example 7).
LOW and HIGH may vary over time (examples 8-9).
RATIO may also vary over time (example 10).
EXPRAND-VALUE can be abbreviated as XRV (example 11).
Exponentially-distributed values can also be produced using EXPONENTIAL-VALUE or EXPCURVE-VALUE. A discussion of the differences between the generators that produce exponential distributions can be found via example 12.
EXAMPLE 1: (make-histogram (exprand-value 1 100))
EXAMPLE 2: (for-example (exprand-value 1 100))
EXAMPLE 3: (for-example (exprand-value 1.0 100))
EXAMPLE 4: (plot (exprand-value c3 c5))
EXAMPLE 5: (plot (exprand-value c3 c5 :ratio 50))
EXAMPLE 6: (plot (exprand-value c3 c5 :ratio 10))
EXAMPLE 7: (for-example (exprand-value 40.0 80 :round 0.5))
EXAMPLE 8: (plot (exprand-value (line 100 40 70) 80))
EXAMPLE 9: (plot (exprand-value 40 (line 100 80 45)))
EXAMPLE 10: (plot (exprand-value 40 80 :ratio (take 50 100 50 10)))
EXAMPLE 11: (make-histogram (xrv 1 100))
EXAMPLE 12: (show-help "exponential generators")
(external-value controller-number low high &key round)
Returns a closure. When applied it returns the value of a Midi controller which has been mapped to the range LOW - HIGH. CONTROLLER-NUMBER is the number of the Midi controller.
If the preference for 'External-Value' has been set to 'Channels', CONTROLLER-NUMBER will not be the controller number but the number of the Midi channel. This is useful if the external device for instance only uses controller 7 on different channels.
This generator assumes of course that an external Midi controller is connected and an appropriate Midi setup has been defined. This generator works with whatever is chosen as the Midi input in the Midi Setup.
Example 1 controls the range of random numbers with a Midi controller in a data stream (example 1).
To quantize the result, bind ROUND to a quantization unit (example 2).
External-value is useful when controlling streams in real-time.
Controller numbers should be in the range 1-127. If 'Channels' has been selected in the preferences, numbers should be in the range 1-16.
External-value may be abbreviated to ex. E.g. (ex 1 c1 c3).
EXAMPLE 1: (fill-template
make-midi-data-stream stream1 100 1
(rv (external-value 1 40 80) (external-value 2 40 80))
f 1)
EXAMPLE 2: (fill-template
make-midi-data-stream stream2 100
(external-value 1 1.0 3 :round 0.25)
(rv 40 80)
f 1)
(extract parameter object &key chords durmax (velmax t) chanmax (rests t))
Returns a list of values extracted from a section, note structure, community, or midi performance object. PARAMETER determines which values are extracted. The values are in the order of occurance in the section.
Possible parameters are:
PITCH which returns a list of pitch values (as midi note numbers)
RHYTHM which returns a list of rhythmic values (including rests)
DURATION which returns a list of durations in milliseconds (sections)
VELOCITY which returns a list of velocity values
NOTE which returns a list containing note objects
ATTACK which returns a list of attack times (as percentage of the total duration.)
RAW-ATTACK which returns a list of attack times in milliseconds.
CONTROLLER-VALUES which returns controller values from a midi controller object or from a section.
PROGRAM-NUMBERS which returns program numbers from a midi program object or from a section.
CHANNEL which returns a list of channel values.
Section S1 is defined in example 1. Example 2 returns a list of pitch values.
Parameters PITCH, RHYTHM, VELOCITY, and CHANNEL return a list that can be used as input in a data section and reproduce the original section. Rests will be negative numbers in the rhythm list. The corresponding positions in a pitch list or a velocity list will contain a 0.
Example 3 defines a section with rests. Example 4 extracts rhythm. Note the negative values for rests. Example 5 extracts pitches. Note the pitch value of 0 at the locations where rests would occur. Example 6 makes a new data section, using the values for section s1 for rhythm and pitch but using a different value for velocity. To discover the number of notes (and rests) that need to be made, you could evaluate (get-length (extract 'pitch s2)).
Extract can be used to create a list of values which can be manipulated by another generator. In this case, the place holders for rests (0 or a negative value) can be omitted by binding the keyword RESTS to nil (examples 7 and 8). This can also be done with the methods for extracting rhythm, velocity, channel, and note.
Example 9 makes a note section with a list of notes extracted from section s2. Note that rests are included (example 10). Rests can be omitted by binding keyword RESTS to nil. The list of extracted notes can also be used as input to another generator (example 11). Rests are omitted in example 11.
A note-list is a one-dimensional list containing each note from an object, one after another, sorted according to their starting time. Extracting the note list in a note section means that all layers will be flattened into one layer. One note will only start after the previous is finished. This tool is most suitable for a section that is a single, non-overlapping melody.
For sections with several layers, it is possible to gather all events with the same start time into one event. The result is a chord with several pitches but one duration, velocity, and channel value. This feature uses the keywords CHORDS, DURMAX, VELMAX, and CHANMAX.
To show the use of the CHORDS keyword, two sections need to be made (examples 12-13).
Example 12 makes 4 layers of section s5. Example 13 thins it out with a shotgun filter so that not all chords have the same number of values.
Example 14 extracts the notes from section s7 (example 13). The notes are played in series, one after another, with no chords occuring. The default value for RESTS is t.
Example 15 binds the keyword CHORDS to t. This will gather all pitches with the same start time into one note. This note will only have one velocity and one duration value. Pitch repetitions are ignored. These chords will follow each other in sequence.
The chords produced with the keyword CHORDS may make input that is more useful for another generator (example 16).
When CHORDS is bound to t, the choice of duration, velocity, and channel values for the chord depends on the values for the keywords DURMAX (for duration), VELMAX (for velocity), and CHANMAX (for channel). If DURMAX is bound to nil (the default situation), the smallest duration of the notes in the chord is used as the value for the chord. If DURMAX is t, the largest value is used. VELMAX and CHANMAX work in a similar way. The default value for VELMAX is t. The default for CHANMAX is nil (example 17).
If the rhythmic value used to make a section is not known (e.g. when a section is read from a Midi file), the value for the clock input can be derived (example 18).
EXTRACT can also be used to get parameter values from a section read in from a Midi file.
EXAMPLE 1: (fill-template data-section s1 150 40 (rv 1 3)
(rv c3 c7) (rc '(pp mf ff)) 1)
EXAMPLE 2: (print-result (extract 'pitch s1))
EXAMPLE 3: (fill-template data-section s2 150 40
(plus-min (rv 1 3) .3) (rv c3 c7) (rc '(pp mf ff)) 1)
EXAMPLE 4: (print-result (extract 'rhythm s2))
EXAMPLE 5: (print-result (extract 'pitch s2))
EXAMPLE 6: (fill-template data-section s3 150 40
(extract 'rhythm s2)
(extract 'pitch s2)
f 1)
EXAMPLE 7: (print-result (extract 'pitch s2 :rests nil))
EXAMPLE 8: (for-example
(series-choice (extract 'pitch s2 :rests nil)))
EXAMPLE 9: (fill-template note-section s4 150 40
(extract 'note s2))
EXAMPLE 10: (plot s4)
EXAMPLE 11: (fill-template note-section s5 150 40
(random-choice (extract 'note s2 :rests nil)))
EXAMPLE 12: (fill-template new-generate-parallel-section
s6 4 0 s5 nil nil nil nil)
EXAMPLE 13: (fill-template filter s7 s6
(shotgun 30) 'whatever t)
EXAMPLE 14: (fill-template structured-section chord1 150
(extract 'note s7))
EXAMPLE 15: (fill-template structured-section chord2 150
(extract 'note s7 :chords t))
EXAMPLE 16: (fill-template note-section chord3 150 40
(random-choice (extract 'note s7 :chords t)))
EXAMPLE 17: (fill-template note-section chord4 150 40
(random-choice (extract 'note s7 :chords t
:durmax t :velmax nil)))
EXAMPLE 18: (print-result (get-rhythmic-unit s1))
(fibonacci &optional seed1 seed2)
Returns a closure. When applied, it will generate the next value in the Fibonacci series.
In the Fibonacci series, the next value is the sum of the previous two values. The series starts with 0 and 1 (example 1).
Some composers like to have deviant versions of the Fibonacci series. In this case values for the optional parameters SEED1 and SEED2 should be provided. The first value returned will be SEED1, SEED2, then SEED1 + SEED2, etc. In this case it is important that arguments are provided for both SEED1 and SEED2 (example 2).
To return a list of Fibonacci values that are <= some limit, the tool GENERATE-RANGE could be used (example 3).
EXAMPLE 1: (for-example (fibonacci))
EXAMPLE 2: (for-example (fibonacci 100 200))
EXAMPLE 3: (for-example (generate-range (fibonacci) 500000))
(fill-gaps section)
Returns a closure that should be used for the DURATION parameter of a transformation. SECTION must be a section since this transformer only works with sections. Presumably, SECTION would be the name of the section being transformed.
This transformer will add to the duration of any note that does not continue at least until the beginning of the next note. It will not shorten a note that continues past the start of the next note (examples 1-4).
EXAMPLE 1: (fill-template density-section ds1
10 3 (random-value 0.0 100) 100
(random-value 40 80) f 1)
EXAMPLE 2: (plot ds1)
EXAMPLE 3: (fill-template transform transform1 ds1
:duration (fill-gaps ds1))
EXAMPLE 4: (plot transform1)
(fill-template type name &rest data)
FILL-TEMPLATE fills the dialog boxes with initial values. This is primarily useful when writing documentation for objects. The type should agree with the type under the DEFINE menu, except all word combinations should be hypenated. Data section should be data-section, note section should be note-section, etc. Other than types that can be derived from the menu, the following are available: community, data-section, density-section, density-curve-section, note-section, parallel-section, scheme, sequential-section, structured-section, timed-section, xy-section, rule-stockpile, controller-density-object, controller-data-object, program-density-object, program-data-object, data-stream, csound-score-object, sequential-score-object, parallel-score-object, generate-sequential-score-object, generate-parallel-score-object, and osc-score-object.
The remaining values for the dialog should be filled in, from top to bottom, left to right. E.g. for data-section: name, clock unit, number, rhythm, pitch, velocity, channel (example 1).
When in doubt about the appropriate form for entering the data for a particular type of object, look at the way that the input in stored for the object to see how it should be entered.
If object MY-DATA has been made, the input can be accessed with get-input (example 2).
Other possibilities (besides documenting objects) include write-sf for creating the dialog for writing sound files (example 3). Arguments are the expression and the number of iterations. Optionally a minimum and maximum value can be specified as the last two arguments.
EXAMPLE 1: (fill-template data-section my-data 10 100 1
(random-value c2 c5) mf 1)
EXAMPLE 2: (print-result (get-input my-data))
EXAMPLE 3: (fill-template write-sf (sine 441 -10000 10000)
44100)
(filter-and parameter filter ... parameter-N filter-n)
Produces a filter that can be applied to sections. A section event is passed if all of the conditions are met. A condition is a parameter such as pitch and a filter to apply to that parameter. If one or more of the filters return no value, then the original event is rejected.
This allows a filter to combine conditions, e.g. an event may be passed only if the pitch was within a certain range and rhythm below a certain value.
PARAMETER should be PITCH, VELOCITY, CHANNEL, or RHYTHM.
FILTER can be any filter suitable for use with a section, e.g. low-pass, high-pass, or band-pass.
Any number of parameter/filter pairs can be specified.
FILTER-AND should be used in the FILTER method: choose OTHER as the filter type and WHATEVER as the parameter.
Example 1 is a section that will be filtered. It is printed with example 2 and plotted with example 3.
Example 4 filters the section from example 1. It allows events where the pitch is between 65-75 and rhythm is <= 100. Note that rhythm is expressed in milliseconds (rhythmic value * clock unit). Example 5 prints the filtered section and example 6 plots it.
Example 7 makes a section with 4-note chords.
Example 8 will filter the chords. The pitch filter only allows pitches that fall within the specified band-pass range. This will thin out the chords.
Example 9 prints the filtered result.
The filters are applied from left to right.
EXAMPLE 1: (fill-template data-section ds1 100 50
(rv 1 2) (rv 60 80)
mf 1)
EXAMPLE 2: (show-text ds1)
EXAMPLE 3: (plot ds1)
EXAMPLE 4: (fill-template filter ds1-filtered ds1
(other (filter-and 'pitch (band-pass 65 75)
'rhythm (low-pass 100)))
'whatever t)
EXAMPLE 5: (show-text ds1-filtered)
EXAMPLE 6: (plot ds1-filtered)
EXAMPLE 7: (fill-template data-section ds2 100 50
(rv 1 2) (make-chord (rv 60 80) 4)
mf 1)
EXAMPLE 8: (fill-template filter ds2-filtered ds2
(other (filter-and 'rhythm (low-pass 100)
'pitch (band-pass 65 75)))
'whatever t)
EXAMPLE 9: (show-text ds2-filtered)
(filter-if if-parameter if-filter then-parameter then-filter)
Produces a filter that can be applied to sections. It allows filters to be applied to just some of the events. Other events are passed unfiltered.
IF-FILTER is applied to IF-PARAMETER. If it returns a value, THEN-FILTER is applied to THEN-PARAMETER. The result of applying THEN-FILTER is the result of this tool.
If applying IF-FILTER to IF-PARAMETER does not return a value, then the original event is passed without filtering.
Example 1 defines a section with 2 Midi channels.
Example 2 will check if the event is in channel 1. If that is the case, a band-pass filter is applied to pitch. If the pitch is within that range, it is passed. Otherwise it is rejected.
If the event was not in channel 1, it is passed without any additional filtering.
Examples 3-4 will print text versions of the section and the filtered section.
IF-PARAMETER and THEN-PARAMETER should be PITCH, VELOCITY, CHANNEL, or RHYTHM.
IF-FILTER and THEN-FILTER can be any filter suitable for use with a section, e.g. low-pass, high-pass, or band-pass.
FILTER-IF should be used in the FILTER method: choose OTHER as the filter type and WHATEVER as the parameter.
EXAMPLE 1: (fill-template data-section test1 100 20
(rv 1 2) (rv 60 80) mf '(1 2))
EXAMPLE 2: (fill-template filter test1f test1
(other (filter-if 'channel (value-pass 1)
'pitch (band-pass 65 75)))
'whatever t)
EXAMPLE 3: (show-text test1)
EXAMPLE 4: (show-text test1f)
(filter-or parameter filter ... parameter-N filter-N)
Produces a filter that can be applied to sections. A section event is passed if one of the filters meets its condition. A condition is a parameter such as pitch and a filter to apply to that parameter. As soon as a condition is met, FILTER-OR stops and does not check any other conditions.
This allows a filter to accept various possibilities, e.g. short notes or high pitches.
PARAMETER should be PITCH, VELOCITY, CHANNEL, or RHYTHM.
FILTER can be any filter suitable for use with a section, e.g. low-pass, high-pass, or band-pass.
Any number of parameter/filter pairs can be specified.
FILTER-OR should be used in the FILTER method: choose OTHER as the filter type and WHATEVER as the parameter.
Filters are tested from left to right.
Example 1 makes a section.
Example 2 prints a text version of that section.
Example 3 filters the section. Events with pitches >= 75 are allowed as are events with rhythms <= 100 (ms). Only one of the two conditions need be met. All other events are rejected.
EXAMPLE 1: (fill-template data-section ds1 100 50
(rc '(1 4)) (rv 40 80)
mf 1)
EXAMPLE 2: (show-text ds1)
EXAMPLE 3: (fill-template filter ds1-filtered ds1
(other (filter-or 'pitch (high-pass 75)
'rhythm (low-pass 100)))
'whatever t)
EXAMPLE 4: (show-text ds1-filtered)
(filter-stockpile stockpile filter)
Returns a list made by filtering STOCKPILE. STOCKPILE may be a list or stockpile. FILTER should be an expression such as:
(low-pass threshold)
(high-pass threshold)
(band-pass low high)
(band-reject low high)
(bank low1 high1 low2 high2 ...)
(shotgun percentage)
(pass-stockpile-filter stockpile)
(repetition-filter)
(pitch-class-filter stockpile)
(reject-pitch-class-filter stockpile)
or some other suitable filter expression
(see Help>Lisp>Your Own for information about making filters.)
The low-pass filter passes values <= 5 (example 1).
The repetition-filter removes repetitions (example 2).
The pass-stockpile-filter passes values contained in its list or stockpile (example 3).
The ANYTHING tool can be used to construct a filter expression (example 4). If the function returns a true value, the element from the stockpile is passed through.
Filters can be combined with the logical tools CONSTRAINT-AND and CONSTRAINT-OR. They can be negated with CONSTRAINT-NOT. Example 5 passes values outside the range 60-70 which are not a member of pitch-class 0 (e.g. 48, 72).
EXAMPLE 1: (print-result
(filter-stockpile '(1 2 3 4 5 6 7 8 9 10)
(low-pass 5)))
EXAMPLE 2: (print-result
(filter-stockpile '(1 2 2 3 3 4 4 5 6 7 8 9 10)
(repetition-filter)))
EXAMPLE 3: (print-result
(stockpile->notename
(filter-stockpile '(c#3 d3 f3 f#3 g3)
(pass-stockpile-filter
'(c3 f3 g3)))))
EXAMPLE 4: (print-result
(filter-stockpile (from 1 10)
(anything < 5)))
EXAMPLE 5: (print-result
(filter-stockpile (from 40 80)
(constraint-and (anything outside 60 70)
(constraint-not (pitch-class 0)))))
(find-range thing &key n chord parameter)
Returns a list with strings for the minimum and maximum values of THING. If THING is a generator, it is applied N times to find the range. N defaults to 1000 times.
THING can be a list, stockpile, generator, shape, section etc (examples 1-4).
If THING contains or produces elements that are lists (e.g. chords), the min and max value within the chords are determined. The keyword CHORD defaults to t and causes this behavior (example 5).
If CHORD is bound to nil, a range is returned for each position in the list (example 6).
When CHORD is bound to nil, all elements should have the same length. The primary use of binding CHORD to nil, is to return separate minimum and maximum values for each dimension in a multi-dimensional (chaotic) result (example 7).
If THING is a section, the pitch range will be returned. Example 8 assumes section1 exists.
The range of other section parameters can be found by binding the PARAMETER keyword to DURATION or VELOCITY (example 9).
Knowing the expected range is important if you are using the generator MAP/TIME which assumes you know the possible range of the input values. It is also useful with MAP-TRANSFORMER.
EXAMPLE 1: (for-example (find-range '(2 10 5 6)))
EXAMPLE 2: (for-example
(find-range (henon 0.0 0.0 1.4 0.3 1)))
EXAMPLE 3: (for-example
(find-range (henon 0.0 0.0 1.4 0.3 1) :n 20))
EXAMPLE 4: (for-example (find-range sine-shape))
EXAMPLE 5: (for-example
(find-range '((60 64 67) (67 34 88))))
EXAMPLE 6: (for-example
(find-range '((60 64 67) (67 34 88)) :chord nil))
EXAMPLE 7: (for-example
(find-range (henon 0.0 0.0 1.4 .3 1 :xy t) :chord nil))
EXAMPLE 8: (for-example (find-range section1))
EXAMPLE 9: (for-example (find-range section1 :parameter 'velocity))
(flatten list-or-stockpile)
Returns a list containing no inner parentheses. All nested lists are 'flattened' into a list with only one level (example 1).
Flatten works with lists or stockpiles.
EXAMPLE 1: (print-result (flatten '(a (b c) (d (e (f (g)))))))
(fm-chord c m i &key (round t) name (base 440.0) (block0 t) duplicates)
Returns a closure. When applied, a chord (expressed as a list of Midi note numbers) is returned. The chord contains a simulation of the process of frequency modulation (fm) using the carrier frequency C and the modulation frequency M. Both C and M are expressed as (floating-point) Midi note numbers.
FM-CHORD has some similarity to the generator RING-MODULATE-CHORD. In the later, the new chord will contain C + M and C - M. In FM-CHORD, any number of pairs of sidebands can be produced. I is an integer specifying the number of sets of sidebands which should be produced.
The sidebands will be C + M, | C - M |, C + 2M, | C - 2M |, ...
The Midi note numbers are converted to frequency values before the sidebands are calculated. Once calculated, the sideband frequencies are converted to Midi note numbers.
This generator reflects ideas present in the field of spectral composition. Gondwana by Tristan Murail is an example of a composition with chords made with a similar concept.
C and M should each be one (floating-point) Midi note number (examples 1-2). If a chord is specified as input, only the first value will be used.
The default value for ROUND is t. This will round off the resulting Midi note numbers to be integers. If real numbers are desired, ROUND should be bound to NIL (example 3). If ROUND is bound to another number, such as 0.5, the values will be quantized using that value. 0.5 rounds to quarter-tones (example 4).
Keyword NAME controls whether pitches are returned as numbers or as note names. When it is bound to T, note names are returned (printed) (example 5).
Keyword BASE is for specifying a reference frequency for Midi note number 69 (a4). It defaults to 440.0 Hz (example 6).
If C and M are the same number, the result of subtracting the values will be 0. If keyword BLOCK0 is bound to nil, 0 is an allowed result. (example 7). By default, BLOCK0 is bound to t and 0s are removed (example 8).
If keyword DUPLICATES is nil, duplicate values in the chord will be removed. This is the default case. When bound to t, duplicate values will be allowed (examples 9-10).
If frequencies should be input instead of Midi note numbers, use the generator HZ->MIDI to convert the values (example 11). The frequencies used in this example produce the first fm chord in Gondwana according to Dalbavie.
C, M, and I can vary over time (examples 12-14). They can be generators, lists, constants, etc.
To use the results of FM-CHORD as a list of pitches instead of a chord, FM-CHORD should be forced to return one value by using MAKE (example 15).
This list (made with MAKE) could be used as an input to another generator (example 16).
To use FM-CHORD to generate several lists of pitches which can be input to another generator, use SELECT-STOCKPILES (example 17). To understand this example you may need to consult the help for SELECT-STOCKPILES (example 18).
Chords can be filtered for repetitions and other intervals with CLEANUP-CHORD (example 19).
Chords can be combined into one chord with JOIN->CHORD (example 20).
Chords can be converted to a different range with CONVERT2 (examples 21-22).
EXAMPLE 1: (for-example (fm-chord 60 50 1)
:number 1)
EXAMPLE 2: (for-example (fm-chord 60 50 3)
:number 1)
EXAMPLE 3: (for-example (fm-chord 60 50 3 :round nil)
:number 1)
EXAMPLE 4: (for-example (fm-chord 60 50 3 :round 0.5)
:number 1)
EXAMPLE 5: (for-example (fm-chord 60.0 50.0 3 :name t)
:number 1)
EXAMPLE 6: (for-example (fm-chord 60 50 3 :base 415)
:number 1)
EXAMPLE 7: (for-example (fm-chord 60 60 3 :block0 nil)
:number 1)
EXAMPLE 8: (for-example (fm-chord 60 60 3)
:number 1)
EXAMPLE 9: (for-example (fm-chord 62 50 5 :duplicates t)
:number 1)
EXAMPLE 10: (for-example (fm-chord 62 50 5)
:number 1)
EXAMPLE 11: (for-example
(fm-chord (hz->midi 392) (hz->midi 207.65) 9
:round 0.5)
:number 1)
EXAMPLE 12: (fill-template data-section section1 1000 10
1 (fm-chord (from 60.0 69) 50 5) f 1)
EXAMPLE 13: (fill-template data-section section2 1000 10
1 (fm-chord 60 (from 50 59 :step 0.5) 5) f 1)
EXAMPLE 14: (fill-template data-section section3 1000 10
1 (fm-chord 60 50 (from 1 10)) f 1)
EXAMPLE 15: (fill-template data-section section4 200 50 1
(make (fm-chord 60 50 5))
f 1)
EXAMPLE 16: (fill-template data-section section5 200 50 1
(series-choice (make (fm-chord 60 50 5)))
f 1)
EXAMPLE 17: (fill-template data-section section6 200 50 1
(select-stockpiles 10 series-choice
(fm-chord (from 60.0 69) 50 5))
f 1)
EXAMPLE 18: (show-help 'select-stockpiles)
EXAMPLE 19: (show-help 'cleanup-chord)
EXAMPLE 20: (show-help 'join->chord)
EXAMPLE 21: (for-example (fm-chord (chromatic c4) c3 5)
:number-per-line 1 :number 10)
EXAMPLE 22: (for-example
(convert2 (fm-chord (chromatic c4) c3 5) 10 50 70)
:number-per-line 1 :recycle nil)
(fn &optional factor)
This tool is a shortcut for FROM-NUMBER.
It can be used when specifying input for sections and most Midi objects. It can also be used when creating Csound or OSC files.
It returns the number of events which have been specified or calculated for the NUMBER parameter of the object (example 1).
See the documentation for FROM-NUMBER for more information and examples (example 2).
EXAMPLE 1: (fill-template data-section data-section1 200
20 '(2 1)
(random-value c1 g#4)
(convert line-shape (fn) pp ff) 1 0)
EXAMPLE 2: (show-help 'from-number)
(follow shape object low high)
Returns a closure. A shape determines the 'shape' of the transformation. A SHAPE is adjusted to produce the same number of values as exist in OBJECT (that may be the name of a section, a community or just some number of values). The values of SHAPE will range between LOW and HIGH. These values will be used to multiply the values being transformed. This allows a transformation that changes over time following the shape of SHAPE.
SHAPE may be drawn or specified via the DEFINE menu. A shape may also be a list of numbers,a mask, or a generator.
If SECTION1 has been defined, it can be transformed with example 1.
Some standard shapes have been included in the AC Toolbox environment:
line-shape
sine-shape
expo-shape
line-shape provides an ascending line.
sine-shape is a sinusoidal motion.
expo-shape is an ascending exponential motion.
The shape could also just be a list of values:
(follow '(0 100) section1 1 5)
If SHAPE is a mask, random choices are made between the boundaries of the mask. If SECTION1 and MASK1 have been defined, section1 can be transformed with example 2
If SHAPE is a generator, the output of the generator (in whatever range it uses) is mapped to between the LOW and HIGH values of this transformer (example 3).
EXAMPLE 1: (fill-template transform section2 section1
:tempo (follow line-shape section1 1 5))
EXAMPLE 2: (fill-template transform section2 section1
:tempo (follow mask1 section1 1 5))
EXAMPLE 3: (fill-template transform section2 section1
:tempo (follow (random-value 0 100) section1 1 5))
fomus
FOMUS is a music notation formatting tool that can produce output suitable for the LilyPond notation program or for the MusicXML interchange format which can be read by Sibelius, Finale, and other programs.
The AC Toolbox expects FOMUS to be installed in /usr/local/bin which is where the FOMUS installer puts it. If LilyPond is chosen as the preferred output mode, it should be installed in the Applications folder.
FOMUS is available via SourceForge (example 1). The AC Toolbox menu item to write files in this format is 'File>Write FOMUS File'.
The AC Toolbox assumes that FOMUS version 0.1.10 or higher is installed.
EXAMPLE 1: (open-url "http://fomus.sourceforge.net/")
(for-example generator &key number number-per-line recycle)
Prints the results of applying the GENERATOR a NUMBER of times in a window. NUMBER-PER-LINE values are printed per line (example 1).
The default number of results is 20. This can be overridden by binding another value to the keyword NUMBER (example 2).
The default number of values per lines is 5. This can be overridden by binding another value to the keyword NUMBER-PER-LINE (example 3).
The primary use of this tool is in help windows which document the use of generators and tools.
If the RECYCLE keyword is bound to t, the example data is written to the previous example or show-transformation window (after erasing the previous data). This helps cut down on screen clutter. If the value is nil, a new window is made each time example data is requested.
The default behaviour for this keyword is specified in the Preferences dialog.
GENERATOR could also be a list, a stockpile, or a tool that produces a list (example 4).
EXAMPLE 1: (for-example (random-value 1 100))
EXAMPLE 2: (for-example (random-value 1 100) :number 50)
EXAMPLE 3: (for-example (random-value 1 100) :number-per-line 7)
EXAMPLE 4: (for-example (gather-until (random-value 1 5) 50))
(force-int &optional transformer)
Returns a closure that forces the result of the transformation to be an integer value (example 1).
If no TRANSFORMER is specified, the value to be transformed is returned as an integer value (example 2).
Lisp function round is used to force the value to be an integer.
EXAMPLE 1: (show-transformation
(force-int (transpose 12.5))
'(60 60.5 61 6.5))
EXAMPLE 2: (show-transformation
(force-int) '(60 60.5 61 61.5))
(force-mod mod &optional transformer)
Returns a closure that performs a modulo operation on the result of a transformation.
In example 1, the values 60, 64, and 67 are transposed by 1. The result, modulo 12 is returned.
In example 2, the values 60, 64, and 67 are inverted and returned modulo 12.
If no transformer is specified, the modulo operation is applied to the value being transformed. Example 3 returns the pitch values modulo 12. This is the pitch-class.
Modulo operations are sometimes used in connection with lists of pitch values or intervals.
EXAMPLE 1: (show-transformation (force-mod 12 (transpose 1))
'(60 64 67))
EXAMPLE 2: (print-result
(transform-stockpile '(60 64 67) (force-mod 12 (invert)))
EXAMPLE 3: (print-result
(transform-stockpile '(60 64 67) (force-mod 12))
(FREQ->SAMPLES FREQUENCY)
Intended for use when writing sound files (using the File>Write Sound File menu item). It returns the number of samples for a period with the specified FREQUENCY (examples 1-2).
The value for sample rate, specified in the options for the Write Sound File dialog, is used for the calculations.
More information about writing sound files can be found in the Index item 'Writing Sound Files'.
EXAMPLE 1: (print-result (freq->samples 100))
EXAMPLE 2: (fill-template write-sf
(sine (freq->samples 100) -10000 10000)
(seconds->samples 2))
(frequency-shift-chord chord offset &key round name base)
Returns a closure. When applied, a chord (expressed as a list of Midi notenumbers) is returned. The chord contains a simulation of frequency shifting each pitch of CHORD by a frequency OFFSET specified in Hz.
OFFSET is added to the frequency equivalent of each pitch in CHORD. The result is converted to Midi note numbers.
This generator reflects ideas present in the field of spectral composition.
CHORD can be a list, stockpile, a generator that produces a list, etc. (example 1).
Example 2 produces a table of the frequency equivalents of all Midi notenumbers.
Example 3 shows the frequency equivalent of one notenumber, e.g. 60.
Example 4 shows the note number closest to a certain frequency, e.g. 100 Hz.
CHORD and OFFSET may change over time (examples 5-6).
The default value for ROUND is t. This will round off the Midi note numbers to be integers. If real numbers are desired, ROUND should be bound to NIL (example 7). If ROUND is bound to another number, such as 0.5, the values will be quantized using that value. 0.5 rounds to quarter-tones (example 8).
Keyword NAME controls whether pitches are printed as numbers or as note names. When it is bound to T, note names are printed (example 9).
When note names are printed, pitches can be printed with the digits after the decimal point by binding ROUND to nil (example 10).
Keyword BASE is for specifying a reference frequency for Midi note number 69 (a). It defaults to 440.0 Hz (example 11).
Chords can be filtered for repetitions and other intervals with CLEANUP-CHORD (example 12).
Chords can be combined into one chord with JOIN->CHORD (example 13).
Chords can be converted to a different range with CONVERT2 (example 14).
EXAMPLE 1: (for-example
(make (frequency-shift-chord '(60 64 67) 100)))
EXAMPLE 2: (show-midi->hz)
EXAMPLE 3: (for-example
(make (midi->hz 60)))
EXAMPLE 4: (for-example
(make (hz->midi 100 :round t)))
EXAMPLE 5: (for-example
(frequency-shift-chord (make-chord (walk 60 3) 3) 100)
:number-per-line 1 :number 3)
EXAMPLE 6: (for-example
(frequency-shift-chord '(60 64 67) '(100 200 300))
:number-per-line 1 :number 3)
EXAMPLE 7: (for-example
(make (frequency-shift-chord
'(60 64 67) 100 :round nil)))
EXAMPLE 8: (for-example
(make (frequency-shift-chord
'(60 64 67) 100 :round 0.5)))
EXAMPLE 9: (for-example
(make (frequency-shift-chord
'(60 64 67) 100 :name t)))
EXAMPLE 10: (for-example
(make (frequency-shift-chord
'(60 64 67) 100 :round nil :name t)))
EXAMPLE 11: (for-example
(frequency-shift-chord '(60 64 67) '(100 200 300)
:base 415)
:number-per-line 1 :number 3)
EXAMPLE 12: (show-help 'cleanup-chord)
EXAMPLE 13: (show-help 'join->chord)
EXAMPLE 14: (show-help 'convert2)
(from begin end &key type step)
Returns a a sequence of values from BEGIN to END. Default output type is a list. Default for STEP is 1 (examplse 1-2).
Example 3 uses a step of 0.5.
BEGIN, END, and STEP can be generators. The generator will be applied once to determine a value (example 4).
To return a vector instead of a list, bind the keyword TYPE to vector (example 5).
Note that there can be floating point deviations in the values if the step size is a floating point number. If this is a problem, a possible solution is to express the step size as a rational number such as 1/10 instead of .1 (examples 6-7).
When BEGIN > END, the step size should be a positive number (example 8).
EXAMPLE 1: (for-example (from 40 80))
EXAMPLE 2: (for-example (from 10 1))
EXAMPLE 3: (for-example (from 1 10 :step 0.5))
EXAMPLE 4: (for-example
(from (random-value 1 20) (random-value 1 20)))
EXAMPLE 5: (print-result (from 40 50 :type 'vector))
EXAMPLE 6: (print-result (from 0 1 :step .1))
EXAMPLE 7: (print-result (from 0 1 :step 1/10))
EXAMPLE 8: (print-result (from 10 1 :step .5))
(from-layers)
This tool can be used when creating Csound or OSC files. It returns the number of layers that have been specified or calculated for the LAYERS parameter. It is a convenient way to use the number of layers in another parameter (example 1).
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
In object score1, the value of the p4 parameter, which in some instrument could be the amplitude parameter, is scaled by the number of layers. If the number of layers is changed in the specification (or is the result of applying a generator), the correct value for the number of layers is available for use in the P4 parameter.
Amplitude scaling can also be done with the tool SCALE-BY-LAYERS.
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 5 100 1 0 (random-value .1 .2)
(/ 1.0 (from-layers))
(random-value 100.0 1000))
(from-number &optional factor)
This tool can be used when specifying input for sections and most Midi objects. It can also be used when creating Csound or OSC files.
It returns the number of events that have been specified or calculated for the NUMBER parameter of the object.
It is a convenient way to use the number of notes in a different parameter. If you change the number of notes, the value in the other parameters also change (example 1).
Optionally, a value can be given to FACTOR. If it is a number, the number of notes is multiplied by that value. The result is always an integer (example 2).
If the number of notes is unknown at the moment that the specification is made, (from-number) will return the calculated number (examples 3-6).
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
The shortcut for FROM-NUMBER is FN.
EXAMPLE 1: (fill-template data-section data-section1 200
20 '(2 1)
(random-value c1 g#4)
(convert line-shape (from-number) pp ff) 1 0)
EXAMPLE 2: (fill-template data-section data-section2 200
40 1
(convert sine-shape (from-number .5) c1 g#4)
f 1 0)
EXAMPLE 3: (fill-template data-section data-section3 200
(until-time 10) '(2 1)
(random-value c1 g#4)
(convert line-shape (from-number) pp ff) 1 0)
EXAMPLE 4: (fill-template data-section data-section4 200
(random-value 20 50) '(2 1)
(random-value c1 g#4)
(convert line-shape (from-number) pp ff) 1 0)
EXAMPLE 5: (fill-template density-curve-section density-curve1
20 expo-shape 1 50 1
(random-value 100 200)
(walk c3 (random-value -5 5) c1 c#5)
(convert line-shape (from-number) pp ff) 1)
EXAMPLE 6: (fill-template osc-score-object osc-score1
(until-time 10) "sine1" nil nil nil 1 0
"dur" (random-value 0.1 0.2)
"amp" 0.3
"freq" (convert line-shape (from-number) 200.0 800))
(from-overlap)
This tool is intended to be used together with the OVERLAP generator when producing Csound or OSC files. When OVERLAP has been used, a list of duration values is generated so that the overlap in start times may be calculated. This list can be recovered using from-overlap.
When the START parameter of a Csound score dialog or an OSC score object contains OVERLAP, the DURATION parameter of that Csound score dialog should use (from-overlap) (example 1).
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
Example 2 produces an OSC score using FROM-OVERLAP.
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8192 10 1
f2 0 8192 20 2 1"
nil nil 1 10 1
(overlap 0 (random-value 0.5 1.5) 0.25)
(from-overlap) 0.5
(random-value 100.0 1000))
EXAMPLE 2: (fill-template osc-score-object osc-score1 10 "sine1"
NIL NIL NIL 1
(OVERLAP 0 (RANDOM-VALUE 0.5 1.5) 0.25)
"dur" (FROM-OVERLAP) "amp" 0.5
"freq" (RANDOM-VALUE 100.0 1000))
(from-start-times)
This tool can be used when specifying input for Csound or OSC files.
It should only be used in combination with the tool DENSITY-OF-START-TIMES.
(from-start-times) should be the input for NUMBER when DENSITY-OF-START-TIMES is used as input to START. This is the only intended use for this tool.
(from-start-times) will return the total number of events calculated with DENSITY-OF-START-TIMES (example 1). Any other expressions needing to know the number of values should use (from-number).
Example 1 can be rendered with test csound.orc in Support/FileExamples.
FROM-START-TIMES can be abbreviated as FST.
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8192 20 2 1" nil nil 1
(from-start-times) 1
(density-of-start-times
10 line-shape 1 10)
(random-value 0.5 1)
0.1
(random-value 220 880))
(fst)
This tool is a shortcut for FROM-START-TIMES. It can be used with Csound or OSC files.
It should be used in combination with DENSITY-OF-START-TIMES or the shortcut, DENSITY (example 1).
See the documentation for DENSITY-OF-START-TIMES for additional information (example 2).
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8192 20 2 1" nil nil 1
(fst) 1
(density
10 line-shape 1 10)
(rv 0.5 1)
0.1
(rv 220 880))
EXAMPLE 2: (show-help 'from-start-times)
(function-of-x function &key low-x high-x number)
Returns a closure. When applied, a value is returned which is the result of using X in a function.
FUNCTION should be a Lisp expression which contains the symbol X. Each time the generator is applied, the value of X changes which could result in a different output from the generator (examples 1-2).
By default, X will receive values in the range 0 - 1. The lower limit can be changed by binding a new value to the keyword LOW-X. The upper limit can be changed by binding a value to the keyword HIGH-X (examples 3-7).
Example 8 is a somewhat more complex function, used in Crux by Simon Cummings.
The keyword NUMBER controls the number of different values X will receive. The default value is 100. This means that after 100 values, X will return to LOW-X and the series will repeat (example 9).
This generator could be used, for example, to generate shapes or to produce lists using CONVERT (examples 10-11).
EXAMPLE 1: (plot (function-of-x (* x x)))
EXAMPLE 2: (plot (function-of-x (sin (* 2 pi x))))
EXAMPLE 3: (plot (function-of-x (sin x)))
EXAMPLE 4: (plot (function-of-x (sin x) :low-x -5 :high-x 5))
EXAMPLE 5: (plot (function-of-x (exp x)))
EXAMPLE 6: (plot (function-of-x (exp x) :low-x -5 :high-x 5))
EXAMPLE 7: (plot (function-of-x (* x x) :low-x -3 :high-x 3))
EXAMPLE 8: (plot (function-of-x (+ (* 0.714285714 x)
(* 2.3 (sin (expt x 2.19))))
:low-x 0. :high-x 5))
EXAMPLE 9: (plot (function-of-x (sin x) :number 50))
EXAMPLE 10: (fill-template generate-shape shape1 100
(function-of-x (sin x)))
EXAMPLE 11: (for-example
(convert (function-of-x (sin x) :number 10) 10 1 10))
(funnel list)
Returns a closure that forces the value being transformed to be one of the values included in the LIST. LIST may be a list or stockpile. If a value is equidistant between two values in LIST, a random choice is made between the values (example 1).
The values in the funnel can be floating-point numbers (example 2).
The idea for this transformer was adapted from the sieve funnel in AthenaCL (example 3).
Example 4 shows a sieve segment that is the union of two sieves.
This sieve segment can be used with funnel (example 5)
See the help for the tool SIEVE for more information about sieves.
EXAMPLE 1: (show-transformation
(funnel '(1 3 5 7 9))
'(1 2 3 4 5 6 7 8 9 10))
EXAMPLE 2: (show-transformation
(funnel (from 60.0 65. :step .5))
(convert line-shape 20 60.0 65))
EXAMPLE 3: (open-url "http://www.athenacl.org")
EXAMPLE 4: (for-example
(sieve-union (sieve 3 40 40 80)
(sieve 4 40 40 80)))
EXAMPLE 5: (for-example
(transform/time
(random-value 40 80)
(funnel (sieve-union (sieve 3 40 40 80)
(sieve 4 40 40 80)))))
(gather-until input total &optional clock-unit always-less min stop)
Returns a list of values whose combined absolute values are = TOTAL. One use of this is to fill a metric unit with various values.
In the default situation, as soon as TOTAL has been reached (or just exceeded) no more values are added to the list.
INPUT can be a constant, a list, or a generator (examples 1-4).
If the sum of the values returned by GATHER-UNTIL should always be <= to TOTAL (but never exceeding it), ALWAYS-LESS should be bound to t (examples 5-6). Note that if no CLOCK-UNIT is specified, a nil should be entered before the value for ALWAYS-LESS.
When ALWAYS-LESS is true, INPUT will be queried a number of times to see if there is another value which will fit. This happens STOP number of times (example 7). The default value for STOP is 500. It can be replaced with another value (example 8).
To speed up the process when ALWAYS-LESS is true, a value for MIN can be specified. If the distance between the current total of values in the list to be returned is less than the value of MIN, the current list is returned (example 9) without looking for any other possible values.
If the optional parameter CLOCK-UNIT is specified, TOTAL is considered to be a time in seconds instead of any other unit such as beats. INPUT values will be considered to be multiples of the CLOCK-UNIT. GATHER-UNTIL will gather until that amount of time has been filled (example 10). To demonstrate the way that CLOCK-UNIT works, example 10 is rewritten using multiples of 150 ms as the input values and 5000 ms for the total (example 11).
EXAMPLE 1: (for-example (gather-until (random-value 1 5) 50))
EXAMPLE 2: (for-example (gather-until '(1 2 4) 40))
EXAMPLE 3: (for-example (gather-until (split 96 6 .6 2) (* 10 96)))
EXAMPLE 4: (for-example (sum (gather-until 3 20)))
EXAMPLE 5: (for-example (gather-until 3 20 nil t))
EXAMPLE 6: (for-example (sum (gather-until 3 20 nil t)))
EXAMPLE 7: (for-example (gather-until '(1 2) 11 nil t))
EXAMPLE 8: (for-example (gather-until (rc '(1 2)) 11 nil t nil 100))
EXAMPLE 9: (for-example (gather-until (rc '(333 666)) 1000 nil t 333))
EXAMPLE 10: (for-example (gather-until '(1 2 4) 5 150))
EXAMPLE 11: (for-example (gather-until '(150 300 600) 5000))
(gaussian-choice sequence standard-deviation mean)
Returns a closure. When applied, it returns one element of the sequence. The index for that element is chosen according to a Gaussian distribution. Both the STANDARD-DEVIATION and the MEAN should be expressed as index values (relative to the sequence) (example 1).
STANDARD-DEVIATION and MEAN may vary over time.
EXAMPLE 1: (for-example (gaussian-choice '(a b c d e f g h i) 3 5))
(gaussian-value standard-deviation mean
lower-boundary upper-boundary
&key conversion round)
Returns a closure. When applied, it returns a number according to a Gaussian distribution. Most (ca. 68%) of the results will occur within ą STANDARD-DEVIATION from the MEAN. To keep things under control a bit, all values < LOWER-BOUNDARY or > UPPER-BOUNDARY are discarded (examples 1-3).
The values for LOW and HIGH determine the type of output (examples 4-5).
Results can be quantized by binding a quantization unit to ROUND (example 6).
Another way to convert results to integers is by binding a Lisp conversion function to the keyword CONVERSION (example 7). Before AC Toolbox 4.5.3, the standard behavior for this generator was to have conversion default to TRUNCATE and therefore all output was by default truncated. This behavior is demonstrated in example 7.
If both ROUND and CONVERSION are specified, ROUND takes precedence.
STANDARD-DEVIATION, MEAN, LOWER-BOUNDARY and UPPER-BOUNDARY may vary over time.
EXAMPLE 1: (for-example (gaussian-value 5 50 40 60))
EXAMPLE 2: (make-histogram (gaussian-value 10 50 1 100)
:number 1000)
EXAMPLE 3: (plot (gaussian-value 5 50 20 80))
EXAMPLE 4: (for-example (gaussian-value 5 50 40 60))
EXAMPLE 5: (for-example (gaussian-value 5 50 40.0 60))
EXAMPLE 6: (for-example
(gaussian-value 5 50 40.0 60 :round 0.25))
EXAMPLE 7: (for-example
(gaussian-value 5 50 40.0 60
:conversion #'truncate))
general midi
In addition to using Midi objects to control a General Midi device, instruments can be assigned to Midi channels via Other>General Midi. This Midi setup can be saved via File>Save GM Selections and loaded at some other time via File>Load GM Selections.
(generate tool)
Returns a closure. When applied, the tool (or Lisp expression) is evaluated and the result is returned.
This generator in fact converts a tool into the form necessary to be used as a generator.
TOOL can be an AC Toolbox tool or some valid Lisp expression.
ALEA is a tool that returns a random value between two limits. It is not a generator and can therefore not be used with FOR-EXAMPLE to generate several values (example 1).
By enclosing it within a GENERATE expression, this would be possible (example 2).
Other simple examples are (examples 3-5).
An example using a controller.
The basic idea is to define a controller that will produce a value and a generator that will return the negative version of that value. TAKE will be used to produce one value from the controller and then the negative value from the generator.
Define the controller (example 6)
Note that the controller could be also be defined using the dialog produced by the Controller menu item.
To generate the value from the controller and then the negative value from the generator see (example 7).
EXAMPLE 1: (for-example (alea 1 100))
EXAMPLE 2: (for-example (generate (alea 1 100)))
EXAMPLE 3: (for-example (generate 10))
EXAMPLE 4: (for-example (generate '(1 2 3)))
EXAMPLE 5: (for-example (generate (+ 2 2)))
EXAMPLE 6: (define cont1 (make-controller '(1 2 3 4)))
EXAMPLE 7: (for-example
(take 1 (do-the-next-thing cont1)
1 (generate (- (get-most-recent cont1)))))
generate parallel section
The dialog box produced by this menu item allows variants of one or more sections to be made and then combined in parallel.
Example 1 creates a section to vary.
Example 2 generates a parallel section using this section.
In example 2, three variants will be made of section DS1 and these variants will be combined in parallel. In this case, a variant is a new section using the input data of a previous one. The offset time is 0 which means that all variants will start together.
The first variant always starts at time 0. Subsequent variants can start later if the offset parameter produces a value > 0. Offset time is expressed in seconds (example 3).
Sometimes it is useful to remake stockpiles (or other objects) before making a variant of a section.
Example 4 makes a stockpile to determine the rhythm values for the section in example 5.
Example 6 calculate new rhythmic values for each layer in the parallel section:
A generator can be used to determine which sections should be varied (example 7).
In example 7, five layers will be produced. For each layer, a choice will be made between varying ds1 or ds2.
EXAMPLE 1: (fill-template data-section
ds1 100 30
(random-value 1 5)
(random-value 40 80)
(beta-value 60 100 .2 .1) 1)
EXAMPLE 2: (fill-template new-generate-parallel-section
parallel1 3 0 ds1
nil nil nil nil)
EXAMPLE 3: (fill-template new-generate-parallel-section
parallel2 3
(random-value 0.0 5) ds1
nil nil nil nil)
EXAMPLE 4: (fill-template generate-stockpile
st 30 (random-value 1 5))
EXAMPLE 5: (fill-template data-section
ds2 100 30
st (random-value 40 80)
(beta-value 60 100 .2 .1) 1)
EXAMPLE 6: (fill-template new-generate-parallel-section
parallel3 3 0 ds2 st
nil nil nil)
EXAMPLE 7: (fill-template new-generate-parallel-section
parallel4 5
(random-value 0.0 5)
(random-choice '(ds1 ds2))
st nil nil nil)
generate sequential section
The dialog box produced by this menu item allows variants of one or more sections to be made and then combined in sequence.
Example 1 creates a section to vary.
Examples 2-3 generate sequential sections using this section.
Three variants will be made of section DS1 and these variants will be combined in sequence. In this case, a variant is a new section using the input data of a previous one. The offset time is 0 which means that each variant will start immediately after the previous one is finished.
The first variant always starts at time 0. Between subsequent variants there can be a time delay if offset produces values > 0. Offset time is expressed in seconds.
Sometimes it is useful to remake stockpiles (or other objects) before making a variant of a section.
The stockpile in example 4 is used to determine the rhythmic values for a section (example 5).
Example 6 calculates new rhythmic values for each layer in the sequential section.
A generator can be used to determine which sections should be varied (example 7).
In example 7, 5 variants will be produced. For each variant, a choice will be made between varying ds1 or ds2. A time delay will occur between each variant.
EXAMPLE 1: (fill-template data-section
ds1 100 30
(random-value 1 5)
(random-value 40 80)
(beta-value 60 100 .2 .1) 1)
EXAMPLE 2: (fill-template generate-sequential-section
sequential1 3 0 ds1
nil nil nil nil)
EXAMPLE 3: (fill-template generate-sequential-section
sequential2 3
(random-value 1.0 3)
ds1 nil nil nil nil)
EXAMPLE 4: (fill-template generate-stockpile
st 30 (random-value 1 5))
EXAMPLE 5: (fill-template data-section
ds2 100 30
st (random-value 40 80)
(beta-value 60 100 .2 .1) 1)
EXAMPLE 6: (fill-template generate-sequential-section
sequential3 3 1 ds2 st
nil nil nil)
EXAMPLE 7: (fill-template generate-sequential-section
sequential4 5
(random-value 1.0 3)
(random-choice '(ds1 ds2))
st nil nil nil)
generate-average (generator &key (number 5) round)
Returns a closure. When applied, the next NUMBER of values produced using GENERATOR are averaged (example 1). By default, ROUND is nil. The result is not rounded.
ROUND can also be bound to a different unit (examples 2-3).
This is a simple and easy way to realize a few different statistical distributions.
A triangle distribution is the average of two numbers (example 4).
Some people realize a Gaussian distribution by averaging 3 or more values (example 5).
Both example 4 and 5 make a histogram of 1000 values to demonstrate the distribution.
GENERATOR can be a generator, list, stockpile, etc.
The default value for NUMBER is 5.
A related tool for calculating an average value is AVERAGE (example 6).
EXAMPLE 1: (for-example
(generate-average (random-value 1 10)))
EXAMPLE 2: (for-example
(generate-average (random-value 1 10) :round 1))
EXAMPLE 3: (for-example
(generate-average (random-value 1 10) :round 0.5))
EXAMPLE 4: (make-histogram
(generate-average (random-value 1 100) :number 2)
:number 1000)
EXAMPLE 5: (make-histogram
(generate-average (random-value 1 100))
:number 1000)
EXAMPLE 6: (show-help 'average)
(generate-diversity number generator &key pitch-class (stop 1000))
Returns a list of values produced by the GENERATOR. Values are added to the list until the desired amount of diversity (measured in the number of different values) is reached. NUMBER refers to the number of different values that should be present before generation stops (examples 1-2).
If diversity should be measured in terms of pitch-classes, bind the keyword PITCH-CLASS to t (example 3).
This tool could be used for instance to generate rhythmic loops that can contain a certain number of different values. It also could construct pitch sequences with a certain number of different pitch-classes present.
The user is responsible for ensuring that the generator that is used is capable of producing the desired amount of diversity. If that is not possible after STOP number of tries, the execution will abort and an error message will appear. The default value for STOP is 1000.
EXAMPLE 1: (for-example (generate-diversity 5 (random-value 1 12)))
EXAMPLE 2: (for-example (generate-diversity 5
(random-choice '(c3 c4 d#3 d2 d#5 b2 b3 b4 a5))))
EXAMPLE 3: (for-example (generate-diversity 5
(random-choice '(c3 c4 d#3 d2 d#5 b2 b3 b4 a5))
:pitch-class t))
(generate-line start n end &key exponential curve round disjunct add min max)
Returns a closure. When applied, a point on a line between START and END is returned. The first point will be START. The next point will move along the line so that the Nth point will be END. The interpolation between START and END is linear (by default) but can also be set to exponential.
After N points have been produced, a new value for N and a new value for END are generated. Points will be produced between the current value and the new value for END. Then a new value for N and a new value for END are produced. And so on. The minimum value for N is 2.
If START is nil, an interpolation of N values occurs between numbers produced by END (which may be a stockpile).
If DISJUNCT is bound to t, both a new start and end value are generated each time.
Both N and END can vary over time and therefore can be constants, lists, stockpiles, generators, etc.
In the default case, the value for START is only used once but can also be a constant, generator, etc. When DISJUNCT is true, START will produce a new value for each line segment.
A deviation from the generated line can be made by binding a generator to ADD. The deviation can be limited by values for MIN and MAX.
In example 1, 10 values between 1 and 10 are produced. Remaining values are on the line from 10 to 10.
In example 2, 10 values between 1 and 10 are produced. Then 10 values between 10 and 5.
If the value for START and/or END are floating point numbers, the output will be floating point numbers. Otherwise the values will be rounded to integers (example 3).
To quantize the result with another unit, bind ROUND to a quantization unit (example 4).
If more values are desired and END is a list or stockpile, the generator will loop through the list (example 5).
END can also be a generator. Each time a new value for the end of the line is needed, the generator will be applied (example 6).
N can be a generator. Each time a new value for the number of values is needed, the generator will be applied (example 7).
If the keyword EXPONENTIAL is t, the interpolation between the values will be exponential (example 8). In this case, the value for the curve is 2.
Keyword CURVE controls the 'steepness' of the curve. Any positive value may be used for CURVE. When a value is bound to CURVE, it is not necessary to bind EXPONENTIAL to t (examples 9-10).
If START is bound to nil, the first value for the line will be the first value returned from END. If END is a list or stockpile, an interpolation between the values in the stockpile will occur (example 11). If END is a function, it will be applied to produce the starting value (the first time) and then the end value(s) (example 12).
When the keyword DISJUNCT is t, a new start position is calculated for each segment. The new segment does NOT start where the previous one left off (examples 13-14).
Keyword ADD can be bound to a generator, list, stockpile, constant, etc. The value is added to the line. For example, it could be used to produce a deviation from the generated line (example 15).
In example 16, GENERATE-LINE produces pitches in a data section. ADD produces a deviation from the generated line in the range ą5 semitones.
When ADD is used, numbers can be specified for MIN and/or MAX. If a value is produced lower than MIN, a new value is made. If a value higher than MAX is produced, a new value is made. If a value in the range specified by MIN-MAX cannot be made in 100 tries, the value is clipped according to the specification for MIN and MAX. If MIN is not provided, no check will be made for the lower limit. If MAX is not provided, no check will be made for the upper limit (examples 17-19). MIN and MAX can vary over time. Note this use of a line with deviation within a specified range is similar to the approach described by James Tenney in his article Computer Music Experiences, 1961-1964.
GENERATE-LINE can also be used to produce a continuous series of mask segments. To do that, one generator should be used for the bottom line of the mask and another generator for the top line. The two generators can then be used as the arguments for random-value (example 20). The difference with example 16 is that in example 20, the distance between the lines could contract and expand. In example 16, the deviation was always within a fixed range.
GENERATE-LINE can be abbreviated to GL (example 21).
A simpler generator, LINE, can be used to produce N values between A and B (examples 22-23).
Line segments can be specified with PIECEWISE (example 24).
EXAMPLE 1: (for-example (generate-line 1 10 10))
EXAMPLE 2: (for-example (generate-line 1 10 '(10 5)))
EXAMPLE 3: (for-example (generate-line 1.0 10 '(10 5)))
EXAMPLE 4: (for-example (generate-line 1.0 20 40 :round 0.5))
EXAMPLE 5: (for-example
(generate-line 1.0 10 '(10 5))
:number 40)
EXAMPLE 6: (plot
(generate-line 1.0 10 (random-value 10 20)))
EXAMPLE 7: (plot
(generate-line 1.0 (random-value 5 20)
(random-value 1 20)))
EXAMPLE 8: (plot
(generate-line (random-value 1.0 5)
(random-value 5 10)
(random-value 1 10)
:exponential t))
EXAMPLE 9: (plot
(generate-line 1.0
25
'(10 7 2 1)
:exponential t))
EXAMPLE 10: (plot
(generate-line 1.0
25
'(10 7 2 1)
:curve 4))
EXAMPLE 11: (for-example (generate-line nil 5 '(1 20 5 10)))
EXAMPLE 12: (plot (generate-line nil 10 (rv 1 100)))
EXAMPLE 13: (plot
(generate-line (rv 1 100) 10 (rv 1 100)
:disjunct t))
EXAMPLE 14: (plot
(generate-line (rv 1 100.0) (rv 5 20) (rv 1 100)
:disjunct t :exponential t))
EXAMPLE 15: (plot
(generate-line (rv 1 50.0) (rv 5 20) (rv 1 50)
:add (random-value -5.0 5)))
EXAMPLE 16: (fill-template
data-section test1 100 400 1
(generate-line (random-value c2 g#5)
(random-value 5 30)
(random-value c2 g#5)
:exponential t
:add (random-value -5 5))
mf 1 0)
EXAMPLE 17: (for-example
(generate-line 1.0 10 10 :add (rv -1.0 1) :min 1 :max 10))
EXAMPLE 18: (for-example
(generate-line 1.0 10 10 :add (rv -1.0 1) :min 1))
EXAMPLE 19: (for-example
(generate-line 1.0 10 10 :add (rv -1.0 1) :max 10))
EXAMPLE 20: (fill-template
data-section test2 100 400 1
(random-value
(generate-line (random-value c2 g#5)
(random-value 40 80)
(random-value c2 g#5)
:exponential t)
(generate-line (random-value c2 g#5)
(random-value 40 80 )
(random-value c2 g#5)
:exponential t))
mf 1 0)
EXAMPLE 21: (plot (gl 1.0 (rv 5 20) (rv 1 20)))
EXAMPLE 22: (for-example (line 20 1 20))
EXAMPLE 23: (show-help 'line)
EXAMPLE 24: (show-help 'piecewise)
(generate-range generator limit &key stop)
Returns a list of values created by applying the generator until a certain limit has been reached.
This could be useful for constructing scales where the generator would be an existing scale generator, such as major or melodic minor, or a user-defined scale defined with the tool define-scale (examples 1-3).
Other generators can be applied until the LIMIT is reached (example 4).
The user is responsible for GENERATOR being able to reach LIMIT. If this tool has not been able to do that after STOP attempts, an error message occurs. STOP could be bound to a higher value if desired (example 5).
EXAMPLE 1: (for-example (generate-range (major 36) 72))
EXAMPLE 2: (define my-scale (define-scale '(1 2 2 1)))
EXAMPLE 3: (for-example (generate-range (my-scale c1) c4))
EXAMPLE 4: (for-example (generate-range (prime-number) 100))
EXAMPLE 5: (for-example (generate-range (always 1) 100))
(generate-scale first intervals)
Returns a closure. When applied, FIRST is returned. Then an interval produced by INTERVALS is added to FIRST. Another interval is produced and added to the previous result. Etc.
INTERVALS would typically be a list and represent the intervals in a scale (examples 1-2).
EXAMPLE 1: (for-example (generate-scale 60 '(2 2 1 2 2 2 1)))
EXAMPLE 2: (for-example (midi->notename
(generate-scale c3 '(2 2 1 2 2 2 1))))
(generate-sf-name generator)
Returns a closure. When applied, the GENERATOR will choose among possible soundfile names which then will be adjusted to be in the appropriate format for a Csound score file.
If the file is a sound file, it should be in the sample directory. If it is an analysis file, it should be in the analysis directory.
In example 1, random-choice is the generator choosing from the list of two possible soundfile names. Each soundfile name should be a string (enclosed in double quotes). Replace "sax1" and "harry" with the names of files found in your sample directory.
The examples in this help text can be rendered using 'test csound.orc' found in 'Support/FileExamples'.
GENERATOR may be a generator, stockpile, list, etc. (example 2). It should not be just a string reflecting one file name. Use SF-NAME for that case.
If the choice of sound file is generated and a different duration is desired based on that choice, the following steps could be taken:
1. Make a stockpile choosing the sound files (example 3).
2. Make a lookup table with the file names and durations (example 4).
3. Use these two stockpiles in the csound score description (example 5).
The shortcut for GENERATE-SF-NAME is GSF.
EXAMPLE 1: (fill-template csound-score-object score1
"" nil nil 1 10 3 0
(random-value .5 1)
(generate-sf-name
(random-choice '("sax1" "harry")))
0 1 .01 .01)
EXAMPLE 2: (fill-template csound-score-object score1 ""
nil nil 1 10 3 0
(random-value .5 1)
(generate-sf-name '("sax1" "harry"))
0 1 .01 .01)
EXAMPLE 3: (fill-template generate-stockpile stock1 10
(random-choice '("sax1" "flute")))
EXAMPLE 4: (fill-template construct-stockpile table1
(make-lookup-table
"sax1" 10.33 "flute" 9.66))
EXAMPLE 5: (fill-template csound-score-object score1 ""
nil nil 1 10 3 0
(lookup stock1 table1)
(generate-sf-name stock1)
0 1 .01 .01)
(generate-sum expression &optional (number 5))
Returns a closure. When applied, the next NUMBER of values from EXPRESSION are added and the sum is returned.
NUMBER has the default value of 5. Example 1 adds 5 outputs from the generator (random-value 1 10).
Example 2 adds 20 outputs of the generator.
If EXPRESSION is a list, the first NUMBER of values from the list are summed, then the next NUMBER are summed, etc. (example 3).
EXPRESSION can change over time.
A different way to produce a sum is discussed in the help for the tool SUM.
EXAMPLE 1: (for-example (generate-sum (random-value 1 10)))
EXAMPLE 2: (for-example (generate-sum (random-value 1 10) 20))
EXAMPLE 3: (for-example (generate-sum (from 1 10)))
generators
A generator is a function which returns the next value in some series each time it is used. A generator for producing increasing integers would return the value 1 the first time it is used, then 2, then 3, ... A generator for producing Midi note numbers for a major scale starting with 60 (c4) would return 60, then 62, 64, 65, 67, etc.
Generators tend to have one of two suffixes.
Value means values will be produced between two limits (a bandwidth), e.g. (random-value 1 100) would produce a value in the range between 1 and 100.
Choice means values will be chosen from an available supply of values, e.g. from a list. (random-choice Ô(a b c d e)) chooses a value from the list Ô(a b c d e).
Individual help windows for each generator are available via the Annotated Index or the Index.
(get-intervals stockpile &key first between)
Returns the list of intervals. By default, the intervals are from the first value to each other value in STOCKPILE. STOCKPILE may be a list or stockpile (examples 1-2).
If the first interval (between the first value and itself) should be included, bind the keyword FIRST to t (example 3). This faciliates the derivation of pitch sets.
Alternatively, the intervals between each value in STOCKPILE can be returned. In that case, BETWEEN should be bound to t (example 4). If both FIRST and BETWEEN are bound to t, BETWEEN takes precedence and FIRST is ignored.
EXAMPLE 1: (for-example (get-intervals '(60 64 67)))
EXAMPLE 2: (for-example (get-intervals '(c4 e4 g4)))
EXAMPLE 3: (for-example (get-intervals '(60 64 67) :first t))
EXAMPLE 4: (for-example (get-intervals '(60 64 67) :between t))
(get-length object)
Returns the number of elements, objects, or points in some AC Toolbox object (example 1).
STOCKPILE: the number of values is returned.
SECTION: the number of separate start times is returned.
COMMUNITY: the number of sections or communities in this one.
SHAPE: the number of points defining the shape.
NOTE STRUCTURE: the number of notes in a structure. Rests are not counted.
EXAMPLE 1: (print-result (get-length wilhelmus))
(get-most-recent controller)
Returns the most recent value that a controller has produced. If none has been produced, the controller is applied to produce a value.
(get-object-duration object &key seconds)
Returns the duration of a section or community in milliseconds (examples 1-2).
Bind the keyword SECONDS to t to return a value in seconds (example 3).
EXAMPLE 1: (fill-template data-section ds1 100 100 1 (rv 40 80) f 1)
EXAMPLE 2: (print-result (get-object-duration ds1))
EXAMPLE 3: (print-result (get-object-duration ds1 :seconds t))
(get-rhythmic-unit section-or-community)
Derives a clock-unit that could have been used in the section or community.
If section S1 exists, example 1 returns the rhythmic unit.
EXAMPLE 1: (print-result (get-rhythmic-unit s1))
(get-stockpile object)
Returns a list of values from OBJECT.
STOCKPILE: returns a list of the values in the stockpile (example 1 and 1b).
SECTION: returns a list of note objects. The notes are in order but without their start time.
NOTE STRUCTURE: returns a list of notes, rests, and delays in the note structure (example 1).
SHAPE: returns a list of values describing the shape (example 2).
COMMUNITY: returns a list of objects (sections or communities) in the community.
CONTROLLER: returns a list of values that have been produced by the controller since it was last reset.
GET-STOCKPILE would probably be primarily used when writing your own Lisp code, e.g. your own generators.
EXAMPLE 1: (define stock1 (generate-stockpile 10 (rv 1 100)))
EXAMPLE 1b: (print-result (get-stockpile stock1))
EXAMPLE 2: (for-example (get-stockpile wilhelmus))
EXAMPLE 3: (for-example (get-stockpile sine-shape))
(gl start n end &key exponential curve round disjunct add min max)
GL is a shortcut for GENERATE-LINE.
It returns a point on a line between START and END. The first point is START. The Nth point is END. New values for N and END are produced and a line is made from the current value to the new value of END in N steps (examples 1-2).
The interpolation between points is exponential if the keyword EXPONENTIAL is bound to t (example 3).
The steepness of the exponential curve can determined with CURVE. If a value is bound to CURVE, it is assumed that an exponential interpolation is desired (example 4).
If DISJUNCT is t, a new starting point is made for each line segment (example 5).
ADD can be bound to a generator, list, stockpile, constant, etc. to deviate from the generated line (example 6). MIN and MAX are only available if ADD is used. They limit the possible output after the deviation has been added.
See the documentation for GENERATE-LINE for more information (example 7).
EXAMPLE 1: (plot (gl 0 50 '(100 50)))
EXAMPLE 2: (plot (gl 0 (rv 5 15) (rv 0 100)))
EXAMPLE 3: (plot (gl 0 (rv 10 20) (rv 0 100) :exponential t))
EXAMPLE 4: (plot (gl 0 (rv 10 20) (rv 0 100) :curve 4))
EXAMPLE 5: (plot
(gl (rv 1 50) (rv 10 20) (rv 50 100) :disjunct t))
EXAMPLE 6: (plot (gl (rv 1 50) (rv 10 20) (rv 50 100) :add (rv -5.0 5)))
EXAMPLE 7: (show-help 'generate-line)
(group for-value for-repetitions)
Returns a closure. When applied, it produces one value that can be of any type. FOR-VALUE is used to produce a value. FOR-VALUE may be a constant, a list, or a generator. This value occurs a number of times as determined by FOR-REPETITIONS (which also may be a constant, list, or generator to produce a number).
Each application of the closure returns one value. If that value should occur 4 times, the next 3 applications of the closure result in the same value being returned (examples 1-2).
FOR-VALUE and FOR-REPETITIONS can vary over time.
GROUP differs from STUTTER in that GROUP repeats all values whereas STUTTER only repeats some values (example 3).
EXAMPLE 1: (for-example (group (random-choice '(a b c d e))
(random-value 2 6)))
EXAMPLE 2: (for-example (group '(60 64 67) '(2 5)))
EXAMPLE 3: (for-example
(stutter 4 (random-choice '(a b c d e)) 5))
(grow start growth &key n lower upper (reset t) (function #'*))
Returns a closure. When applied, a geometric or arithmetric series of numbers will be produced. By default, a geometric series (multiplication of the previous value by a growth factor) will occur.
Example 1 is an endless geometric series. The first value is START. The second value is START * GROWTH. The next value is the previous value * GROWTH. There is no upper limit.
Example 2 is a decreasing series. Each application of the closure with decrease the value. There is no lower limit.
The series can be limited to N values. The value N+1 will again be START (example 3).
The series can be clipped to be within the range LOWER and UPPER (examples 4-5).
An arithmetic series (adding GROWTH to the previous value) can be realized by binding #'+ to FUNCTION (example 6).
All parameters except RESET can vary over time. They can be constants, lists, stockpiles, generators, etc.
If a series has N values and one or more parameters that vary over time, the new parameter values will be produced every N values (example 7).
By default, RESET is set to t. If it is bound to nil, the series will continue from its current value instead of resetting the series to the START value (examples 8-9). There must be a value for N for this to have any effect.
If START changes over time and RESET is t, then START will receive a new value after each N values (example 10).
Example 11 produces a data section with a rhythm controlled by grow. START is chosen each N times. The series will start at the new start point every N times. N is also a generator.
Example 12 produces a data section where the rhythmic series is continuous. It changes every N times but does not reset to the start value. It continues from where it was.
EXAMPLE 1: (for-example (grow 1 1.1))
EXAMPLE 2: (for-example (grow 1 .9))
EXAMPLE 3: (for-example (grow 1 1.1 :n 5))
EXAMPLE 4: (for-example (grow 1 .8 :lower .4))
EXAMPLE 5: (for-example (grow 1 1.1 :upper 2))
EXAMPLE 6: (for-example (grow 1 2 :function #'+))
EXAMPLE 7: (for-example (grow 1 (random-choice '(.9 1.1)) :n 5))
EXAMPLE 8: (for-example (grow 1 (rc '(.9 1.1)) :n 5 :reset nil))
EXAMPLE 9: (plot (grow 1 (rv .9 1.1) :n 10 :reset nil))
EXAMPLE 10: (for-example (grow (rv 1 3) 1.1 :n 5))
EXAMPLE 11: (fill-template data-section section1 100 100
(grow (rv 1.0 3) 0.9 :n (rv 5 20)
:lower 0.01)
c4 f 10)
EXAMPLE 12: (fill-template data-section section2 50 200
(grow 2 (rv 0.9 1.1) :n (rv 5 10)
:lower 0.01 :upper 10 :reset nil)
c4 f 10)
(gsf generator)
This generator is a shortcut for GENERATE-SF-NAME. It returns a closure.
When applied, the GENERATOR will choose among possible soundfile names which then will be adjusted to be in the appropriate format for a Csound score file.
If the file is a sound file, it should be in the sample directory. If it is an analysis file, it should be in the analysis directory.
In example 1, random-choice is the generator choosing from the list of two possible soundfile names. Each soundfile name should be a string (enclosed in double quotes). Replace "sax1" and "harry" with the names of files found in your sample directory.
The example in this help text can be rendered using 'test csound.orc' found in 'Support/FileExamples'.
See the documentation for GENERATE-SF-NAME for more examples (example 2).
EXAMPLE 1: (fill-template csound-score-object score1
"" nil nil 1 10 3 0
(random-value .5 1)
(gsf
(random-choice '("sax1" "harry")))
0 1 .01 .01)
EXAMPLE 2: (show-help 'generate-sf-name)
(harmonic-chord fundamental-pitch harmonics &key number round name distortion subharmonic)
Returns a closure. When applied, a chord (expressed as a list of notenumbers) is returned. The chord contains notes that are harmonics of the specified fundamental-pitch.
FUNDAMENTAL-PITCH should be a Midi notenumber or a pitch symbol such as c4 derived from a constant, list, stockpile, generator, etc.
HARMONICS contains the desired harmonics. It may be a list, stockpile, generator, etc. (example 1).
When HARMONICS is a list, the resulting chord will contain the same number of notes as are specified for the harmonics. Note that if the fundamental is desired, harmonic 1 should be specified.
If HARMONICS is not a list, the number of harmonics chosen is specified with the keyword NUMBER. This value defaults to 4. (examples 2-3).
When a generator is used for HARMONICS and the FUNDAMENTAL-PITCH should be included in the chord, generator TAKE can be used (example 4).
The default value for ROUND is t. This will round off the Midi note numbers to be integers. If real numbers are desired, ROUND should be bound to NIL (example 5). If ROUND is bound to another number, such as 0.5, the values will be quantized using that value. 0.5 rounds to quarter-tones (example 6).
DISTORTION allows the spectrum to be (slightly) stretched or compressed. The technique is based on a description by Joshua Fineberg (1999).
DISTORTION values above 1 stretch the spectral. Values below 1 compress the spectrum. DISTORTION may be a constant, list, stockpile, generator, etc. The default value is 1 (no distortion) (examples 7-9).
The distortion formula is:
(* fundamental-freq (expt partial-no distortion))
This formula produces the results mentioned in Fineberg's dissertation. The formula he includes does not.
Keyword NAME controls whether pitches are printed as numbers or as note names. When it is bound to t, note names are printed (example 10).
When note names are printed, pitches can be printed with the digits after the decimal point by binding ROUND to nil (example 11) or a quantization unit (example 12).
When keyword SUBHARMONIC is bound to t, harmonic intervals are subtracted from the fundamental rather than added to it. This means that higher harmonics result in lower pitches (example 13). This technique was used by Grisey in Modulations. A discussion of it can be found in Rose (1996).
FUNDAMENTAL-PITCH, HARMONICS, DISTORTION, and SUBHARMONIC may vary over time. FUNDAMENTAL-PITCH (example 14), DISTORTION (example 15), and SUBHARMONIC (example 16) are chosen once per chord.
Chords can be filtered for repetitions and other intervals with CLEANUP-CHORD (example 17).
Chords can be combined into one chord with JOIN->CHORD (example 18).
Chords can be converted to a different range with CONVERT2 (example 19).
Fineberg, J. (1999). Sculpting Sound: An introduction to the Spectral Movement - its ideas, techniques and music (Doctoral dissertation, Columbia University).
Rose, F. (1996). Introduction to the pitch organization of French spectral music. Perspectives of New Music, 34(2), 6-39.
EXAMPLE 1: (for-example
(make (harmonic-chord 24 '(1 4 7))))
EXAMPLE 2: (for-example
(make (harmonic-chord 24 (random-value 1 10))))
EXAMPLE 3: (for-example
(make (harmonic-chord 24
(random-value 1 10) :number 6)))
EXAMPLE 4: (for-example
(make (harmonic-chord 24
(take 1 1 5 (random-value 1 16))
:number 6)))
EXAMPLE 5: (for-example
(make (harmonic-chord 24 '(1 4 7) :round nil)))
EXAMPLE 6: (for-example
(make (harmonic-chord 24 '(1 4 7) :round 0.5)))
EXAMPLE 7: (for-example
(make (harmonic-chord 24 (from 1 5) :distortion 1)))
EXAMPLE 8: (for-example
(make (harmonic-chord 24 (from 1 5) :distortion 1.1)))
EXAMPLE 9: (for-example
(make (harmonic-chord 24 (from 1 5) :distortion 0.9)))
EXAMPLE 10: (for-example
(make (harmonic-chord 24 '(1 4 7) :name t)))
EXAMPLE 11: (for-example
(make (harmonic-chord 24 '(1 4 7)
:name t :round nil)))
EXAMPLE 12: (for-example
(make (harmonic-chord 24 '(1 4 7)
:name t :round 0.5)))
EXAMPLE 13: (for-example
(make (harmonic-chord 48 (from 1 5) :subharmonic t
:name t)))
EXAMPLE 14: (for-example
(harmonic-chord (random-value c0 c2) '(1 4 7))
:number-per-line 1)
EXAMPLE 15: (for-example
(harmonic-chord 24 '(1 4 7 9) :distortion '(1 1.2 1 0.9)
:round 0.5)
:number-per-line 1 :number 4)
EXAMPLE 16: (for-example
(harmonic-chord 48 (from 1 5) :subharmonic '(nil t))
:number-per-line 1 :number 2)
EXAMPLE 17: (show-help 'cleanup-chord)
EXAMPLE 18: (show-help 'join->chord)
EXAMPLE 19: (show-help 'convert2)
(harmonic-minor start)
Returns a closure. When applied, a note number corresponding to the next value in an ascending harmonic-minor scale is generated. The first value in the series is START. The series could continue indefinitely (examples 1-2).
EXAMPLE 1: (for-example (harmonic-minor 60) :number 8)
EXAMPLE 2: (for-example (harmonic-minor 55) :number 8)
help
HELP TAGS
When the mouse is held over a text input item, a button, etc. a help-tag (the yellow dialog with help) will appear after a certain amount of time. Help-tags generally do not appear for text items.
?
Many dialogs have a button with a question mark. Clicking this button will produce a window with the relevant help for that dialog. All dialogs which define objects have this help button. A few others such as the Csound File Options dialog also have it.
GENERATORS, TOOLS, TRANSFORMERS
Information about many generators, tools, and transformers which are available in the AC Toolbox can be found by selecting the item in the Index table or in the Annotated Index. The Index just includes item names. The Annotated Index includes a brief description. In the Annotated Index either the name or description can be searched.
Alternatively, the name of a generator etc. can be selected. Help can be found by then typing the key combination Command-=. (That is holding the command key while pressing the = key). This is the shortcut for the menu item 'Help>Lookup Selection'.
When a text input item is selected in a dialog, CTRL-CLICKing (or using the right mouse button) in the box will produce a popup menu which has an item to look for help for the selection.
OBJECTS
Information about objects which have been defined by a user in the Toolbox can be found in the Objects dialog. If it is not open, use the menu item 'Tools>Show Objects'. The dialog has a table containing all defined objects. Each time a new object is defined, it is added to the table. Using a popup menu, a table of only objects of a particular type can be selected. The input specification for an object can be requested. Various other actions can be performed. Objects can also be removed from the environment by choosing the Remove option.
DIALOG EXAMPLES
Examples of dialogs used to define various objects can be chosen from the table produced by the 'Dialog Examples' menu item in the Info menu. Each dialog will include an example of appropriate input to that dialog.
ANNOTATED INDEX
Online help entries for generators, transformers, and tools can be found in the annotated index table together with a brief description of what the generator, etc. does. Check boxes allow choosing among the possible items which can be displayed. A popup menu allows limiting the displayed items to those belonging to a category such as 'Chaos' or 'Rhythm'. A filter allows searching either the item names or the item descriptions. The general information from the Index is also available in the Annotated Index although it behaves in a somewhat different way than the entries for generators, transformers, and tools.
INDEX
All online help entries for generators, transformers, tools, and general information can be found in the index table. This table can be filtered to only include entries containing some group of letters or words. In the options, a choice can be made to only include general information or only include generators, tools, and transformers.
The index can be selected via the Info menu or with the key combination Command-I.
If a generator is chosen in the index, its help window is opened.
Index also includes entries for general information. This includes topics that otherwise would 'fall between the cracks'. Information about all of the menu items can be found per menu. Each menu has an entry in the table similar to Menu: File describing each menu item. Each object which can be defined using the Define menu has an entry similar to Objects: Sections describing that class of objects.
HELP->FILE
A tool with the name HELP->FILE can be used to write all or some online help to one file. This file can be in html or text format and can be searched or browsed without using the AC Toolbox. The tool allows an optional type parameter to limit the information being gathered in the window. See the help for this tool for details.
LISP
More detailed information about the Lisp functions used within the Toolbox to create and manipulate objects can be found in the help files associated with the different types of objects or operators. These help files can be opened by selecting the object type from the menu item Lisp (in the Info menu). The embedded lines of Lisp code (indicated with EVALUATE: ) can be evaluated by using the ENTER key or CMD-Return. The result is printed in the echo area (under the editor pane). Information about writing your own generators, transformers, etc. can be found under that same Lisp menu with the item 'Your Own'.
help windows
TEMPLATE
A help window for a generator always starts with a template for using that generator. This template includes the name and parameters of the generator, e.g. (1/f-value n a z).
The name of the generator is 1/F-VALUE. The parameters are N, A, and Z. The role of the parameters is always explained in the help window.
A generator such as WALK contains the word &OPTIONAL in its template. This means that all parameters after this word are optional, i.e. they do not have to be used. The user never uses the word &OPTIONAL in an expression.
A generator such as RAMP includes the word &KEY in its template. The parameters that follow are keywords and may be ignored. If they are to be used, the keyword is preceded by a colon. The template for RAMP is:
(ramp begin end increment &key conversion (wrap t))
There are two keywords in that template: CONVERSION and WRAP. The expression (wrap t) in that template means that the keyword WRAP has the default value T. The help files for generators with keywords show examples of how to use the keywords in an expression.
The help windows for transformers and tools both begin with similar templates.
EXAMPLES
Help windows for generators, tranformers, and tools usually include a separate pane with examples of Lisp expressions which can be evaluated to produce some sample results which are printed or plotted. To produce these results, place the cursor at the end of the expression and press the ENTER key (which is different than the return key). It is possible to use CMD-Return instead of ENTER. The Lisp expression could also be selected and evaluated with the menu item, 'Edit>Evaluate Selection'.
FOR-EXAMPLE
The function FOR-EXAMPLE applies a generator several times and prints the result in a window. Usually FOR-EXAMPLE will produce 20 values. Example 1 is such an expression. It means that FOR-EXAMPLE will use the generator 1/F-VALUE to produce some sample results.
FOR-EXAMPLE also has keywords available to adapt the output. Some expressions make use of these keywords. Example 2 uses the generator PRODUCE-PULSE to produce 12 values which will be printed six values to a line.
If the expression in FOR-EXAMPLE is not a generator, it is evaluated once and the result is printed in a window.
PLOT
Plot produces a graph related to its input expression. If the input is a generator, that generator is applied a number of times and the values are plotted. When example 3 is evaluated, 100 hundred values produced by the generator RANDOM-VALUE are plotted.
If the input is a list, the values in the list are plotted.
PLOT has keywords available to adapt its output. NUMBER allows a generator to be applied a specified number of times instead of the default 100 times. MIN and MAX allow a minimum and maximum value to be specified for plotting the results. If these values are not specified, PLOT will use the actual minimum and maximum value derived from the results.
In example 4, the generator 1/F-VALUE is applied 200 times. Even though this generator seldom reaches its specified minimum and maximum value, the plot will use a minimum value of 1 and a maximum value of 100.
SHOW-TRANSFORMATION
Help windows for transformers use the function SHOW-TRANSFORMATION in the expressions which produce sample results.
Example 5 prints the result of applying the transformer, in this case (TRANSPOSE 12), to each value in the list.
FILL-TEMPLATE
FILL-TEMPLATE creates a dialog box used for defining an object. The expression may seem confusing but does not need to be understood. If you evaluate the expression, a familiar looking dialog should appear. FILL-TEMPLATE is just a way to make the dialog (example 6).
OPEN-URL
OPEN-URL will open an url supplied as a string.
Example 7 makes an internet connection and opens (if possible) the browser page from the AC Toolbox. A few help items include an url for getting more information.
SHOW-INFO
Provides information about a section, Midi object, community, or stockpile in a window. The information includes the total number of events and the total duration of the object.
If section S1 exists, example 8 will open or update a section info window.
SHOW-TEXT
This is another way to examine the output of a section, Midi object, or stockpile. A more or less readable version of the object is printed in a window.
If section S1 exists, example 9 will print out the starttime, duration, channel, velocity, and pitch of each event.
PRINT-RESULT
Prints the result of applying a tool or Lisp function in a window (example 10).
PLOT-MANY
Produces a graph containing the output of more than one generator, list, etc. (example 11).
EXAMPLE 1: (for-example (1/f-value 20 1 100))
Example 2: (for-example (produce-pulse '(5 0 2 4 1 3) 2)
:number 12 :number-per-line 6)
EXAMPLE 3: (plot (random-value 1 100))
EXAMPLE 4: (plot (1/f-value 200 1.0 100)
:number 200 :min 1 :max 100)
EXAMPLE 5: (show-transformation (transpose 12)
'(60 62 64 65))
EXAMPLE 6: (fill-template specify-stockpile stock1 c3 c#3 64 66 69 b3)
EXAMPLE 7: (open-url "http://www.actoolbox.net")
EXAMPLE 8: (show-info s1)
EXAMPLE 9: (show-text s1)
EXAMPLE 10: (print-result (cal '(10 20 30) + 2))
EXAMPLE 11: (plot-many 100 "Plot Three Generators"
(rv 1 50) (rv 100 200) (rv 300 400))
(help->file &key type prose brief html open release)
This tool gathers online help windows into one file which can be read without the AC Toolbox. The file could also be searched, formatted, and/or printed in another program.
The online help for generators, tools, transformers, general, and the glossary can be gathered with this tool. If no TYPE is specified, all of the above are gathered in alphabetical order. This takes a while (example 1).
TYPE can also be set to GENERATORS, TOOLS, TRANSFORMERS, GENERAL, or GLOSSARY which results in only the appropriate items being gathered. If type is EVERYTHING, (the default case), all help items are gathered (examples 2 - 6).
Generators, tools and transformers have been divided into various subcategories. These subcategories can also be used to collect only the help for that subcategory (examples 7-9).
The available subcategories are:
basic chaos chord csound file filters koenig mapping masks&shapes
method noise note numbers others pitch programming representation
rhythm select shortcuts spectral stockpiles stream transformation transitions utility
Two or more categories can be included in a list and all help items for those categories will be gathered (examples 10-11).
By default, the file with include some simple html formatting. If keyword HTML is nil, the file with be a plain text file without any html formatting (example 12).
The Annotated Index menu item makes a table of brief descriptions of generators, tools, and/or transformers. To print these brief descriptions to a file, the keyword BRIEF should be bound to t. Everything, generators, tools, transformers, and one or more of the above-mentioned subcategories can be printed briefly (examples 13-15).
By default, the keyword OPEN is bound to t. This will open the resulting html file in the default browser and the resulting text file in an editor window in the AC Toolbox. If this is not desired, bind OPEN to nil (example 16). The files are opened based on their extension: html files should have the extension .html or .htm.
If keyword PROSE is nil, the introductory bit of prose will not precede the help documentation in the file (example 17).
If keyword RELEASE is t, the release notes are included if type is EVERYTHING or GENERAL (example 18).
The default values for the key words are:
TYPE 'everything
PROSE t
BRIEF nil
HTML t
OPEN t
RELEASE nil
EXAMPLE 1: (help->file)
EXAMPLE 2: (help->file :type 'generators)
EXAMPLE 3: (help->file :type 'tools)
EXAMPLE 4: (help->file :type 'transformers)
EXAMPLE 5: (help->file :type 'general)
EXAMPLE 6: (help->file :type 'glossary)
EXAMPLE 7: (help->file :type 'basic)
EXAMPLE 8: (help->file :type 'masks&shapes)
EXAMPLE 9: (help->file :type 'noise)
EXAMPLE 10: (help->file :type '(generators tools))
EXAMPLE 11: (help->file :type '(noise pitch rhythm))
EXAMPLE 12: (help->file :type 'generators :html nil)
EXAMPLE 13: (help->file :brief t)
EXAMPLE 14: (help->file :type 'generators :brief t)
EXAMPLE 15: (help->file :type 'noise :brief t)
EXAMPLE 16: (help->file :type 'stockpiles :open nil)
EXAMPLE 17: (help->file :type '(noise koenig) :prose nil)
EXAMPLE 18: (help->file :release t)
help->window
has been replaced with HELP->FILE.
(henon x y a b giant &key eye xy first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x(n+1)=y(n)+1-ax(n)^2
y(n+1)=bx(n)
The default output variable is X. By using the keyword EYE the variable Y is returned. Both variables will be returned in a list by using the keyword XY.
X and Y are the initial values for the system and should both be a number close to zero. A and B control the behaviour of the system. Both should be a positive value. The system will be stable if the values for A and B are set following this general guideline:
A<=(2.0-B)
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
Small deviations from these values should be possible.
This system shows both periodic and chaotic behaviour. Periodic behaviour generally occurs for small values for A (example 1).
However, if A is small, it depends on the value of B (example 2).
Chaotic behaviour is obtained for higher values for A (examples 3-5).
The initial values for X and Y are not returned. If the initial values should be returned as the first result of the generator, keyword FIRST should be bound to t (examples 6-7).
The Henon-map can be seen with example 8.
It is not possible to predict the maximum and minimum of the output values. To map the output of this function to useful values, use CONVERT (example 9).
A and B may vary over time. Extreme care must be taken that the time-variant values remain in an acceptable range to avoid computational errors (example 10).
If HENON is used in a stream, it may not be convenient to use CONVERT to map the values. In that case, MAP/TIME can be used. This is a generator which maps values on the fly. The minimum and maximum value is however needed to do this mapping.
Tool FIND-RANGE returns the minimum and maximum values of an object or a generator. By default, a generator is applied 1000 times (examples 11-12).
See Bidlack,R. (1992). "Chaotic Systems as Simple (but Complex) Compositional Algorithms". Computer Music Journal, 16(3).
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (henon 0.0 0.0 1.0 0.3 1) :plot nil)
EXAMPLE 2: (plot (henon 0.0 0.0 1.0 0.45 1) :plot nil)
EXAMPLE 3: (plot (henon 0.0 0.0 1.4 0.3 1) :plot nil)
EXAMPLE 4: (plot (henon 0.0 0.0 1.4 0.3 1 :eye t) :plot nil)
EXAMPLE 5: (plot (henon 0.0 0.0 1.4 0.3 10) :plot nil)
EXAMPLE 6: (for-example (henon 0.0 0.0 1.4 .3 1))
EXAMPLE 7: (for-example (henon 0.0 0.0 1.4 .3 1 :first t))
EXAMPLE 8: (plot (henon 0.0 0.0 1.4 0.3 1 :xy t) :number 1000)
EXAMPLE 9: (for-example (convert (henon 0.0 0.0 1.4 0.3 1)
100 c2 c5))
EXAMPLE 10: (plot (henon 0.0 0.0 (line 100 0.8 1.4) .3 1)
:plot nil)
EXAMPLE 11: (for-example (find-range (henon 0.0 0.0 1.4 .3 1)))
EXAMPLE 12: (fill-template make-midi-data-stream stream1 100 1
(map/time (henon 0.0 0.0 1.4 .3 1) -1.28 1.27
50.0 72) f 1)
hetro
Hetro is an analysis program which is available with Csound. Hetrodyne filter analysis is performed on a sound file, producing an analysis file of amplitude and frequency tracks. The analysis file can be read into the AC Toolbox (using READ-TRACKS-FILE) to produce note information. The tracks can also be read with READ-SPECTRUM-FILE in which case one pitch and amplitude value per track will be returned.
If Csound5 or higher is installed, a Hetro analysis file can be made from within the AC Toolbox. Select Other>Csound File Options. Click on the Analysis Programs button and select Hetrodyne Filter (hetro) as the analysis type.
More information about Hetro can be found in the Csound manual.
(high-pass value)
This tool is intended to be used as a filter for WITH, WITHOUT, FILTER-STOCKPILE,FILTER-AND, FILTER-IF, FILTER-OR, etc.
It allows values which are >= VALUE (example 1).
VALUE can change over time.
EXAMPLE 1: (for-example
(with (high-pass 50)
(1/f-value 100 1 100)))
(hz->midi frequency &key round name base)
Returns a closure. When applied one frequency value in Hz is converted to a Midi note number (example 1). The choice of C4 or C3 for middle C can be made in the Preferences dialog.
FREQUENCY can be a constant, list, stockpile, generator, etc. (example 2).
If keyword ROUND is t, the result is rounded to an integer value (example 3). If it is bound to some other number, the result is quantized using that number. E.g., 0.5 would result in quarter-tones (example 4).
By default, ROUND is bound to NIL and the result is a real value. Real numbers can be used for Midi playback using QuickTime or a Capybara.
The keyword NAME, when bound to t, prints out the notename, such as C3, instead of the Midi note number when the generator is applied. ROUND should be bound to t for integer values (example 5).
To print note names with the digits after the decimal point, bind NAME to t and do not bind ROUND to t (example 6).
The keyword BASE is a reference frequency for A4. It defaults to 440.0 Hz (example 7).
This generator is useful if one wants to know the relationship between a frequency value in Hz and a Midi note number. It is also useful when writing generators that need to translate spectral values in Hz to Midi note numbers.
To translate Midi note numbers to a value in Hz, see the generator MIDI->HZ.
EXAMPLE 1: (print-result (make (hz->midi 440)))
EXAMPLE 2: (for-example (hz->midi '(100 200 300 400))
:number 4 :number-per-line 1)
EXAMPLE 3: (for-example (hz->midi '(100 200 300 400) :round t)
:number 4 :number-per-line 1)
EXAMPLE 4: (for-example (hz->midi '(100 200 300 400) :round 0.5)
:number 4 :number-per-line 1)
EXAMPLE 5: (for-example (hz->midi '(100 200 300 400)
:name t :round t)
:number 4 :number-per-line 1)
EXAMPLE 6: (for-example (hz->midi '(100 200 300 400)
:name t)
:number 4 :number-per-line 1)
EXAMPLE 7: (for-example (hz->midi '(100 200 300 400) :base 415)
:number 4 :number-per-line 1)
(if-channel channel parameter transformer)
This transformer can be used with the WHATEVER parameter. If limits the application of TRANSFORMER to the specified parameter on the indicated CHANNEL. CHANNEL may be a number or a list of numbers.
IF-CHANNEL can be used with sections, midi sections, and midi objects.
PARAMETER can be one of the following values:
pitch
velocity
tempo
duration
attack
controller-value
controller-number
controller-channel
program-number
program-channel
Example 1 can define a data section where notes alternate between channels 1 and 2. This section is plotted in Example 2.
Example 3 will transpose the pitch values in channel 2 up two octaves. Example 4 will plot the result.
The tempo of channel 1 can be changed in Example 5. Example 6 plots the result.
Example 7 can define a data-section where notes alternate between channels 1,2,3. Example 8 will transpose channels 1 and 3. Example 9 will plot the result.
EXAMPLE 1: (fill-template data-section ds1 100
20 (rv 1.0 3) (rv 48 60) f '(1 2))
EXAMPLE 2: (plot ds1)
EXAMPLE 3: (fill-template transform ds1-trans1 ds1
:whatever (if-channel 2 'pitch (transpose 24)))
EXAMPLE 4: (plot ds1-trans1)
EXAMPLE 5: (fill-template transform ds1-trans2 ds1-trans1
:whatever (if-channel 1 'tempo (stretch 2)))
EXAMPLE 6: (plot ds1-trans2)
EXAMPLE 7: (fill-template data-section ds2 100
20 (rv 1.0 3) (from 60 79) f '(1 2 3))
EXAMPLE 8: (fill-template transform ds2-trans1 ds2
:whatever (if-channel '(1 3) 'pitch
(transpose -15)))
EXAMPLE 9: (plot ds2-trans1)
(in-parallel structure1 structure2 ...)
Returns an instance of the class SOME-PARALLEL. The note structures included in parallel are interpreted to occur at the same time. An indefinite number of structures can be specified to occur in parallel. Structures that can be used in parallel include structures resulting from A-NOTE, A-REST, A-DELAY, IN-SEQUENCE, or IN-PARALLEL. A structure could also be the name of a section.
Example 1 uses two notes in parallel.
Example 2 has two sequences in parallel:
If sections S1, S2, and S3 exist, three sections in parallel could be expressed as in example 3.
IN-PARALLEL can be used in defining NOTE STRUCTURES, STRUCTURED SECTIONS, and NOTE SECTIONS.
EXAMPLE 1: (fill-template
structured-section
section1 200
(in-parallel (a-note 2 c3 mf 1) (a-note 1 c#3 f 2)))
EXAMPLE 2: (fill-template
structured-section
section1 200
(in-parallel (in-sequence (a-note 1 60 mf 1)
(a-rest 3)
(a-note 1 67 mf 1))
(in-sequence (a-note 2 67 mf 1)
(a-note 1 60 mf 1))))
EXAMPLE 3: (fill-template
structured-section
section1 200
(in-parallel s1 s2 s3))
(in-sequence structure1 structure2 ...)
Returns an instance of the class SOME-SEQUENCE. The note structures included in the sequence, when the sequence is used, are interpreted to occur one after another (in sequence). Note structures used in sequence can be made with A-NOTE, A-REST, A-DELAY, IN-SEQUENCE,or IN-PARALLEL. A structure could also be the name of a section. An indefinite number of structures can be included in sequence (example 1).
In example 2, two sequences are ordered in parallel. When they are both finished, the final note occurs.
IN-SEQUENCE can be used in defining NOTE STRUCTURES, STRUCTURED SECTIONS, and NOTE SECTIONS.
EXAMPLE 1: (fill-template
structured-section
section1 200
(in-sequence (a-note 1 60 mf 1)
(a-rest 3)
(a-note 1 67 mf 1)))
EXAMPLE 2: (fill-template
structured-section
section1 200
(in-sequence
(in-parallel (in-sequence (a-note 1 60 mf 1)
(a-rest 3)
(a-note 1 67 mf 1))
(in-sequence (a-note 2 67 mf 1)
(a-note 1 60 mf 1)))
(a-note 5 c3 f 1)))
input
A dialog box, such as the one for data section, must be filled with text.
Numbers may be entered.
Symbols may be used. Symbols may include the names of objects defined within the environment of the AC Toolbox. Symbols may also be one of several predefined symbols for potentially useful quantities such as pitch and dynamics.
The available dynamic symbols are:
ppp pp p mp mf f ff fff
Dynamics may also be expressed with MIDI velocity values (0-127).
Pitches are represented either by MIDI note numbers (0 - 127) or symbols containing the pitch class and octave. The octave of middle C is considered to be 4. The symbolic representation for middle C in the Toolbox is c4. A half tone higher is c#4 or df4. The lowest available pitch is c-1 and the highest is g9. Note that sharps are # and flats are f in this representation. Via the 'Preferences' dialog, it is possible to assign Midi note number 60 to the symbol c3. All other input symbols for pitch are then adjusted accordingly.
Pitches may be expressed using floating-point numbers: 60.5 is a quarter tone higher than 60. Floating-point output can be seen in various options for printing values. It can be heard if playback is done with QuickTime or Capybara/Pacarana as the chosen destination. Section data sent to FOMUS for formatting for use in a notation program can also use quartertones. For other output destinations and for Midi files, pitch is rounded to an integer value.
Lists may be used as input. A list is represented as a quote, a left-parenthesis, zero or more elements separated by a space, and a right parenthesis:
'(1 2 3)
is a list with three elements.
A function which produces an appropriate result can also be used as input. In Lisp, a function is a list without a quote. The first element in the list is the name of the function. If there are any other elements in the list, they represent data to which the function is applied.
(random-value 1 100)
Random-value is the name of the function. 1 and 100 are the data.
(random-choice '(c4 e4 f#4))
Random-choice is the name of the function. '(c4 e4 f#4) is a list used as a data.
Generators and tools are functions which may be used as input in a dialog box.
In most generators, if the input data contains one or more floating-point numbers, the output is a floating-point number. Otherwise the output is an integer. Some generators have keywords such as round or conversion controlling the conversion of output to integer values.
(random-value 40 80) produces integer values. (random-value 40.0 80) produces floating-point values. (random-value c4 (float g#4)) also produces floating-point values.
In a data section, if a single value is a list, it is considered to be a chord: '((60 64 67) (62 67 69)) represents 2 chords.
Rests are represented by negative values for the rhythm parameter.
(insert-rest start-times length-of-rest &key (margin 0))
Returns a closure that can be used as a transformer for sections. It should be used in the WHATEVER box for transforming objects.
Rests will be inserted at the specified START-TIMES if a note occurs at that time. The rest will delay the entrance of the note.
START-TIMES is a stockpile, list, or number specifying where a rest should be added. Rests can only be added at the beginning of a note. The values are expressed in milliseconds. Repeated values are ignored. Values will be sorted to be in ascending order.
LENGTH-OF-REST is a stockpile, generator, etc. that indicates how long the rest should be. The value is in milliseconds.
Example 1 defines a section with a chromatic scale and equal rhythmic values.
Example 2 transforms that section. There is a list of values for the start times where the rest will be inserted. There is also a list of values for the length of the rests. The rests are inserted in the specified order.
The start times of a section can be found by choosing it in the Objects dialog and selecting Edit.
Example 3 defines a section with unequal rhythms.
Example 4 inserts rests into the section. If no note starts at the specified start time, no rest is added. Since the start times in the section might not fall exactly on the specified values, the key word margin is bound to 25 (milliseconds). If a start time of the note is within a margin of 25 milliseconds from the start time specified in INSERT-REST, a rest will be inserted.
Example 5 uses PRODUCE to generate a list of values. INSERT-REST will remove any duplicates and sort the list to be in ascending order.
Example 6 uses a large value (100) for margin. This could result in overlaps since all notes within the margin for the specified start time will start together.
It may be difficult to find values for MARGIN that are effective. One strategy would be to choose from the actual start times that occur in a section.
The actual start times in milliseconds of a section can be gathered using the tool EXTRACT with RAW-ATTACK as the parameter to extract (example 7).
Example 8 chooses from the list of actual start-times in section source2. The margin defaults to 0.
To eliminate the possibility of choosing a start time of 0, use WITHOUT to filter out that value (example 9).
Example 10 defines a section with highly varied rhythmic values.
Example 11 chooses from the actual start times.
Example 12 generates a parallel section based on example 9. Four layers are produced.
Example 13 inserts a rest in any layer where the start time is within the specified margin. This allows holes to be introduced in a multi-layered section.
LENGTH-OF-REST and MARGIN can change over time.
This transformer differs from the SHOVE transformer in that SHOVE works with index values instead of time values. SHOVE does not allow for a margin when picking values. SHOVE also is intended to be used in the ATTACKS box.
Since SHOVE deals with index values, there is always an event at the intended index that can be transformed. This may not be the case with INSERT-REST.
EXAMPLE 1: (fill-template data-section source1
100 20 1 (chromatic c3) mf 1)
EXAMPLE 2: (fill-template transform trans1 source1
:whatever (insert-rest '(200 500 1200)
'(50 200 50)))
EXAMPLE 3: (fill-template data-section source2
25 20 (rv 1 5) (chromatic c3) mf 1)
EXAMPLE 4: (fill-template transform trans2 source2
:whatever (insert-rest '(200 500 800 1200)
'(100 50 300)
:margin 25))
EXAMPLE 5: (fill-template transform trans2b source2
:whatever
(insert-rest (produce 4 (series-value 200 1000))
(sc '(100 175 280 400))
:margin 25))
EXAMPLE 6: (fill-template transform trans2c source2
:whatever
(insert-rest (produce 4 (series-value 200 1000))
(sc '(100 175 280 400))
:margin 100))
EXAMPLE 7: (print-result (extract 'raw-attack source2))
EXAMPLE 8: (fill-template transform trans2d source2
:whatever
(insert-rest (produce 6
(sc (extract 'raw-attack source2)))
(sc '(100 175 280 400))))
EXAMPLE 9: (fill-template transform trans2d source2
:whatever
(insert-rest (produce 6
(without 0
(sc (extract 'raw-attack source2))))
(sc '(100 175 280 400))))
EXAMPLE 10: (fill-template data-section source3
50 100 (beta-value 1.0 3 0.2 0.2) (rv 40 80) mf 1)
EXAMPLE 11: (fill-template transform trans3 source3
:whatever
(insert-rest (produce (rv 4 7)
(sc (extract 'raw-attack source3)))
(sc '(280 400 1000 2000))))
EXAMPLE 12: (fill-template new-generate-parallel-section source4
4 (rv 0.0 1) source3 nil nil nil)
EXAMPLE 13: (fill-template transform trans4 source4
:whatever
(insert-rest (produce (rv 4 7)
(sc (extract 'raw-attack source4)))
(sc '(280 400 1000 2000))))
(insert-to-section section-to-modify times sections &key (margin 0)
This tool can be used when defining a structured section. Given an original section, one or more other sections can be inserted at various times in the original section.
SECTION-TO-MODIFY is the original section into which other sections will be inserted.
TIMES is a constant, list, or stockpile representing the time in milliseconds where the insertion should occur. Repeated values are ignored. Values will be sorted to be in ascending order.
SECTIONS is a constant, list, generator, etc. representing the section(s) to be inserted.
Example 1 defines the original section. It contains a chromatic scale.
Example 2 defines a section with 3 high pitches.
Example 3 defines a section starting with section SOURCE1. At time 600 (ms), section REPEAT3 is inserted. At the end of section HIGH3, the remaining values from section SOURCE1 occur.
When this tool is used, the clock unit for the new structured section is always ignored.
If a note in the original section does not start at the time specified for the insertion, no insertion occurs (example 4). To see the start times for the notes in the original section, choose the Edit button in the Objects dialog.
A margin can be specified for testing the start time for the insertion. If a note in the original section starts between the specified time and the specified time plus the margin, the insertion will occur (example 5).
Example 6 is another section to insert in the original.
In example 7, two sections are inserted at different time points.
Example 8 shows the use of PRODUCE to make a list of insertion times and a generator to produce the sections to insert. INSERT-TO-SECTION will sort the values in ascending order and remove any duplicates.
Choosing time points for insertion with a generator is tricky. If the value chosen is less than the start time in the section, nothing is inserted. This could mean that each time you make section INSERT5, a different number of insertions occurs.
Another way to generate time points is to choose from the actual start times in the original section. These values can be found by using EXTRACT with the parameter RAW-ATTACK (example 9).
Example 10 eliminates the possibility of choosing start time 0 as a place to insert a section.
It is also possible to insert part of a section by using SLICE (examples 11-12). In these examples, SLICE is used to produce three sections: one is the first 10% of the duration of section MANY; the second includes the notes between 50-70% of MANY; the third includes the notes in the last 10% of MANY.
Instead of using INSERT-TO-SECTION, it is also possible to combine bits and pieces of sections by using the note-structure IN-SEQUENCE (example 13).
EXAMPLE 1: (fill-template data-section source1
100 40 1 (chromatic c2) mf 1)
EXAMPLE 2: (fill-template data-section high3
150 3 1 '(f#5 g5 f#5) mf 1)
EXAMPLE 3: (fill-template structured-section insert1
10 (insert-to-section source1 2600 high3))
EXAMPLE 4: (fill-template structured-section insert2
10 (insert-to-section source1 2625 high3))
EXAMPLE 5: (fill-template structured-section insert3
10 (insert-to-section source1 2625 high3
:margin 100))
EXAMPLE 6: (fill-template data-section random5
50 10 1 (rv c4 c5) mf 1)
EXAMPLE 7: (fill-template structured-section insert4
10 (insert-to-section source1 '(900 2500)
'(high3 random5)))
EXAMPLE 8: (fill-template structured-section insert5
10 (insert-to-section source1
(produce 4
(series-choice
(from 300 4000 :step 100)))
(rc '(high3 random5)) :margin 100))
EXAMPLE 9: (fill-template structured-section insert6
10 (insert-to-section source1
(produce 4
(sc (extract 'raw-attack source1)))
(rc '(high3 random5))))
EXAMPLE 10: (fill-template structured-section insert7
10 (insert-to-section source1
(produce 4
(without 0
(sc (extract 'raw-attack source1))))
(rc '(high3 random5))))
EXAMPLE 11: (fill-template data-section many
150 50 1 (tendency-value '(50 70 80 20 35)) mf 1)
EXAMPLE 12: (fill-template structured-section insert8
10 (insert-to-section source1
'(500 1900 3700)
(list (slice many 0 10)
(slice many 50 70)
(slice many 90 100))
:margin 100))
EXAMPLE 13: (fill-template structured-section insert9
10 (in-sequence (slice source1 0 10)
high3
(slice source1 11 60)
random5
(slice source1 61 100)))
(inside-osc rhythm value)
This tool can be used during the creation of OSC scores. It allows a synthdef argument to be updated during a current OSC event, e.g. frequency could be changed during a sound.
RHYTHM is a constant, generator, etc. that specifies a time value in seconds for making the next update. The first update happens when the OSC event is created. An OSC event is considered to be the event that is created when parameters that are not made with INSIDE-OSC are specified.
VALUE is a generator, list, etc. that produces the update values for changing a parameter inside an event.
The examples use synthdef sine1 which can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
Example 1 updates the frequency parameter of synthdef sine1 every 0.1 seconds. The frequency values are produced with generator WALK. The total duration of the event is between 1 and 3 seconds long. The event duration is articulated with an attack and decay.
Example 2 generates three of the OSC scores from Example 1 in parallel.
Example 3 shows how a rest between OSC events can be created with negative durations. One random duration between 2.0 and 4 seconds is chosen followed by one random rest between 1.0 and 2 seconds. Also, the rhythm for updating the freq parameter using INSIDE-OSC is chosen with a random value.
Example 4 triggers events according to a generator in the Start parameter of the OSC score.
Files made with INSIDE-OSC can be rendered, plotted, transformed, and used as an input for making a histogram. They cannot (yet) be filtered.
INSIDE-OSC also cannot be used when making an osc file from a section with SECTION->OSC.
EXAMPLE 1: (fill-template osc-score-object inside1
10 "sine1" nil nil nil 1 0
"dur" (rv 1.0 3)
"freq"
(inside-osc 0.1
(walk 1400 (rv -100 100.0) 1000 2000))
"amp" 0.1 "decay" 0.4)
EXAMPLE 2: (fill-template generate-parallel-osc-score-object
inside2 3 (rv 0.0 0.1) inside1)
EXAMPLE 3: (fill-template osc-score-object inside3 10 "sine1"
nil nil nil 1
0
"dur" (take 1 (rv 2.0 4) 1 (rv -1.0 -2))
"amp" 0.2
"freq"
(inside-osc (rv 0.2 1.5)
(rv 100.0 1000)))
EXAMPLE 4: (fill-template osc-score-object inside4
5 "sine1" nil nil nil 1 (rv 0.0 30)
"dur" (rv 5.0 10)
"freq"
(inside-osc (rv 0.5 1.5)
(walk (rv 200 800)
(rv -20 20) 100 1000))
"amp" 0.1)
installing csound
When the AC Toolbox refers to Csound, Csound5 or higher is assumed. The user should install it in /usr/local/bin. The installer available from SourceForge will install it in this location.
The Csound installer can be downloaded with example 1 (or 2).
If Csound5 or higher has not been installed, it is not possible to render Csound files or use the analysis programs such as pvanal.
The installer from SourceForge will probably install both 32-bit and 64-bit versions of Csound. This bit size refers to the resolution of the internal calculations. 32-bit calculations may be faster and more suitable for realtime use. The choice between 32-bit and 64-bit calculations can be made in the Csound File Options dialog. The AC Toolbox assumes that 'csound' is the name of the 32-bit version and 'csound64' is the name of the 64-bit version.
The Manual button in the Csound File Options dialog assumes that the Csound manual is installed as:
/Library/Frameworks/CsoundLib64.Framework/Resources/Manual/ or
/Library/Frameworks/CsoundLib.Framework/Resources/Manual/
Installers from SourceForge will probably install it in one or both of these locations. If the manual is requested and not found in one of these locations, the user will be asked to locate the folder for the manual. If different versions of Csound have been installed, it may be necessary to point the Toolbox to the desired version of the manual. This can be done with the 'Select Manual' button in the Csound File Options dialog.
Additional information about Csound can be accessed with example 2.
If errors occur when rendering files in the AC Toolbox, check the default directories for soundfiles, etc. (found in the Csound File Options dialog). Selecting the Display option for 'Messages' in the Csound File Options may assist in tracking errors when a file is rendered.
EXAMPLE 1: (open-url "http://sourceforge.net/projects/csound/files/")
EXAMPLE 2: (open-url "http://www.csounds.com/")
(interpolate thing1 thing2 number &key shape finish)
Returns a closure. When applied one value from an interpolation between THING1 and THING2 is returned. The interpolation takes place in the course of NUMBER of elements.
During each step of the interpolation, either an element from THING1 or an element from THING2 is returned. In the default case, the probability that an element from THING2 will be returned increases linearly during the interpolation.
THING1 and THING2 can be lists, stockpiles, note structures or anything else that DO-THE-NEXT-THING can deal with.
In example 1, either a or 1 is returned, b or 2, etc.
THING1 and THING2 do not have to have the same length. Each one cycles through its elements. If THING1 has 3 elements, and THING2 has 4, then either a or 1 is returned, b or 2, c or 3, a or 4, etc (example 2).
THING1 and/or THING2 could be a generator (example 3).
Instead of a linearly increasing probability that an element from THING2 will be chosen, any shape can be specified with the shape keyword (example 4).
In order to know how many interpolated values are needed to end the process at the end of THING1 or THING2, the FINISH keyword should receive the value 1 or 2. The number of values needed is printed in the Text Output window. The number of values requested could then be adjusted to correspond to this value if that is desired (example 5).
This generator is derived from an idea by Rainer Boesch which he realized in Cadenza.
EXAMPLE 1: (for-example (interpolate '(a b c d) '(1 2 3 4) 40)
:number 40 :number-per-line 4)
EXAMPLE 2: (for-example (interpolate '(a b c) '(1 2 3 4) 40)
:number 40 :number-per-line 3)
EXAMPLE 3: (for-example (interpolate (random-value 1 10)
'(a b c d e) 40)
:number 40)
EXAMPLE 4: (for-example (interpolate '(a b c d e)
'(1 2 3 4 5) 40
:shape sine-shape)
:number 40)
EXAMPLE 5: (for-example (interpolate '(a b c) '(1 2 3 4) 43
:finish 2)
:number 43 :number-per-line 4)
(interpolate-chords chord1 chord2 number-of-steps &key exponential (round t) name conversion )
Returns a closure. When applied, one chord expressed as a list of Midi note numbers is returned. The first application of the generator returns CHORD1. Each notenumber in CHORD1 is interpolated to the notenumber in the corresponding position in CHORD2 in the course of NUMBER-OF-STEPS.
By default, the interpolation is linear.
CHORD1 and CHORD2 should each be a list. This list could come from a stockpile or a generator but cannot change over time (example 1).
For a logarithmic interpolation, the keyword EXPONENTIAL should be bound to t (example 2).
Keyword NAME controls whether pitches are printed as numbers or as note names. When it is bound to t, note names are printed (example 3).
The conversion keyword is no longer supported. Any value bound to it will be ignored. ROUND should be used instead.
The default value for ROUND is t. This will round off the Midi note numbers to be integers. If real numbers are desired, ROUND should be bound to NIL (example 4).
If ROUND is bound to another number, such as 0.5, the values will be quantized using that value. 0.5 rounds to quarter-tones (example 5).
When note names are printed and pitches are real numbers, pitches can be printed with the digits after the decimal point (example 6).
EXAMPLE 1: (for-example
(interpolate-chords '(50 59 63) '(60 64 67) 10)
:number-per-line 1 :number 10)
EXAMPLE 2: (for-example
(interpolate-chords '(50 59 63) '(60 64 67) 10
:exponential t)
:number-per-line 1 :number 10)
EXAMPLE 3: (for-example
(interpolate-chords '(50 59 63) '(60 64 67) 10 :name t)
:number-per-line 1 :number 10)
EXAMPLE 4: (for-example
(interpolate-chords '(50 59 63) '(60 64 67) 10
:round nil)
:number-per-line 1 :number 10)
EXAMPLE 5: (for-example
(interpolate-chords '(50 59 63) '(60 64 67) 10
:round 0.5)
:number-per-line 1 :number 10)
EXAMPLE 6: (for-example
(interpolate-chords '(50 59 63) '(60 64 67) 10
:name t :round 0.5)
:number-per-line 1 :number 10)
(interpolate-loops loop1 loop2 number-of-steps &key exponential conversion)
Returns a list starting with LOOP1 and ending with LOOP2. Between these two loops, each value in LOOP1 will be incremented or decremented in value until LOOP2 is reached. The first value of LOOP1 will change into the first value of LOOP2, the second of value of LOOP1 will change into the second value of LOOP2. The transition will occur in a NUMBER-OF-STEPS (this is the total number of steps including the values from the two loops) (examples 1-2).
LOOP1 and LOOP2 may be lists or stockpiles.
The transition is linear. To have an exponential transition, bind the keyword EXPONENTIAL with t (example 3).
The default situation is that no conversion of the resulting numbers takes place. If a conversion is desired for a linear interpolation, bind the keyword CONVERSION with a Lisp conversion function such as #'round that will round to the nearest integer or #'float that ensures that a number is a floating point number (example 4).
EXAMPLE 1: (for-example
(interpolate-loops '(1 1 1 1 1) '(.5 1 1.5 2 3) 10))
EXAMPLE 2: (plot
(interpolate-loops '(1 1 1 1 1) '(.5 1 1.5 2 3) 10))
EXAMPLE 3: (for-example
(interpolate-loops '(1 1 1 1 1) '(.5 1 1.5 2 3) 10
:exponential t))
EXAMPLE 4: (for-example
(interpolate-loops '(1 1 1 1 1) '(.5 1 1.5 2 3) 10
:conversion #'float))
(interpret-pulse produce-pulse &optional max-indispensability low high)
Returns a closure. When applied, it returns one interpreted value from a pulse (indispensability) interpreted either as a rhythmic value or some other value (e.g. a velocity). This generator does not thin the pulses (as is the case with generator produce-pulse).
The standard interpretation is for rhythmic values; 1 or -1 is produced depending if the pulse-value is positive or negative (examples 1-2). If the optional parameters are included, the interpretation is for velocity (or some other parameter). Negative pulse values are 0 and positive values are mapped between LOW-VALUE and HIGH-VALUE (examples 3-4).
The pulse value is determined by how indispensable it is and what the level of thinning is. Both of these concepts come from Clarence Barlow (1987).
This generator assumes that the value produced by parameter PRODUCE-PULSE is already thinned (if it indeed is to be thinned). This pulse value is taken as is and interpreted.
Barlow, C. (1987). Two Essays on Theory. Computer Music Journal, 11(1), 44-60.
EXAMPLE 1: (for-example (interpret-pulse (thin '(5 0 3 4 1 2) 2))
:number 24 :number-per-line 6)
EXAMPLE 2: (for-example (interpret-pulse '(5 0 2 4 1 3))
:number 12 :number-per-line 6)
EXAMPLE 3: (for-example (interpret-pulse (thin '(5 0 2 4 1 3) 2)
5 50 90)
:number 12 :number-per-line 6)
EXAMPLE 4: (for-example (interpret-pulse '(5 0 2 4 1 3) 5 50 90)
:number 12 :number-per-line 6)
(interpret-sieve pattern sieve type)
Returns a list reflecting the application of a sieve to a list (pattern). Four types of interpretations of possible. Each of these interpretations assumes a rhythmic usage.
Type 1: The sieve indicates the index (in the pattern) of values that are on. All other values are out: i.e. made negative. The index of the first value in the pattern is 1 (example 1).
Type 2: The sieve indicates the index (in the pattern) of values that are on. The subsequent values are added to the preceding value to create a longer ON value and no rests (example 2).
Type 3: The inverse of 1. The sieve values are off and others are on (example 3).
Type 4. The inverse of 2. Only the notes that are not in the sieve are on. The duration lasts until the next 'off' note (example 4).
PATTERN and SIEVE can be lists or stockpiles.
For information regarding the application of sieves to durations, see the paper by Amiot etal in the 1986 ICMC Proceedings.
EXAMPLE 1: (for-example(interpret-sieve '(1 1 1 1) '(1 3) 1))
EXAMPLE 2: (for-example(interpret-sieve '(1 1 1 1) '(1 3) 2))
EXAMPLE 3: (for-example (interpret-sieve '(1 1 1 1) '(1 3) 3))
EXAMPLE 4: (for-example(interpret-sieve '(1 1 1 1) '(1 3) 4))
(invert (&key pc))
Returns a closure that reverses the direction of intervals in the parameter being transformed. The first value is not changed.
The process of inversion is typically applied to pitch (example 1).
The result of inverting a chord has been defined as the inversion of each interval in the chord. The first value in the chord is not changed (example 2).
Alternately, the transformed values can be reduced modulo 12 for a serial-style inversion. This happens if keyword PC is bound to t (example 3).
EXAMPLE 1: (show-transformation (invert) '(60 62 67 65 62))
EXAMPLE 2: (show-transformation
(invert)
'((60 64 67) (67 64 62) (46 76 45)))
EXAMPLE 3: (print-result
(transform-stockpile '(0 8 11 6 9 4 10 2 7 1 5 3)
(invert :pc t)))
(invert-stockpile stockpile)
Returns a list made by transforming STOCKPILE. STOCKPILE may be a list or stockpile (example 1).
The values in STOCKPILE are inverted, modulo 12 (example 2). This can be seen as reducing the values to the range of 0-11 and then subtracting from 12. This is a style of inversion that might be primarily useful in dealing with pitches and intervals.
If the input is a pitch-matrix, each row (list) in the matrix will be inverted (examples 3-4).
EXAMPLE 1: (print-result
(invert-stockpile '(0 8 11 6 9 4 10 2 7 1 5 3)))
EXAMPLE 2: (print-result
(invert-stockpile
'(67 70 61 68 66 71 60 62 69 64 65 63)))
EXAMPLE 3: (for-example
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3))
:number-per-line 1)
EXAMPLE 4: (for-example
(invert-stockpile
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3)))
:number-per-line 1)
(iterate function initial-value)
Returns a closure that will apply FUNCTION to the INITIAL-VALUE. Subsequent applications of the closure, apply FUNCTION to the previous result (examples 1-2).
EXAMPLE 1: (for-example (iterate #'1+ 1))
EXAMPLE 2: (for-example (iterate #'(lambda (x) (* x 2)) 1))
(jitter thing deviation &key percent round)
Returns a closure. When applied, a random value in the range ą DEVIATION is added to THING. If DEVIATION is an integer, the amount of deviation is calculated as an integer (example 1). If DEVIATION is a real number, the deviation is calculated as a real number (example 2).
If either THING and DEVIATION are real numbers, the result is a real number.
Both THING and DEVIATION can vary over time (examples 3-4).
If keyword PERCENT is bound to t, DEVIATION is considered to be a percentage of THING (example 5).
ROUND can be used to quantize the result (example 6).
While JITTER has some similarities with the generator SHAKE, there is an important difference. With SHAKE, the value of DEVIATION is always added to THING. If it is a constant value, the same value is always added (example 7). If it is a generator, the result of applying the generator is added. This means that the deviation does not have to be symmetrical around the value of THING but can vary in any desired way using any generator (example 8).
With JITTER, DEVIATION always is used to produce an uniformly distributed random value in the range ąDEVIATION (example 9). When DEVIATION changes over time, the range for the random distribution changes over time (example 10).
JITTER can also be used to produce textures with a changing amount of deviation in a Csound or OSC file. Example 11 is a Csound score that can be used with 'test csound.orc' which can be found in Support/FileExamples. P5 is the frequency value which starts with a 30% deviation around 500 Hz and ends with a 1% deviations.
EXAMPLE 1: (for-example (jitter 50 5))
EXAMPLE 2: (for-example (jitter 50 5.0))
EXAMPLE 3: (plot (jitter (line 100 20 100) 10))
EXAMPLE 4: (plot (jitter 100 (line 100 0.0 20)))
EXAMPLE 5: (plot (jitter (line 100 20 100) 10.0 :percent t))
EXAMPLE 6: (for-example (jitter 100 5.0 :round 0.5))
EXAMPLE 7: (for-example (shake 100 10))
EXAMPLE 8: (for-example (shake 100 (beta-value 0 10.0 .2 .2)))
EXAMPLE 9: (for-example (jitter 100 10))
EXAMPLE 10: (for-example (jitter 100 (line 20 0 20)))
EXAMPLE 11: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 300 1
(make&sort (from-number) (random-value 0.0 15))
(random-value 1.0 3) (random-value 0.01 0.05)
(jitter 500 (line (from-number) 30.0 1) :percent t))
(join object1 object2...)
Two or more objects of the same type may be joined into one object of that type. The resulting object can be used anywhere that an object of that type can be used (example 1).
The objects can be stockpiles, shapes, masks, sections, etc.
When it is desirable that shapes and masks have the same number of values in the object made with join, the last argument should be t (example 2-3).
JOIN is the same operator which is available using the menu item from Methods.
JOIN can be used to connect two or more transformers (example 4). The output of the most right transformer is the input to the one to its left. This functions in the same way as the tool COMPOSE.
EXAMPLE 1: (plot (join sine-shape expo-shape))
EXAMPLE 2: (plot (join line-shape sine-shape))
EXAMPLE 3: (plot (join line-shape sine-shape t))
EXAMPLE 4: (show-transformation
(join (random-deviation 10.0) (transpose -12))
'(60 64 67))
(join->chord &rest generators)
Returns a closure. When applied, the output of each of the generators is gathered in a chord (a list of numbers). Each generator is applied every time (example 1).
Any repetitions that would occur within the resulting chord because of the combination are removed. This effects the chord size of the result.
GENERATORS can be a generator, list, stockpile, or constant. Any number of generators can be used.
Example 2 combines a fixed pitch and 3 randomly selected values into a chord.
Example 3 facilitates a section with one HARMONIC-CHORD. Example 4 combines two harmonic chords. The second changes for each event.
The generators can be produce numbers or lists of numbers (example 5).
Unwanted intervals can be removed from the resulting chords with the generator CLEANUP-CHORD (example 6).
Chords can be converted to a different range with CONVERT2 (example 7).
EXAMPLE 1: (for-example
(join->chord (make-chord (random-value 30 40) 3)
(make-chord (random-value 70 80) 3))
:number-per-line 1)
EXAMPLE 2: (for-example
(join->chord c2
(make-chord (series-value 60 80) 3))
:number-per-line 1)
EXAMPLE 3: (fill-template data-section section1 1000 4 1
(harmonic-chord c3 (from 1 8))
mf 1)
EXAMPLE 4: (fill-template data-section section2 1000 4 1
(join->chord (harmonic-chord c3 (from 1 8))
(harmonic-chord (from d#3 f#3) (from 1 8)))
mf 1)
EXAMPLE 5: (for-example
(join->chord (rv 30 40) (rv 50 60) (rv 70 80)))
EXAMPLE 6: (show-help 'cleanup-chord)
EXAMPLE 7: (show-help 'convert2)
(jump start step chunk &optional lower upper vary-step (loop 1))
Returns a closure. When applied, the first value is produced by START. The next value is START plus STEP. STEP is added again to this result until CHUNK number of values have been produced. At that time, a leap is made to a new value produced by START and the process repeats. Basically this generator takes some steps, jumps, and takes some more steps (examples 1-3).
LOWER and UPPER boundaries may be specified as optional parameters. Once a boundary is reached, a new value is chosen and the process starts over again (example 4).
If LOOP > 1, the previous CHUNK number of values are repeated. LOOP should be a positive number. The default value is 1 (example 5).
START, STEP, CHUNK, LOOP, LOWER, and UPPER may vary over time. START, STEP, CHUNK, and LOOP are chosen once per jump. LOWER and UPPER are updated with each value (examples 6-8).
If VARY-STEP is t, then the value for STEP is chosen each time instead of once per jump (examples 9-10). In examples 9-10, LOWER and UPPER are not used and therefore must be bound to nil if parameter VARY-STEP is to be bound to t.
This generator could also be used to generate index values for reading a list or stockpile, etc (examples 11-12).
JUMP can be used to 'slide' through a group of values. In Example 13, the start values for three note groups increase by 1 so that the first group is 1,2,3 and the second group is 2,3,4, etc.
EXAMPLE 1: (for-example (jump (random-value 1 20) 1 3))
EXAMPLE 2: (plot (jump (random-value 1 20) 1 3))
EXAMPLE 3: (for-example (jump (random-value 1 20) -1 4))
EXAMPLE 4: (for-example (jump (random-value 1 20)
(random-choice '(-1 1)) 3 1 20))
EXAMPLE 5: (for-example (jump (random-value 1 20) 1 3 1 20 nil 2))
EXAMPLE 6: (for-example (jump (random-value 1 20)
(random-choice '(-1 1))
(random-value 2 5) 1 20))
EXAMPLE 7: (plot (jump (random-value 1 100)
(plus-min (random-choice '(1 2 3)) .5)
(random-value 2 5) 1 100))
EXAMPLE 8: (plot (jump (random-value 1 18)
1 3 1 20 nil (random-value 2 4)))
EXAMPLE 9: (for-example (jump '(1 10 20) '(1 2 3) 4 nil nil t))
EXAMPLE 10: (for-example (jump (rv 1 20) (rv 1 3) 4 nil nil t))
EXAMPLE 11: (for-example (read-from (from 40 80)
(jump (random-value 1 41)
(random-choice '(-1 1))
3 1 41)))
EXAMPLE 12: (fill-template note-section section1 150 100
(read-from wilhelmus
(jump (random-value 1
(get-length wilhelmus))
(random-choice '(-1 1))
5 1 (get-length wilhelmus))))
EXAMPLE 13: (for-example (jump (walk 1 1) 1 3))
keyboard shortcuts
COMMAND-CLICK MAKE button
The object is specified rather than made. This means that the input specification is stored but the data is not evaluated. This can be useful if the objects are not specified in sequential order (i.e. an object is used in another object before is has been made.
CTRL-CLICK MAKE button
For many objects, a popup menu appears which allows the object to be played, plotted, etc. depending on what might be appropriate.
ENTER
CMD-RETURN
If the cursor is at the end of a Lisp expression in an edit window, e.g. the pane with the examples in a help window, the expression is evaluated. Either of these two shortcuts can be used.
kyma
Kyma is a sound design language which produces code that runs on a Capybara or a Pacarana. Kyma sounds which have been downloaded to a Capybara or Pacarana can be controlled with the AC Toolbox. Check in the index for 'Midi output using a Capybara/Pacarana' for a description of this process.
(layer-number)
This tool is intended for use when specifying Csound Objects or OSC Score Objects. When more than one layer is being calculated, this function will return the number of the current layer. This allows different values to be used for different layers.
Example 1 is a Csound example. It can be rendered with test csound.orc found in Support/FileExamples. It uses instrument 1 from that orchestra. P5 will be calculated using a different boundaries for each layer. This can be verified by opening the CSD file with File>Text>Open.
Example 2 is an OSC example. The random walk for each layer starts on a different frequency. This behavior can be confirmed by plotting the OSC file (Tools>Plot>OSC File). The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 3
10 1 0 (random-value 0.1 0.2) 0.2
(random-value
(read-from '(100 600 1500) (layer-number))
(read-from '(200 500 1000) (layer-number))))
EXAMPLE 2: (fill-template osc-score-object osc-score1
50 "sine1" nil nil nil 3 0
"dur" (random-value 0.05 0.1)
"amp" 0.1
"freq" (walk (read-from '(200 1000 2000) (layer-number)) (rv -20.0 20) 50 4000))
(lehmer-choice stockpile &key a b m seed)
Returns a closure. When applied, a value is chosen from the stockpile (or list) using the lehmer-value generator. When the same seed is used, the same series of outputs is produced (examples 1-3).
Behavior is controlled by A,B, and M. These values may change over time.
The default values for the keywords are:
A pi
B 0.25
M 1.0
SEED 1
Bret Battey provides the following general description of the behaviors:
If m = 1:
- if a < 1 and b = 0, the result will always be an exponential decay from the seed to 0.
- if b > 0 and a = 0, the system resolves immediately to b
- when a + b < 1.0, x goes to a steady state
- when a + b > 1.0, simple periodicity arises
- the most complex behavior results when a > 1
For more information on pattern generation with this algorithm, see
Battey, B. (2004). "Musical Pattern Generation". Organised Sound, 9(2), 137-150.
EXAMPLE 1: (for-example (lehmer-choice '(a b c d e f g h)))
EXAMPLE 2: (plot (lehmer-choice (from 1 100))
:plot nil)
EXAMPLE 3: (plot (lehmer-choice (from 1 100) :seed .5)
:plot nil)
EXAMPLE 4: (plot (lehmer-choice (from 1 100) :a .45 :b .5)
:plot nil)
EXAMPLE 5: (plot (lehmer-choice (from 1 100) :a 1.23 :b .92)
:plot nil)
(lehmer-value low high &key a b m seed round)
Returns a closure. When applied, it will produce a value in the range LOW-HIGH using the Lehmer's Linear Congruential formula. While this formula is traditionally used to generate random numbers (given carefully selected arguments), it can also be used as a pattern generator. The default values for A, B, and M facilitate its use as a pattern generator.
Where X(n) is the seed, the algorithm implements this formula:
X(n+1) = a*X(n) + b mod m
The default values for the keywords are:
A pi
B 0.25
M 1.0
SEED 1
This generator is deterministic. Given the same input, it will always produce the same output. Changing the seed changes the sequence of output values (examples 1-2).
Changing A, B, and/or M changes the behavior of the generator (examples 3-6).
Bret Battey provides the following general description of the behaviors:
If m = 1:
- if a < 1 and b = 0, the result will always be an exponential decay from the seed to 0.
- if b > 0 and a = 0, the system resolves immediately to b
- when a + b < 1.0, x goes to a steady state
- when a + b > 1.0, simple periodicity arises
- the most complex behavior results when a > 1
A, B, M, LOW, and HIGH may vary over time.
LOW and HIGH determine the type of the output. If they are both integers, the output is an integer. If one or more is a real number, the output is a real number.
To quantize the result with another unit, bind ROUND to a quantization unit (example 7).
For more information on pattern generation with this algorithm, see
Battey, B. (2004). "Musical Pattern Generation". Organised Sound, 9(2), 137-150.
EXAMPLE 1: (plot (lehmer-value 1 100)
:plot nil)
EXAMPLE 2: (plot (lehmer-value 1 100 :seed .75)
:plot nil)
EXAMPLE 3: (plot (lehmer-value 40 80 :a .7 :b 0.0)
:plot nil)
EXAMPLE 4: (plot (lehmer-value 40 80 :a .9 :b 0.1)
:plot nil)
EXAMPLE 5: (plot (lehmer-value 40 80 :a .98 :b 0.4)
:plot nil)
EXAMPLE 6: (plot (lehmer-value 40 80 :a 1.23 :b 0.92)
:plot nil)
EXAMPLE 7: (for-example
(lehmer-value 40.0 80 :a 1.23 :b 0.92 :round 0.25))
lilypond
LilyPond is an open source music notation program (example 1). It can be used in combination with FOMUS to produce sketches of notated musical material. The AC Toolbox can write section data to a FOMUS file and FOMUS in turn can produce a LilyPond file. This is done via the menu item 'File>Write FOMUS File'.
If used together with FOMUS, LilyPond should be installed in the Applications folder.
EXAMPLE 1: (open-url "http://lilypond.org")
(limit stockpile low high &key reject)
This tool returns a list containing part of a list or stockpile. It can return values that are between or outside LOW and HIGH. It can also just return values <= HIGH or >= LOW.
Example 1 returns the values from the list that are between (and including) LOW and HIGH.
Example 2 returns values from the list that are not between LOW and HIGH.
Example 3 binds HIGH to nil so only values >= LOW are returned.
Example 4 binds LOW to nil to only values <= HIGH are returned.
This tool could be used in combination with the various generators that select from a stockpile, such as all of the generators ending in -CHOICE.
Example 5 defines a stockpile with a scale.
Example 6 prints the generated values.
Example 7 chooses from the stockpile with RANDOM-CHOICE.
Examples 8-9 choose from part of the stockpile.
EXAMPLE 1: (for-example (limit (from 40 80) 60 70))
EXAMPLE 2: (for-example (limit (from 40 80) 60 70 :reject t))
EXAMPLE 3: (for-example (limit (from 40 80) 60 nil))
EXAMPLE 4: (for-example (limit (from 40 80) nil 60))
EXAMPLE 5: (fill-template generate-stockpile scale1 30
(walk 30 (random-value 1 3)))
EXAMPLE 6: (for-example scale1)
EXAMPLE 7: (for-example (random-choice scale1))
EXAMPLE 8: (for-example (random-choice (limit scale1 60 70)))
EXAMPLE 9: (for-example (random-choice (limit scale1 60 nil)))
(limit-range low high &optional modulo)
Returns a closure that limits the range of the parameter being transformed. LOW and HIGH are the limits.
If a parameter is less than LOW, MODULO is added to the parameter until it is within the range. By default, MODULO is 12.
If a parameter is higher than HIGH, MODULO is subtracted from the parameter until it is within the range.
Values between LOW and HIGH are not changed (example 1).
To use a different value for MODULO, specify a number as the optional third argument to LIMIT-RANGE (example 2).
If the distance between LOW and HIGH is less than MODULO, it may not be possible for a number to be squeezed into the range. In that case a warning message is given and the parameter value is not changed (example 3).
EXAMPLE 1: (show-transformation
(limit-range 60 72) '(50 60 62 72 75))
EXAMPLE 2: (show-transformation
(limit-range 60 72 2) '(50 60 62 72 75))
EXAMPLE 3: (show-transformation
(limit-range 60 61) '(50 60 62 72 75))
(limit-spectrum spectrum &key low high reject)
This tool returns a spectrum that has been limited to have pitches in the range LOW to HIGH. The spectrum to be limited should have been read with tool READ-SPECTRUM-FILE.
Example 1 reads a spectrum file. Select the sample file 'test spear bassoon.txt' in Support/FileExamples.
Example 2 prints data from that spectrum.
Example 3 limits that spectrum and saves it in a stockpile.
Example 4 prints data from the limited spectrum.
Example 5 shows the number of peaks in the limited spectrum.
If REJECT is t, then pitches will only be outside the range LOW to HIGH (example 6).
If only a value for LOW is specified, no upper limit will be applied (example 7).
If only a value for HIGH is specified, no lower limit will be applied (example 8).
A spectrum that has been limited with this tool can be used as input to SPECTRUM->PITCH, SPECTRUM->CHORD, and any other generators or tools that accept a spectrum as input (example 9).
EXAMPLE 1: (fill-template construct-stockpile original
(read-spectrum-file :round 0.5))
EXAMPLE 2: (spectrum->window original)
EXAMPLE 3: (fill-template construct-stockpile limited
(limit-spectrum original :low c2 :high c5))
EXAMPLE 4: (spectrum->window limited)
EXAMPLE 5: (print-result (peaks? limited))
EXAMPLE 6: (spectrum->window
(limit-spectrum original :low c3 :high c5 :reject t))
EXAMPLE 7: (spectrum->window
(limit-spectrum original :low c4))
EXAMPLE 8: (spectrum->window
(limit-spectrum original :high c5))
EXAMPLE 9: (for-example (spectrum->pitch limited))
(line number-of-steps start finish &key round exponential curve wrap conversion)
LINE is a shortcut (abbreviation) for LINE-SEGMENT (example 1).
It returns the next point on a line. After NUMBER-OF-STEPS values, it starts at the beginning again (example 2).
If START and/or FINISH is a real number, the result is a real number (example 3). Otherwise the result is an integer.
To quantize to units, bind ROUND to a number (example 4).
Curves can be produced by binding EXPONENTIAL to t (example 5). In that case, 2 is used as the value for CURVE. The steepness of the curve can be controlled by binding a positive value to CURVE (example 6). If a value is bound to curve, it is not necessary to also bind the keyword EXPONENTIAL (example 7). A plot of several different lines is available using example 8.
If a generator is used for the values for NUMBER-OF-STEPS, START, or FINISH, only the initial value for that argument is produced (example 9).
See the help for LINE-SEGMENT for more information (example 10).
A line with several segments can be generated with GENERATE-LINE (example 11).
EXAMPLE 1: (plot (line 100 1 100))
EXAMPLE 2: (for-example (line 10 1 10))
EXAMPLE 3: (for-example (line 20 1.0 10))
EXAMPLE 4: (for-example (line 20 1.0 10 :round 0.5))
EXAMPLE 5: (plot (line 100 1.0 100 :exponential t))
EXAMPLE 6: (plot (line 100 1.0 100 :exponential t :curve 8))
EXAMPLE 7: (plot (line 100 1.0 100 :curve 6))
EXAMPLE 8: (plot-many 100 "Lines with Different Curves"
(line 100 1.0 100)
(line 100 1.0 100 :exponential t)
(line 100 1.0 100 :curve 4)
(line 100 1.0 100 :curve 10))
EXAMPLE 9: (for-example (line 10 (rv 1 5) 10))
EXAMPLE 10: (show-help 'line-segment)
EXAMPLE 11: (show-help 'generate-line)
(line-segment number-of-steps start finish &key round exponential curve wrap conversion )
Goes from START to FINISH in NUMBER-OF-STEPS (examples 1-3).
The default value for the keyword WRAP is nil. This indicates that after FINISH has been reached, the next value will be START. If WRAP is T, the current increment is added to START (example 4).
If START or FINISH are floats, the result will be a float. Otherwise the result will be an integer value (examples 5-6). This is a change from the behavior of LINE-SEGMENT in versions of the AC Toolbox before 4.5.5. In the earlier versions, the result was always a float unless explicitedly rounded. The current practice is similar to other generators in the AC Toolbox.
Results can be converted to integers by binding ROUND to t (example 7).
Results can be quantized by binding a quantization unit to ROUND (example 8).
An exponentially curved line can be produced by binding the keyword EXPONENTIAL to t (example 9). If no value for CURVE has been specified, the value 2 is used. The steepness of the curve can be changed by binding CURVE to a positive value (example 10).
If a value is bound to CURVE, it is not necessary to bind EXPONENTIAL to t (examples 11-12).
The behavior for a descending exponential line was changed in 4.5.6 to correspond to the shape produced by GENERATE-LINE and EXPONENTIAL-MOTION (example 13).
Another way to convert results to integers is by binding a Lisp conversion function to the keyword CONVERSION (examples 14-15).
If both ROUND and CONVERSION are bound, ROUND takes precedence.
The shortcut for LINE-SEGMENT is LINE (example 16).
Generators can be used to derive the initial values for NUMBER-OF-STEPS, START, and FINISH (examples 17-19). Note that each of these generators will only be used to be produce one value.
To generate a series of line segments with different start and finish values, use GENERATE-LINE (example 20).
To specify a specific series of line segments, use PIECEWISE (example 21).
EXAMPLE 1: (for-example (line-segment 20 1 20))
EXAMPLE 2: (for-example (line-segment 20 20 1))
EXAMPLE 3: (for-example (line-segment 10 1 10))
EXAMPLE 4: (for-example (line-segment 10 1 10 :wrap t))
EXAMPLE 5: (for-example (line-segment 20 1.0 10))
EXAMPLE 6: (for-example (line-segment 20 1 10))
EXAMPLE 7: (for-example (line-segment 10 1.0 5 :round t))
EXAMPLE 8: (for-example (line-segment 10 1 3 :round 0.25))
EXAMPLE 9: (plot (line-segment 100 1.0 100 :exponential t))
EXAMPLE 10: (plot (line-segment 100 1.0 100 :exponential t :curve 8))
EXAMPLE 11: (plot (line-segment 100 1.0 100 :curve 6))
EXAMPLE 12: (plot-many 100 "Line Segments with Different Curves"
(line-segment 100 1.0 100 :curve 2)
(line-segment 100 1.0 100 :curve 4)
(line-segment 100 1.0 100 :curve 8))
EXAMPLE 13: (plot (line-segment 100 1.0 0 :curve 4))
EXAMPLE 14: (for-example (line-segment 20 1.0 7))
EXAMPLE 15: (for-example (line-segment 20 1.0 7 :conversion #'truncate))
EXAMPLE 16: (for-example (line 10 1 10))
EXAMPLE 17: (for-example (line-segment (random-value 5 10) 1 20))
EXAMPLE 18: (for-example (line-segment 10 (rv 5 10) 20))
EXAMPLE 19: (for-example (line-segment 10 1 (rv 10 20)))
EXAMPLE 20: (show-help 'generate-line)
EXAMPLE 21: (show-help 'piecewise)
(linear-choice stockpile &optional direction)
Returns a closure. When applied, one value from STOCKPILE is chosen using a linear distribution. This distribution primarily returns values with a lower index. The probability of choosing values with a higher index decreases linearly (examples 1-3).
By default, DIRECTION is 0 which favors lower values. If DIRECTION is 1, the probability density will increase linearly, favoring higher values (examples 4-6).
STOCKPILE may be a list, stockpile, etc.
DIRECTION may change over time (example 7).
EXAMPLE 1: (for-example (linear-choice '(a b c d e f g h i j)))
EXAMPLE 2: (plot (linear-choice (from 1 100 :step 4)))
EXAMPLE 3: (make-histogram (linear-choice (from 1 100)) :number 1000)
EXAMPLE 4: (for-example (linear-choice '(a b c d e f g h i j) 1))
EXAMPLE 5: (plot (linear-choice (from 1 100 :step 4) 1))
EXAMPLE 6: (make-histogram (linear-choice (from 1 100) 1) :number 1000)
EXAMPLE 7: (plot (linear-choice (from 40 60) (group '(0 1) 50)))
(linear-value low high &optional direction round)
Returns a closure. When applied, one random value with a linear distribution is returned. A linear distribution favors lower values. The probability density decreases linearly (examples 1-3).
By default, DIRECTION is bound to 0 which favors lower values. If DIRECTION is bound to 1, higher values are favored and the probability density increases linearly (examples 4-6).
LOW, HIGH, and DIRECTION can change over time (examples 7-9).
To quantize the result with another unit, bind ROUND to a quantization unit (example 10). Note that ROUND is an optional parameter (not a key word) and therefore there must be a value specified for DIRECTION. The value should be 0 (the default) or 1.
The algorithm for a linear distribution produces 2 random numbers and returns the lower of the two. If DIRECTION is 1, the higher value is returned.
The shortcut for LINEAR-VALUE is LV (example 11).
EXAMPLE 1: (for-example (linear-value 40 60))
EXAMPLE 2: (plot (linear-value 40 60))
EXAMPLE 3: (make-histogram (linear-value 1 100) :number 1000)
EXAMPLE 4: (for-example (linear-value 40 60 1))
EXAMPLE 5: (plot (linear-value 40 60 1))
EXAMPLE 6: (make-histogram (linear-value 1 100 1) :number 1000)
EXAMPLE 7: (plot (linear-value (line 100 1 100) 100))
EXAMPLE 8: (plot (linear-value 1 (line 100 20 100) 1))
EXAMPLE 9: (plot (linear-value 1 20 (group '(0 1) 50)))
EXAMPLE 10: (for-example (linear-value 40.0 60 0 0.5))
EXAMPLE 11: (plot (lv 40 80))
(lisp expression)
This tool can be used to insert Lisp expressions into edit boxes in cases where the AC Toolbox error checking might otherwise report some error (such as that the expression is not an AC Toolbox object or generator).
EXPRESSION should be a valid Lisp expression (example 1). Note that example 1 is not written to use any of the existing example Csound orchestras but is just an example of how this tool can be used in a dialog.
EXAMPLE 1: (fill-template csound-score-object
score1 nil nil nil 1 13 1 0 1
(lisp (loop for x from 0 to 12
collect (expt 2 (/ x 12.0)))))
listener
A listener can be created using the menu item 'Other>Listener'. Lisp commands can be evaluated by typing them in this dialog. AC Toolbox tools can also be evaluated.
(load-sound-file &key (size 1000) (average t))
Returns a list containing values read from a 16-bit, mono AIFF of WAVE file.
Since the length of the list can become quite long if the file has a sampling rate of 44.1 kHz, it is often more practical to use groups of samples. SIZE governs the size of the group. If AVERAGE is true, the average of the absolute value of the group is returned (example 1). If AVERAGE is nil, the first value in each group is returned (example 2).
The default value of SIZE is 1000, which for a one second sound recorded at 44.1 kHz would return 44 values (example 3).
The default value for AVERAGE is t. Bind AVERAGE to nil if the values in the group should not be averaged.
The minimum and maximum values returned by this tool are printed in the Listener. This information could be used to map the values to some other range.
If long sound files are read, it make take some time to create a list of all of the values. These lists may be too long to be very useful.
The values returned by LOAD-SOUND-FILE correspond to instantaneous sample values or the amplitude envelope. They do not reflect the frequency content of the recorded signal. See Tutorial 20 in the AC Toolbox tutorial for information about obtaining and using spectral information.
EXAMPLE 1: (plot (load-sound-file))
EXAMPLE 2: (plot (load-sound-file :average nil))
EXAMPLE 3: (plot (load-sound-file :size 1000))
loading definitions
To automatically include definitions, assignments, or forms to load files when the AC Toolbox is loaded, make a file containing these forms and select the file using the dialog produced with the menu-item 'Choose Init File'.
Previous environments can also be loaded by including a form such as
(load "my-old-environment.act")
in this file.
"my-old-environment.act" should be the name of the environment file you want
to include. The filename should include the complete path to the file.
(logist start growthfactor maxpop giant &key first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x(n+1)=mu*x(n)*{1-x(n)}
This formula describes the growth of a population. It accounts for the effects of overpopulation and a shortage of food on the size of the next generation.
The output is the size of the population. The maximum output value is MAXPOP, the minimum is zero.
START sets the fraction of the maximum size of the population possible. It should be a value in the range 0-1. This maximum size is determined by MAXPOP. GROWTHFACTOR controls the behaviour of the system.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
This system is capable of chaotic behavior. This is controled by the parameter GROWTHFACTOR. The value of GROWTHFACTOR must be a number between 0.0 and 4.0. For values smaller than about 3.7 the system is periodic (example 1).
For higher values for GROWTHFACTOR, the system is chaotic (example 2).
To map the output of this function to useful values, use CONVERT (example 3).
GROWTHFACTOR may vary over time (example 4).
The keyword FIRST is no longer supported. Its use has no effect.
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (logist 0.1 3.4 100 1)
:number 50 :plot nil)
EXAMPLE 2: (plot (logist 0.1 3.8 100 1)
:number 50 :plot nil)
EXAMPLE 3: (for-example (convert (logist 0.1 3.8 100 1) 50 c2 c5))
EXAMPLE 4: (plot (logist 0.1 (group (line 10 4.0 3.0) 10)
100 1)
:plot nil)
(logist2 x y growthfactor maxpop giant &key eye xy first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x(n+1)=mu*x(n)*{1-x(n)-y(n)}
y(n+1)=mu*x(n)*y(n)
This formula describes the growth of two populations. One population is the hunter, the other the prey. The size of the both populations depend on each other.
The default output is the size of the X-population. By using the keyword EYE, the size of the Y-population is returned. Both values will be returned in a list by using the keyword XY.
X and Y set the fraction of the maximum size of the populations possible. The should be in the range 0-1. This maximum size is set by MAXPOP. GROWTHFACTOR controls the behavior of the system.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
This system is capable of chaotic behaviour. This is controlled by the parameter GROWTHFACTOR. The value of GROWTHFACTOR must be a number between 0.0 and 4.0. For values smaller than about 3.4 the system is periodic (example 1).
For higher values for GROWTHFACTOR, the system is chaotic (examples 2-5).
To map the output of this function to useful values, use CONVERT (example 6).
GROWTHFACTOR may vary over time (example 7).
The keyword FIRST is no longer supported and its use has no effect.
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (logist2 0.1 0.1 3.0 100 1) :plot nil)
EXAMPLE 2: (plot (logist2 0.1 0.1 3.6 100 1) :plot nil)
EXAMPLE 3: (plot (logist2 0.1 0.1 3.6 100 1 :eye t) :plot nil)
EXAMPLE 4: (plot (logist2 0.1 0.1 3.6 100 1 :xy t) :number 500)
EXAMPLE 5: (plot (logist2 0.1 0.1 3.0 100 1 :xy t) :number 500)
EXAMPLE 6: (for-example (convert (logist2 0.1 0.1 3.6 100 1) 100 c2 c5))
EXAMPLE 7: (plot (logist2 0.1 0.1 (group (line 10 4.0 3.0) 10)
100 1)
:plot nil)
(lookup to-produce-value some-table &key interpolate round)
Returns a closure. When applied, it returns one value from SOME-TABLE that should be a list or stockpile defined by MAKE-LOOKUP-TABLE (example 1) or CONVERT-TO-LOOKUP-TABLE (example 7).
TO-PRODUCE-VALUE can be a constant, a list, a stockpile, or a generator. The value it produces is used as a key to search for an entry in SOME-TABLE. If the key is found, the corresponding value associated with the key in the table is returned (examples 1-2).
If the key is a number and it is not found, the value associated with the nearest key (in value) is returned. If the key is not a number and it is not found, an error is signaled.
MAKE-LOOKUP-TABLE returns a list of values appropriate for a lookup table. This list may also be used in constructing a stockpile. The values that follow should be a key and then some other value to be returned if the key is looked up.
E.g.
(make-lookup-table 1 60 2 50 3 40 10 100 20 45))
has 1,2,3,10, and 20 as the keys
and 60,50,40,100, and 45 as the associated values.
If 1 is looked up in this table, 60 will be returned.
If 2 is looked up, 50 will be returned, etc.
5 will return the number associated with the nearest key without interpolation. In this case, it will be 40.
If interpolation is desired, the keyword INTERPOLATE should be bound to t. Numbers that are not found in the table will be interpolated between the nearest values (examples 3-4).
Values can be rounded using the unit bound to keyword ROUND. This is primarily useful if interpolation has been specified (examples 5-6).
The keys in the lookup table may also be strings (examples 7-8).
CONVERT-TO-LOOKUP-TABLE makes a lookup table by converting an object such as a shape into the values for the table (examples 9-10).
(convert-to-lookup-table object low-key high-key low-value high-value)
The object is mapped to be between LOW-VALUE and HIGH-VALUE. The table contains entries for keys ranging from LOW-KEY to HIGH-KEY. Each of these keys is associated with a value mapped from the OBJECT.
E.g. (convert-to-lookup-table line-shape 1 10 40 80)
would produce a lookup table with the following pairs of keys and values:
KEY VALUE
1 40
2 44
3 49
4 53
5 58
6 62
7 67
8 71
9 76
10 80
LOOKUP is a one way to relate two parameters. The values for the first parameter could be stored in a stockpile. That stockpile could be used to look up values for the second parameter.
Example 11 generates values for pitch and stores them in a stockpile. This stockpile is used for the pitch parameter in the data section (example 12). The pitches are related to the velocity values using a lookup table. The table is defined to have keys from 40 to 80 (the possible pitches). The values for the keys will decrease from 100 to 40. This means that the low keys (the pitches) have higher (velocity) values than the high keys. The values decrease according to the line-shape.
A lookup table could also be defined with only a few values (example 13). Three keys will be used: 40, 60, and 80. Values near 40 receive one value, near 60 another, and near 80 a third value (example 14).
To perform lookup operations and return generators instead of numeric values, see SELECT-GENERATOR-BY-NUMBER (example 15) and SELECT-GENERATOR-BY-CONDITION (example 16).
EXAMPLE 1: (fill-template construct-stockpile table1
(make-lookup-table 1 60 2 50 3 40 10 100 20 45))
EXAMPLE 2: (for-example (lookup '(1 2 3 4 5 6 7 8 9 10 15 25)
table1)
:number 12)
EXAMPLE 3: (plot (lookup (from 1 20) table1)
:number 20)
EXAMPLE 4: (plot (lookup (from 1 20) table1 :interpolate t)
:number 20)
EXAMPLE 5: (for-example
(lookup (from 1 10)
(make-lookup-table 1 40 10 80)
:interpolate t))
EXAMPLE 6: (for-example
(lookup (from 1 10)
(make-lookup-table 1 40 10 80)
:interpolate t :round 1))
EXAMPLE 7: (fill-template construct-stockpile table2
(make-lookup-table "sax1" 10.33 "flute" 9.66))
EXAMPLE 8: (for-example (lookup '("sax1" "flute") table2))
EXAMPLE 9: (fill-template construct-stockpile table3
(convert-to-lookup-table line-shape
40 80 100 40))
EXAMPLE 10: (plot table3)
EXAMPLE 11: (fill-template generate-stockpile pitches 100
(random-value 40 80))
EXAMPLE 12: (fill-template data-section ds1 100 100 1
pitches (lookup pitches table3) 1 0)
EXAMPLE 13: (fill-template construct-stockpile table4
(make-lookup-table 40 100 60 64 80 40))
EXAMPLE 14: (fill-template data-section ds2 100 100 1
(from 40 80) (lookup (from 40 80) table4) 1 0)
EXAMPLE 15: (show-help 'select-generator-by-number)
EXAMPLE 16: (show-help 'select-generator-by-condition)
(loop-through sequence &key start backwards low high step)
Returns a closure that returns successive values from a sequence (list, vector, or stockpile). After all values have been returned once, it loops around to the beginning of the sequence (example 1).
Keyword START is an offset for finding the first value to be returned. By default it is 0. When the offset is 2, the first two values are skipped and the loop begins with the third value (example 2).
Keyword BACKWARDS indicates the direction to loop through the sequence. The default is nil (which means it will not loop through the sequence backwards). To loop through backwards, it should be T (example 3).
Keywords LOW and HIGH can be used to map the value from the loop to another range. Both LOW and HIGH must be specified if the value is to be mapped. LOW and HIGH may change over time (examples 4-5).
Keyword STEP is the increment used to read from the list. The default value is 1 which means every value is read. If STEP is 2, values 1,3,5 ... are read (examples 6-7).
EXAMPLE 1: (for-example (loop-through '(a b c d)))
EXAMPLE 2: (for-example (loop-through '(a b c d) :start 2))
EXAMPLE 3: (for-example (loop-through '(a b c d) :backwards t))
EXAMPLE 4: (plot (loop-through '(1 3 5 7 9) :low 1 :high 50))
EXAMPLE 5: (plot (loop-through '(1 3 5 7 9)
:low (line 100 1 9)
:high (line 100 9 50)))
EXAMPLE 5: (for-example (loop-through '(a b c d e f g h i j k)
:step 2))
EXAMPLE 6: (for-example (loop-through '(a b c d e f g h i j k)
:backwards t :step 2))
(lorenz x y z sigma R B giant &key eye zet xy xyz (stepsize 0.01) first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x'=sigma*(y-x)
y'=Rx-y-xz
z'=xy-Bz
x = x + (x'*stepsize)
y = y + (y' * stepsize)
z = z + (z' * stepsize)
The default output variable is X. Y and Z are returned by using the keywords EYE and ZET, respectively. A list with the values for X and Y is returned by using the keyword XY. All variables will be returned in a list by using the keyword XYZ.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
X, Y, and Z set the initial conditions. SIGMA, R, and B control the behaviour of the system. In general, higher values for R and B increase the chaos, while the same is true for lower values for SIGMA (examples 1-5).
The phase plot of the system is obtained by example 6.
It is not easy to predict the maximum and minimum of the output values. To map the output of this function to useful values, use CONVERT (example 7).
The initial values for X, Y, and Z are not returned. If the initial values should be returned as the first result of the generator, keyword FIRST should be bound to t (examples 8-9).
SIGMA, R, and B can change over time. When specifying a change function, attention should be paid to the value of GIANT (example 10).
See Bidlack,R. (1992). "Chaotic Systems as Simple (but Complex) Compositional Algorithms". Computer Music Journal, 16(3).
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (lorenz 1.0 1.0 1.0 10 28 1.0 10)
:number 300 :plot nil)
EXAMPLE 2: (plot (lorenz 1.0 1.0 1.0 10 28 3/8 10)
:number 300 :plot nil)
EXAMPLE 3: (plot (lorenz 1.0 1.0 1.0 10 28 5.2 10)
:number 300 :plot nil)
EXAMPLE 4: (plot (lorenz 1.0 1.0 1.0 2 28 3/8 10)
:number 300 :plot nil)
EXAMPLE 5: (plot (lorenz 1.0 1.0 1.0 10 40 3/8 10)
:number 300 :plot nil)
EXAMPLE 6: (plot (lorenz 0.1 0.1 0.1 10 28 3/8 1 :xyz t)
:number 3000)
EXAMPLE 7: (for-example
(convert (lorenz 1.0 1.0 1.0 10 28 3/8 10) 100 c2 c5))
EXAMPLE 8: (for-example
(lorenz 1.0 1.0 1.0 10 28 1.0 10))
EXAMPLE 9: (for-example
(lorenz 1.0 1.0 1.0 10 28 1.0 10 :first t))
EXAMPLE 10: (plot (lorenz 1.0 1.0 1.0 10 (line 3000 1.0 40)
1.0 10)
:number 300 :plot nil)
(low-pass value)
This tool is intended to be used as a filter for WITH, WITHOUT, FILTER-STOCKPILE, FILTER-AND, FILTER-IF, FILTER-OR, etc.
It allows values which are <= VALUE (example 1).
VALUE can change over time.
EXAMPLE 1: (for-example
(with (low-pass 50)
(1/f-value 100 1 100)))
(lv low high &optional direction round)
This is an abbreviation for LINEAR-VALUE. When applied, one random value with a linear distribution is returned. A linear distribution favors lower values. The probability density decreases linearly (example 1).
By default, DIRECTION is bound to 0 which favors lower values. If DIRECTION is bound to 1, high values are favored and the probabiity density increases linearly (example 2).
See the documentation for LINEAR-VALUE for more examples and information (example 3).
EXAMPLE 1: (make-histogram (lv 1 100) :number 1000)
EXAMPLE 2: (make-histogram (lv 1 100 1) :number 1000)
EXAMPLE 3: (show-help 'linear-value)
(major start)
Returns a closure. When applied, a note number corresponding to the next value in a major scale is generated. The first value in the series is START. The series could continue indefinitely (examples 1-2).
EXAMPLE 1: (for-example (major 60) :number 8)
EXAMPLE 2: (for-example (major 55) :number 8)
(make generator)
MAKE applies a generator. If the result is a symbol, it then evaluates the produced result. Otherwise the result is returned. This is useful for instance if you want to make a choice among object names with a generator and then evaluate the name to get the object itself to use as input to a function.
Assuming the existence of two masks - MASK1 and MASK2 - a choice between them can be made for use in CONVERT (example 1).
It is also useful if you want only one value from a generator and do not want that value to change over time (example 2).
In example 2, a lower boundary and an upper boundary are chosen and used to determine all values.
EXAMPLE 1: (plot
(convert (make (random-choice '(mask1 mask2))) 100 1 100))
EXAMPLE 2: (for-example (random-value (make (random-value 1 40))
(make (random-value 50 100))))
(make&sort number generator &optional predicate)
Returns a list produced by applying the GENERATOR a NUMBER of times. The list is sorted in ascending order. The primary use of this tool is for making Csound or OSC files (example 1).
To sort the list in a different way, supply a predicate to use during the sort (example 2).
This generator is useful if a Csound or OSC score object generates (random) values for start times but also uses a mask or shape in another parameter. To make sure that the mask or shape is presented in the right order, the start times should be sorted. With MAKE&SORT you can generate values and then sort them.
The Csound score produced by example 3 can be rendered with test csound.orc in Support/FileExamples.
The source code for the synthdef sine1 (used in example 4) can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
MAKE&SORT can be abbreviated to MS (example 5).
This tool can also be used when ascending lists of numbers are required, e.g. in the transformers INSERT-REST and REPLACE-BY-INDEX.
EXAMPLE 1: (for-example (make&sort 10 (random-value 1 50)))
EXAMPLE 2: (for-example (make&sort 10 (random-value 1 50) #'>))
EXAMPLE 3: (fill-template csound-score-object
score1 "f1 0 8193 10 1
f2 0 8193 20 2 1" nil nil 1 20 1
(make&sort 20 (random-value 0.0 10))
(random-value 1.0 2)
0.1
(convert expo-shape 20 200.0 400))
EXAMPLE 4: (fill-template osc-score-object osc-score1
20 "sine1" nil nil nil 1
(make&sort 20 (random-value 0.0 10))
"dur" (random-value 1.0 2)
"amp" 0.2 "freq"
(convert expo-shape 20 200.0 400))
EXAMPLE 5: (fill-template osc-score-object osc-score1
20 "sine1" nil nil nil 1
(ms 20 (random-value 0.0 10))
"dur" (random-value 1.0 2)
"amp" 0.2 "freq"
(convert expo-shape 20 200.0 400))
(make-chord source-object size-object &key block pitch-class stop allow-repeats limit)
Returns a closure. A chord is a list of note numbers in either a data section or a note section. This closure, when applied, will produce a list of note numbers that could be used as chords for either of those two types of sections.
SOURCE-OBJECT can be a list, stockpile, generator etc. capable of providing numerical values. These values are grouped in succession to produce a chord. If SOURCE-OBJECT is a list and each chord should have 4 values, each successive 4 values are taken from the list. If need be, the closure will wrap around to the beginning of list to get more values.
SIZE-OBJECT indicates the number of pitches to be included in the chord (list). It may be a constant, generator, stockpile, etc. (examples 1-2).
Keyword BLOCK will prevent certain intervals from being present in a chord. To do this, BLOCK should be bound to an interval or a list of intervals. These intervals will be blocked. Before a value is included in a chord, it is checked to see that it does not create a forbidden interval. Intervals are expressed as a number of semitones.
Some of the chords in example 3 will probably contain the same pitch more than once.
The chords in example 4 will not contain any pitch doublings, since the unison is blocked.
The chords in example 5 will not contain any unisons or minor thirds.
If unison intervals are blocked, it is still possible that a chord would contain an octave. To prevent this, values should be reduced to their pitch class before the intervals are examined. This can done by binding keyword PITCH-CLASS to t (examples 6-7).
If one or more intervals are being blocked, it is the responsibility of the user to make sure that a chord of the desired size can actually be created without using the blocked intervals. The Toolbox will give up after trying STOP number of times (examples 8-9).
If successive chords should not contain common pitches, bind ALLOW-REPEATS to nil. This will prevent the selection of any pitch used in the previous chord. If this is not possible, the Toolbox will give up after STOP number of attempts.
The example 10 prevents repetitions in successive chords but allows a pitch to be used more than once within a chord. The example 11 also blocks the repetition of a pitch within a chord.
Keyword LIMIT can limit the range of the chord to be within ąlimit steps of the first value chosen for the chord. The first value chosen for the chord is the last one listed in the printed representation of the chord (examples 12-14). If a value cannot be found within the requested limits, the Toolbox will stop trying after STOP number of attempts.
SOURCE-OBJECT, SIZE-OBJECT, and LIMIT may vary over time.
Example 15 uses MAKE-CHORD in a data-section.
Chords can be combined into one chord with JOIN->CHORD (example 16).
EXAMPLE 1: (for-example (make-chord '(60 62 64 65 67 69 71) 3))
EXAMPLE 2: (for-example (make-chord (random-value 40 80)
(random-value 2 4)))
EXAMPLE 3: (for-example (make-chord (random-value 60 72) 4))
EXAMPLE 4: (for-example
(make-chord (random-value 60 72) 4 :block 0))
EXAMPLE 5: (for-example
(make-chord (random-value 60 72) 4
:block '(0 3)))
EXAMPLE 6: (for-example
(make-chord (random-value 48 72) 4 :block 0
:pitch-class t))
EXAMPLE 7: (for-example
(midi->notename
(make-chord (random-value 48 72) 4 :block 0
:pitch-class t)))
EXAMPLE 8: (for-example
(make-chord (rv 60 62) 4 :block 0))
EXAMPLE 9: (for-example
(make-chord (rv 60 62) 4 :block 0 :stop 500))
EXAMPLE 10: (for-example
(make-chord (rv 60 65) 3 :allow-repeats nil))
EXAMPLE 11: (for-example
(make-chord (rv 60 65) 3 :block 0 :allow-repeats nil))
EXAMPLE 12: (for-example
(make-chord (rv 40 80) 4 :block 0 :limit 6))
EXAMPLE 13: (for-example
(make-chord (rv 40 80) 4 :block 0
:limit (line 20 3 12)))
EXAMPLE 14: (plot
(make-chord (rv 40 80) 4 :block 0
:limit (line 100 3 12)))
EXAMPLE 15: (fill-template
data-section section1 400 20 1
(make-chord (random-value 48 72) 3 :block '(0 4 7)
:pitch-class t)
mf 1 0)
EXAMPLE 16: (show-help 'join->chord)
(make-conditional-table
entry possibilities
entry possibilities
...)
Constructs a table for use with transition. An ENTRY is a list of one or more previous values. POSSIBILITIES is a list of elements and their probabilities that could follow the entry.
Any number of entries and possibilities can be made. Traditionally probability is expressed as a value between 0 and 1. 0 is never. 1 is always. In this tool, probability can be any positive value and will be scaled to the proper range.
Example 1 constructs a first-order table, i.e. that one previous value is examined. If the previous value is A, then the next value is either B (30% probability) or C (70% probability). If the previous value is B, then C will always follow. If the previous value is C, then either A or B will follow.
Examples 2-3 show using a conditional table with the generator TRANSITION.
See the help for TRANSITION for more information.
EXAMPLE 1: (for-example
(make-conditional-table
'(a) '(b .3 c .7)
'(b) '(c 1)
'(c) '(a .5 b .5)))
EXAMPLE 2: (for-example
(transition (make-conditional-table
'(a) '(b .3 c .7)
'(b) '(c 1)
'(c) '(a .5 b .5))))
EXAMPLE 3: (for-example
(transition (make-conditional-table
'(a) '(b 1 c 3)
'(b) '(c 1)
'(c) '(a 5 b 2))))
(make-histogram sequence-or-function &key title print number replace round min max)
If SEQUENCE-OR-FUNCTION is a sequence (list or vector), a histogram is drawn in a window reflecting the contents of the sequence. It is assumed that the sequence will only contain numbers (example 1).
If keyword PRINT is bound to t, the values and their frequency of occurence are printed in a window instead of graphed (example 2).
If SEQUENCE-OR-FUNCTION is a lexical closure (a generator), a histogram is drawn reflecting the result of applying that closure a number of times (example 3). The default number of times is 100. This can be changed with the key word NUMBER (example 4).
It is assumed that the closure will only produce numbers.
Keyword ROUND can be bound to a number which is used as the unit to quantize values before the histogram is made (examples 5-7).
Keyword REPLACE determines if the previous histogram window will be closed after a new one is made (example 8).
The default value for REPLACE is specified in the Preferences dialog.
Keyword TITLE allows a string to be used to give the window a title (example 9).
Normally the representation is scaled to have the lowest value on the left and the highest value on the right. If other boundaries are desired, they can be specified with MIN and MAX (example 10). If the actual minimum value < MIN or the actual maximum value is > MAX, the actual value is used (example 11).
EXAMPLE 1: (make-histogram '(1 2 1 1 1 2 2 2 1 2 3 4 5))
EXAMPLE 2: (make-histogram '(1 2 1 1 1 2 2 2 1 2 3 4 5) :print t)
EXAMPLE 3: (make-histogram (random-choice '(1 2 3 4 5)))
EXAMPLE 4: (make-histogram (random-choice '(1 2 3 4 5)) :number 200)
EXAMPLE 5: (make-histogram (rv 1.0 10))
EXAMPLE 6: (make-histogram (rv 1.0 10) :round 1)
EXAMPLE 7: (make-histogram (rv 1.0 10) :round 0.5)
EXAMPLE 8: (make-histogram (rv 1 20) :replace t)
EXAMPLE 9: (make-histogram (noise-value 100 1 100 -1.5)
:title "Pink/Brown Noise")
EXAMPLE 10: (make-histogram (rv 40 80) :min 1 :max 100)
EXAMPLE 11: (make-histogram (rv 1 100) :min 40 :max 80)
(make-lookup-table key value key value ...)
MAKE-LOOKUP-TABLE returns a list of values appropriate for a lookup table. This tool may also be used in constructing a stockpile. The values that follow should be a key and then some other value to be returned if the key is be looked up (examples 1).
E.g.
(make-lookup-table 1 60 2 50 3 40 10 100 20 45)
has 1,2,3,10,and 20 as the keys
and 60,50,40,100,and 45 as the associated values.
If 1 is looked up in this table, 60 will be returned.
if 2 is looked up, 50 will be returned, etc.
A lookup table is used by the generator LOOKUP (example 2).
A key can be a string (examples 3-4).
A key can also refer to a generator, list, or stockpile.
When it refers to a generator, that generator is applied to produce a new value each time the key is referenced (with lookup) (examples 5-6).
When a key refers to a list or stockpile, the next value is returned each time the key is referenced (examples 7-9).
Generator LOOKUP can interpolate between values in the table (example 10).
For a different method for making a lookup table, see CONVERT-TO-LOOKUP-TABLE. It can convert an object such as a shape into the values for the table.
EXAMPLE 1: (fill-template construct-stockpile table1
(make-lookup-table 1 60 2 50 3 40 10 100 20 45))
EXAMPLE 2: (for-example
(lookup '(1 2 3 4 5 6 7 8 9 10 15 25)
table1)
:number 12)
EXAMPLE 3: (fill-template construct-stockpile table2
(make-lookup-table "sax" 10.33 "flute" 5.1))
EXAMPLE 4: (for-example
(lookup (random-choice '("sax" "flute"))
table2))
EXAMPLE 5: (fill-template construct-stockpile table3
(make-lookup-table 1 1 5 (sc '(10 20 30))
10 (rv 100 200) 20 1000))
EXAMPLE 6: (for-example
(lookup (from 1 20) table3))
EXAMPLE 7: (fill-template specify-stockpile stock1
50 60 70 80)
EXAMPLE 8: (fill-template construct-stockpile table4
(make-lookup-table 1 stock1 5 10
10 (srv 20 30)))
EXAMPLE 9: (for-example
(lookup (from 1 15) table4))
EXAMPLE 10: (for-example
(lookup (from 1 20) table1 :interpolate t))
(make-many-variants names object &rest to-make)
This tool will generate one or more variants of OBJECT. It is intended for use in the Listener or in an editor window.
NAMES should be a list of symbols to use as the names for the variants.
Example 1 can be used to define a stockpile. Example 2 creates three variants of this stockpile which are called STOCK1B, STOCK1C, STOCK1D. When the expression is evaluated, the names of these new stockpiles will appear in the Objects dialog.
Any AC Toolbox object can be used as OBJECT, though it only makes sense if the input specification involves some kind of random values.
It is also possible to remake one or more existing objects before making the variant. If an object is remade, the original values are lost. Example 3 can be used to define a data section which uses the values of STOCK1 for pitch. Rhythm is also derived from the values of STOCK1. Lower pitches will have longer durations. Example 4 generates 2 new sections which are variants of DS1. Before each variant is generated, STOCK1 is remade.
Any number of objects can be remade but only one object can be varied (examples 5-7).
EXAMPLE 1: (fill-template generate-stockpile stock1 20 (random-value 40 80))
EXAMPLE 2: (make-many-variants '(stock1b stock1c stock1d) stock1)
EXAMPLE 3: (fill-template data-section ds1 100 20
(otf 1.0 / stock1 * 100) stock1 f 1)
EXAMPLE 4: (make-many-variants '(ds1b ds1c) ds1 stock1)
EXAMPLE 5: (fill-template generate-stockpile stock2 20
(random-choice '(pp p f ff)))
EXAMPLE 6: (fill-template data-section ds2 100 20
(otf 1.0 / stock1 * 100) stock1 stock2 1)
EXAMPLE 7: (make-many-variants '(ds2b ds2c) ds2 stock1 stock2)
(make-note-function duration-object pitch-object velocity-object channel-object)
Returns a closure. When applied, one note (as an object for a note section) is produced. The input parameters may be single values, sequences, or generators (examples 1-2).
EXAMPLE 1: (fill-template note-section note1 150 20
(make-note-function 1 '(60 64 67) '(96 64) 1) 0)
EXAMPLE 2: (fill-template note-section note2 150 20
(make-note-function (random-value 1 10)
(major 60)
(random-value 50 90)
(random-value 1 2)) 0)
(make-permutation elements &key number length)
Returns a list of all possible permutations of the elements in ELEMENTS. ELEMENTS is usually a list or a stockpile (example 1).
Each permutation is also a list.
The number of possible permutations of a series of elements is the factorial of the number of elements. For example, four elements have 24 possible combinations.
The following table shows that the number of possible combinations increases very quickly as the number of elements grows:
elements combinations
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
10 3628800
11 39916800
12 479001600
Unless the AC Toolbox has an exceptionally large stack size, creating all 479 million combinations of twelve elements is probably not a practical activity. Permutations of up to seven or eight elements seem to fit into a standard AC Toolbox memory partition.
If some permutations of a larger number of elements is desired, the keyword NUMBER can be set to the number of permutations desired. This allows that NUMBER of permutations to be created even though it is practically impossible to produce all permutations of all the elements (example 2).
Note that the permutations are constructed according to a fixed algorithm. Each time a permutation is made with the same elements, the same permutation results. If a different order of permutations is desired, the permutation should be read with a generator such as SERIES-CHOICE which could read the permutations in a different order (example 3).
A different group or order of permutations can also be made by putting the elements to be permuted in a different order (examples 4-5).
If a permutation should have a length smaller than the number of elements, use the keyword LENGTH. For example, if you want to permute 4 elements in groups of 3 (example 6)
See the help for the generator READ-PERMUTATION for examples of reading single elements from a permutation.
EXAMPLE 1: (for-example (make-permutation '(0 4 7)))
EXAMPLE 2: (for-example
(make-permutation '(1 2 3 4 5 6 7 8 9 10 11 12)
:number 10)
:number-per-line 1)
EXAMPLE 3: (for-example
(series-choice (make-permutation '(1 2 3 4)))
:number 24 :number-per-line 1)
EXAMPLE 4: (for-example
(make-permutation '(4 1 2 3))
:number-per-line 1)
EXAMPLE 5: (for-example
(make-permutation (rearrange-stockpile '(1 2 3 4) 'shuffle))
:number-per-line 1)
EXAMPLE 6: (for-example
(make-permutation '(ppp p f ff) :length 3))
(make-row &key n)
Returns a list of values that could be treated as a (12-tone) row. The first value is 0. The other values are randomly chosen, without repetition, to be in the range 1 to (- N 1) (example 1).
The default value for N is 12.
If keyword N is bound to another value, that many values will be returned in the range 0 to (- N 1). The first value in this case is still 0 (example 2).
EXAMPLE 1: (print-result (make-row))
EXAMPLE 2: (print-result (make-row :n 6))
(make-unconditional-table element probability element probability ...)
Constructs a table for use with transition. Any number of elements may be entered together with a corresponding probability of occurence. Traditionally probability is expressed as a value between 0 and 1. 0 is never. 1 is always. In this tool, probability can be any positive value and will be scaled to the proper range (examples 1-3).
See the help for TRANSITION for more information.
EXAMPLE 1:
(for-example
(make-unconditional-table 'this .4 'that .4 'is .2))
EXAMPLE 2:
(for-example
(transition
(make-unconditional-table 'this .4 'that .4 'is .2)))
EXAMPLE 3:
(for-example
(transition
(make-unconditional-table 'this 10 'that 5 'is 20)))
manipulating spectra
Spectra created with the programs SPEAR, Hetro, Audacity or Amadeus can be read into the AC Toolbox with the tool READ-SPECTRUM-FILE and used in a variety of ways.
In SPEAR, data should be exported using the 'text - partials' format. This will produce a text file.
For the Csound utility Hetro, the standard file format is used.
In Audacity a spectral plot should be exported as a text file.
In Amadeus, the spectrum can be saved as a text file (not importable).
When entered in the AC Toolbox, this data will be a static spectrum (one set of data for the entire sound). The peaks are sorted according to descending amplitude.
A list of pitches derived from this spectrum can be returned with SPECTRUM->PITCH. With this tool, the pitches can also be mapped to a different pitch space. If five pitches are requested, they will be the five pitches with the highest amplitudes.
A list of velocities derived from a spectrum can be returned with SPECTRUM->AMP. The velocities can be mapped to a different range. A list of frequencies can be made with SPECTRUM->FREQ.
A chord in the form of a parallel note structure can be created with SPECTRUM->STRUCTURE. A number of pitches from the spectrum will occur at the same time using their corresponding velocity values. The chord can be to a different pitch space. A duration and Midi channel for each member of the chord can be specified (or generated).
SPECTRUM->CHORD is a generator which will produce lists of pitches suitable for use as a chord in a data section. The size of the chord and the selection of peaks can change over time with this generator.
SPECTRUM->MIRROR is a tool that will mirror a spectrum around a given pitch value. If the value is the lowest found in the spectrum, the result could be considered an implementation of Grisey's concept of subharmonicity but then applied to a derived spectrum.
SPECTRUM->RANGE returns the lowest and highest pitches in a spectrum.
LIMIT-SPECTRUM returns a spectrum limited to pitches in a given range. A keyword allows limiting a spectrum to values outside a given range.
A table of information from a spectrum can be produced with SPECTRUM->WINDOW. For each peak, a frequency, floating-point Midi number, note name, amplitude, and velocity value will be displayed.
The number of peaks in a spectrum can be queried with PEAKS?.
To read in a spectral analysis that changes over time use READ-TRACKS-FILE.
Additional information can be found in the help for each of the mentioned tools or generators. Tutorial 20 in Using the AC Toolbox discusses spectral data and its use.
(map-text text &key block low high replace round)
Converts TEXT which may be a string, list, or stockpile into a list of ASCII codes corresponding to the characters in TEXT (example 1).
Specific ASCII codes can be blocked from inclusion in the list using BLOCK which may a single value or a list of ASCII codes (examples 2-3).
The resulting list can be mapped to values between LOW and HIGH. Both of these keywords must be specified if the list is to be mapped (example 4).
If BLOCK, LOW and HIGH are all specified, the blocking of the ASCII occurs before the resulting list is mapped between LOW and HIGH (example 5).
Values which are blocked can be replaced with the value bound to REPLACE (example 6).
The value is replaced before the mapping between LOW and HIGH occurs (example 7).
In example 7, space (character 32) is replaced with character 105 (which is i). Since this occurs before the mapping, the highest value in the resulting list is the one corresponding to t and the lowest corresponds to e.
Values in a list are not stored in a case-sensitive manner (i.e. there is no difference between upper and lower case). Case-sensitive texts should be entered as a string (examples 8-9).
In a list or stockpile, punctuation marks such as : or , are not allowed. To use these punctuation marks, enter the text as a string.
A text can be read from a stockpile (examples 10-11).
This stockpile can be used to determine pitch in a section (example 12).
A string can be used in a stockpile for a case sensitive text (examples 13-14).
Spaces in a text could be used to produce rests by choosing a generator which produces negative values for rhythm if the ascii code is 32 (space) or less and another generator if that is not the case (example 15).
When a rest occurs in a section, the corresponding pitch value is discarded. That is the reason in the above example why spaces were not just removed but replaced. The value that is discarded is the one in the place of the space. The space was replaced was so that the mapping between LOW and HIGH would not be influenced by the low value of space.
Example 16 can read in a text file (which should not include punctuation marks).
A text file read in with READ-TEXT-FILE is not case-sensitive.
LOW and HIGH can vary over time, i.e. they may be generators, lists, etc. in addition to constant values (example 17).
If LOW and HIGH are specified, the resulting values can be quantized by binding a unit to ROUND. If a real number is used as the quantizing unit, LOW and/or HIGH should be a real number (example 18).
EXAMPLE 1: (print-result (map-text "hi there"))
EXAMPLE 2: (print-result (map-text "hi there" :block 32))
EXAMPLE 3: (print-result (map-text "hi there" :block '(32 101)))
EXAMPLE 4: (print-result (map-text "hi there" :low 40 :high 80))
EXAMPLE 5: (print-result (map-text "hi there" :block 32
:low 40 :high 80))
EXAMPLE 6: (print-result (map-text "hi there" :block 32 :replace 0))
EXAMPLE 7: (print-result (map-text "hi there" :block 32 :replace 105
:low 40 :high 80))
EXAMPLE 8: (print-result (map-text '(Hi There)))
EXAMPLE 9: (print-result (map-text "Hi There"))
EXAMPLE 10: (fill-template specify-stockpile text1
this is a stockpile about
nothing in particular)
EXAMPLE 11: (for-example (map-text text1))
EXAMPLE 12: (fill-template data-section text-pitch1 100 47 1
(map-text text1 :low 40 :high 80) mf 1)
EXAMPLE 13: (fill-template specify-stockpile text2
"This is a Stockpile about Nothing in Particular" "")
EXAMPLE 14: (for-example (map-text text2))
EXAMPLE 15: (fill-template data-section text-pitch2
100 47
(act-if (map-text text2)
<= 32 (random-value -1.0 -3)
else (random-value 1.0 3))
(map-text text2 :block 32 :replace 105
:low 40 :high 80) mf 1)
EXAMPLE 16: (for-example (map-text (read-text-file)))
EXAMPLE 17: (plot (map-text "la la la la la la la la"
:low (line 23 40 70)
:high 80))
EXAMPLE 18: (for-example
(map-text "hi there" :low 40 :high 50.0 :round 0.5))
(map-tracks analysis tracks channel &key min-vel max-vel filter)
This tool maps data derived from a sound analysis made either with SPEAR or the Hetro analysis utility of Csound. Both of these programs produce data containing frequency and amplitude tracks, though they use different methods to create this data.
This tool can map a selection of those tracks to Midi data suitable for use in a section. It can also filter out pitch repetitions and duplicates. To quantize the pitches, see READ-TRACKS-FILE.
ANALYSIS should either be the result of using READ-TRACKS-FILE or the name of a stockpile that was constructed with READ-TRACKS-FILE.
Sample Hetro files are available in Support/FileExamples. One is called 'test hetro (intel).het'. The other is 'test hetro (ppc).het'. Select the file whiich is appropriate for your processor.
Example 1 will read in a hetrodyne analysis file and map tracks 1 through 10 to Midi channel 1 without quantizing pitch or filtering repetitions. MAP-TRACKS is expects the clock unit in a structured section to be 1. A higher value will stretch the tempo of the event list.
SPEAR analysis files are available in folder Support/FileExamples.
Examples 2-3 construct a stockpile and use that stockpile in MAP-TRACKS. Select 'test spear voice.txt'. It contains 30 tracks with different durations and start times. The stockpile contains tracks with the pitch rounded to semitones.
Section2 is created by mapping tracks 1-30 from the analysis contained in stockpile voice1. The number of available tracks is printed in the Text Output window when a file is read. The clock unit in the example is 1 since the track data is expressed in milliseconds.
SPEAR partial track files contain partials that do no necessarily last for the duration of the sound. In SPEAR, it is possible to select, edit, and manipulate partials before exporting the partials as text. To see the partials included in the sample file 'test spear voice.txt', open that file in SPEAR. It can also be resynthesized in SPEAR.
TRACKS can have a constant, a list, or a vector as input. If the value is constant, one track will be mapped. If the value is a list or vector, the track numbers contained in the list or vector will be mapped (example 4).
MIDI-CHANNELS can be a constant, list, generator, etc. Each track will be assigned to the next available Midi channel (example 5).
The five tracks chosen in the above example will be assigned to Midi channels 1, 2, 3, and 4 respectively. If fewer channels are specified than tracks, the channel data will loop to provide new data.
Amplitude values from the analysis file are scaled to be velocity values in the range MIN-VEL to MAX-VEL. The default values are 20 and 64 (example 6).
The analysis tends to produce a lot of similar frequencies in succession. When these frequencies are mapped to pitch, particularly when the pitch is quantized to semi or quarter-tones, this produces a large number of repetitions of the same pitch. The analysis tends to produce a lot of data anyway since it is intended for sound resynthesis and not note synthesis (example 7).
One way to deal with the repetitions, is to bind FILTER to t. This removes all successive (or simultaneous) repetitions of the same pitch (examples 9-10). This filter uses a different method than the filter in READ-TRACKS-FILE. The filter in READ-TRACKS-FILE only filters within a track. In MAP-TRACKS, the tracks are turned into note data before they are filtered. This filter will filter pitches regardless of which track in which they originally occurred.
If the number of tracks in the track data are forgotten for whatever reason, use tool TRACKS? to return the number.(example 10).
EXAMPLE 1: (fill-template structured-section
section1 10
(map-tracks (read-tracks-file :type 'hetro) (from 1 10) 1))
EXAMPLE 2: (fill-template construct-stockpile
voice1 (read-tracks-file :type 'spear :round 1))
EXAMPLE 3: (fill-template structured-section section2 1
(map-tracks voice1 (from 1 30) 1))
EXAMPLE 4: (fill-template structured-section section3 1
(map-tracks voice1 (from 1 30 :step 2) 1))
EXAMPLE 5: (fill-template structured-section section4 1
(map-tracks voice1 '(1 3 10 15 30) '(1 2 3 4)))
EXAMPLE 6: (fill-template structured-section section5 1
(map-tracks voice1 (from 1 30) 1
:min-vel 10 :max-vel 80))
EXAMPLE 7: (show-info section5)
EXAMPLE 8: (fill-template structured-section section6 1
(map-tracks voice1 (from 1 30) 1
:filter t))
EXAMPLE 9: (show-info section6)
EXAMPLE 10: (print-result (tracks? voice1))
(map/time value input-low input-high output-low output-high &key chord round)
Returns a closure that can be used to map a VALUE between INPUT-LOW and INPUT-HIGH to the range between OUTPUT-LOW and OUTPUT-HIGH. All parameters can vary over time and may be constants, lists, stockpiles, generators, etc. This generator is a time-varying generator version of the tool MAPVALUE. If OUTPUT-LOW or OUTPUT-HIGH is a real number, the result is also a real number (examples 1-2).
A chaotic generator such as HENON can seem to have unpredictable results. To determine the minimum and maximum results to use with such a generator in MAP/TIME, use the tool FIND-RANGE that returns the minimum and maximum value generator, list, stockpile, etc. If the input is a generator, FIND-RANGE returns the minimum and maximum values found in 1000 applications of the generator (examples 3-4).
If an external controller is connected, controller 1 could be used to control OUTPUT-LOW and controller 2 to determine OUTPUT-HIGH when defining the pitch of a data stream:
(map/time (henon 0.0 0.0 1.4 0.3 1) -1.28 1.27
(external-value 1 c1 c5)
(external-value 2 c1 c5))
If the data being mapped contains chords, the minimum and maximum value can be determined with FIND-RANGE and then mapped with MAP/TIME (examples 5-6).
If a chaotic function producing 2 or more dimensions is being mapped, keyword CHORD should be bound to nil so that each dimension returns and uses its own minimum and maximum value. In example 7, X is mapped to be between 40 and 80. Y is mapped between 20 and 40.
The output can be quantized with keyword ROUND (example 9).
EXAMPLE 1: (for-example
(map/time (henon 0.0 0.0 1.4 0.3 1) -2 2 c1 c5))
EXAMPLE 2: (for-example
(map/time (henon 0.0 0.0 1.4 0.3 1) -2 2 60.0 65))
EXAMPLE 3: (for-example
(find-range (henon 0.0 0.0 1.4 0.3 1)))
EXAMPLE 4: (for-example
(map/time (henon 0.0 0.0 1.4 0.3 1) -1.28 1.27 40 80))
EXAMPLE 5: (for-example (find-range '((60 64 67) (55 65 75))))
EXAMPLE 6: (for-example
(map/time '((60 64 67) (55 65 75)) 55 75 60 65))
EXAMPLE 7: (for-example
(find-range (henon 0.0 0.0 1.4 .3 1 :xy t) :chord nil))
EXAMPLE 8: (for-example
(map/time (henon 0.0 0.0 1.4 .3 1 :xy t)
'(-1.28 -0.38) '(1.27 0.38)
'(40 20) '(80 40) :chord nil))
EXAMPLE 9: (for-example
(map/time (henon 0.0 0.0 1.4 .3 1)
-1.28 1.27 60 80.0 :round 0.5))
(mapvalue x a b c d &key round)
All arguments should evaluate to numbers. Number X, in the range A to B, is mapped to the range C to D. Output type is determined by C and D. Example 1 returns an integer and example 2 returns a real number.
Key word ROUND can also effect the output. It can be bound to a quantization unit (example 3).
EXAMPLE 1: (print-result (mapvalue .5 0 1 0 100))
EXAMPLE 2: (print-result (mapvalue .5 0 1 0.0 100))
EXAMPLE 3: (print-result (mapvalue 0.321452 0 1
0.0 100 :round 0.25))
mask
A mask is represented by two lines. It is a field which changes over time. Values can be calculated to be within a mask. Calculating values within a mask allows parameter values to change in time. CONVERT is a tool that can be used with masks to convert them to some useable parameter values.
(masks&values top bottom n new-top new-bottom
&key conversion generator distance round)
Returns a closure. When applied, a point on a top line and a point on a bottom line are produced. A returned value is chosen randomly between those two points.
The two lines can be seen as describing a tendency mask. This generator could produce an endless series of mask segments and values chosen from them.
The first point on the top line is TOP. The first on the bottom line is BOTTOM. The next point will move along those lines so that the Nth point will be NEW-TOP and NEW-BOTTOM respectively.
After N points have been produced, new values for N, NEW-TOP, and NEW-BOTTOM are generated. Points will be produced between the current values and the new values. Then new values for N, NEW-TOP, and NEW-BOTTOM are produced. And so on.
The output of the generator is a value chosen between the current points on the two lines.
N, NEW-TOP, NEW-BOTTOM and DISTANCE can vary over time and therefore can be constants, lists, stockpiles, generators, etc (example 1).
This generator will produce new destinations for the top and bottom lines after 100 values. This process is continuous.
If more values are displayed, more segments will be produced (example 2).
N may vary over time (example 3).
The values for TOP and BOTTOM are only used once but can also be a constant, generator, etc (example 4).
The choice between the two lines is by default made with random-value. Another generator can be used by binding it to the GENERATOR keyword. The generator should produce values between 0 and 100 (percent). This amount refers to the distance between the two lines (example 5).
The type of the result is dependent on the type for TOP, BOTTOM, NEW-TOP, and NEW-BOTTOM. If any of these are real numbers, the result will be a real number. Otherwise the result is an integer.
To quantize the result with another unit, bind ROUND to a quantization unit (example 6).
It is also possible to bind a Lisp conversion function to the keyword CONVERSION (example 7).
If both ROUND and CONVERSION have values other than nil, ROUND takes precedence.
The key word DISTANCE ensures that there is a minimum distance between the two lines defining the mask. By default, the value for DISTANCE is nil which means that no check is made for a minimum distance. If DISTANCE is bound to a number, the lines will be checked to ensure that the minimum distance is available. If it is not available, the top line is raised. DISTANCE may vary over time (example 8).
MV is a shortcut for MASKS&VALUES (example 9).
EXAMPLE 1: (plot (masks&values 80 40 100
(random-value 30 90)
(random-value 30 90)))
EXAMPLE 2: (plot (masks&values 80 40 100
(random-value 30 90)
(random-value 30 90))
:number 1000)
EXAMPLE 3: (plot (masks&values 80 40 (random-value 10 200)
(random-value 30 90)
(random-value 30 90))
:number 1000)
EXAMPLE 4: (plot (masks&values (random-value 70 90)
(random-value 30 50)
(random-value 10 200)
(random-value 30 90)
(random-value 30 90))
:number 1000)
EXAMPLE 5: (plot (masks&values (random-value 70 90)
(random-value 30 50)
(random-value 10 200)
(random-value 30 90)
(random-value 30 90)
:generator (beta-value 0.0 100 .2 .2))
:number 1000)
EXAMPLE 6: (for-example (masks&values (random-value 70 90)
(random-value 30 50)
20 (random-value 30.0 90)
(random-value 30 90)
:round 0.25))
EXAMPLE 7: (for-example (masks&values (random-value 70 90)
(random-value 30 50)
20 (random-value 30.0 90)
(random-value 30 90)
:conversion #'truncate))
EXAMPLE 8: (fill-template make-midi-data-stream ds1 20 1
(masks&values
(random-value 70 90)
(random-value 30 50)
(random-value 10 50)
(random-value 50 60)
(random-value 50 60)
:distance 4)
ff 1)
EXAMPLE 9: (plot (mv 80 40 100
(random-value 30 90)
(random-value 30 90)))
(mc source-object size-object &key block pitch-class stop allow-repeats limit)
This is a shortcut for MAKE-CHORD. When applied, a chord of size SIZE-OBJECT is made by taking values from SOURCE-OBJECT (examples 1-2).
See the documentation for MAKE-CHORD for more examples and an explanation of the various key words (example 3).
EXAMPLE 1: (for-example (mc (random-value 40 80) 4))
EXAMPLE 2: (fill-template data-section section1 200
50 (random-value 1.0 2)
(mc (random-value 40 80) (random-value 2 4))
(random-choice '(p mf f ff)) 1)
EXAMPLE 2: (show-help 'make-chord)
(melodic-minor start)
Returns a closure. When applied, a note number corresponding to the next value in an ascending melodic minor scale is generated. The first value in the series is START. The series could continue indefinitely (examples 1-2).
EXAMPLE 1: (for-example (melodic-minor 60) :number 8)
EXAMPLE 2: (for-example (melodic-minor 55) :number 8)
menu: define
Various objects can be defined in the AC Toolbox. All objects which may be defined are included as menu items in this menu.
Each object has a separate entry in the Index (as part of the general information).
Undo Definition will undo the last object definition if an object with that name was previously defined.
menu: edit
Most of the items in this menu refer to ways of dealing with text. The text could be in a text file but could also be the input entered in a dialog box item.
The last six items need some special attention.
BALANCE ()
When the cursor is placed after a right parenthesis or before a left one, the cursor is moved to the corresponding parenthesis (if it is present). This can help determine if the appropriate number of parentheses are present. The cursor is moved so it may need to be moved back before continuing with the editing process. This option is only available in text input panes (e.g. in the dialogs for defining objects). It is not available in the Listener or in Lisp editor windows.
SELECT ()
An expression in parentheses can be selected by placing the cursor somewhere in the expression and then selecting this menu item. Also, if the cursor is placing after a ), the selection is made to a corresponding (. In this second case, the menu item can help check if the number of parenthesis are accurate. This option is only available in text input panes (e.g. in the dialogs for defining objects). It is not available in the Listener or in Lisp editor windows.
INSERT NEWLINE
Many dialog items have room for more than one line of text but do not necessarily go to the next line if return is entered. To go to the next line in those dialogs, use this menu item.
EVALUATE LAST FORM
Evaluates the Lisp expression preceding the cursor. This is useful in the Lisp editor.
EVALUATE SELECTION
Evaluates a chosen text, i.e. it treats the text as a Lisp expression and tries to calculate the result. This is useful in the Lisp editor.
EVALUATE ALL
Evaluates an entire text file. This is convenient if the file contains Lisp expressions such as function definitions which a user wants to add to the toolbox. This is useful in the Lisp editor.
menu: file
The File menu provides ways to load and save AC Toolbox objects, open and save text files, import and export MIDI files, and to create files which can be used with other programs.
TEXT
Text files may have been created in another program, may contain additional Lisp definitions which should be evaluated, may contain notes taken by a user, etc.
Text files can be opened, edited, and savedusing the various items of this menu.
LOAD OBJECTS
AC Toolbox objects (such as sections, shapes, masks, etc.) which have previously been saved to a file can be loaded. The objects from the file will be added to the current environment.
REPLACE ALL OBJECTS
AC Toolbox objects which have previously been saved to a file can be loaded. The objects from the file will replace the objects contained in the current environment.
RECENT ENVIRONMENTS
Object files (environments) which have been previously loaded or saved are listed in this menu. Selecting the file name will load the file if it still exists in the same location. The most recent file is the first menu item.
LOAD EXAMPLES
Files containing examples of object specifications, such as those found in the folder AC Toolbox tutorials, can be loaded. A table will list the objects defined in the file. Typically, an example file will only contain an input specification. To use the examples, the user should click on input and make the object.
RECENT EXAMPLES
Example files which have been loaded or saved are listed in this menu. The most recent file is the first menu item. Selecting the file name from the menu will load the file if it still exists in the same location.
SAVE ALL OBJECTS
All AC Toolbox objects which have been defined in the current environment will be saved to a file. Both the input specification and the values which were calculated are saved. Csound and OSC score objects and streams only save the input specification. If an environment has been previously saved, the objects will be saved to a file with that name (replacing the previous file). To see the name of the current file, use the menu item CURRENT ENVIRONMENT FILE?
SAVE ALL OBJECTS AS
All AC Toolbox objects which have been defined in the current environmenet will be saved to a new file.
SAVE SOME OBJECTS
Objects can be chosen from a table to be saved to a file.
SAVE AS EXAMPLES
Saves the input of all objects in the environment. They are saved according to the time at which they were made. The first objects made are saved first. This menu item is useful if you are making examples or tutorials for the AC Toolbox or if you only want to save the general information about objects as opposed to their specific event values.
CURRENT ENVIRONMENT FILE
If the environment has been saved during the current session, the most recent file name used for the environment is displayed.
IMPORT MIDI
A Midi file can be imported and used as a section or Midi object. A Midi file containing notes should be imported as a section. A file containing only MIDI controller data should be imported as a controller object. A file containing only program change information should be imported as a program object. A file containing combinations of the above should be imported as a section.
EXPORT MIDI
A section or a Midi object can be exported to a Midi file. Midi file formats 1 and 0 are supported. File format 1 supports multiple tracks. File format 0 uses only one track.
LOAD LISP FILE
Load either a text file containing Lisp code or a binary file which was compiled to work with the AC Toolbox. This would presumably add features to the AC Toolbox.
CHOOSE INIT FILE
A file can be chosen to be loaded every time the AC Toolbox is started. This file could contain for example Lisp functions and definitions or instructions to load files, such as (load "myfile.lisp").
MIDI SETUP
Creates a dialog to select one input and one output for Midi data. Output can be routed to use QuickTime Musical Instruments or a CoreMidi destination such as a port of a Midi interface. If a Capybara or Pacarana sound computation engine is available, it can be chosen as the output destination for Midi data.
LOAD GM SELECTIONS
A previously saved file containing General Midi instrument selections can be loaded. The file will contain selections made using the dialog box created when the General Midi menu item is chosen.
SAVE GM SELECTIONS
General Midi instrument selections are saved to a file. The selections were made using the dialog box created when the General Midi menu item is chosen.
WRITE FOMUS FILE
Creates a dialog to to pick various options for the FOMUS notation formatting program. A section can be written to a file in this format (with the extension .fms). FOMUS can prepare data for LilyPond or the interchange format MusicXML which can be read by programs such as Sibelius and Finale.
WRITE SOUND FILE
Creates a dialog to write a sound file based on an object. The assumption is that the file will contain integers between -32768 and 32767. The range can also be smaller.
The Options dialog for this feature allows the user to specify the number of values to be written to the file, the sample rate, and the file format. The minimum and maximum value is used only in converting shapes and masks.
Since the minimum and maximum values are only used for shapes and masks, they have no influence on other objects. If a generator is used to produce values for the sound file, the values produced by the generator are written to the file without modification (and are not forced to be in the range specified in the options dialog).
Typically Write Sound File would be used to produce a waveform which could be accessed in another program.
The sound file can use either the AIFF or WAVE file format.
WRITE MAX TABLE
Creates a dialog to generate a table of the specified size suitable for use in Max.
menu: help
The menu contains various possibilities for getting additional information about the AC Toolbox.
GETTING INFORMATION is a text describing several ways to get help about things within the Toolbox.
LOOKUP SELECTION tries to find information about a selected text if it occurs in an AC Toolbox dialog or window. If the selected text is the name of a generator, transformer, or tool, the associated help window is opened. If the selected text is the name of an object, the object is selected in the Objects table.
The keyboard shortcut for Lookup Selection is Command-=.
GO BACK HELP PAGE displays the previous help page if one has been displayed during this session. A help page is the page produced by selecting an item in the Index, Annotated Index, or with Lookup Selection. If a page has been displayed but no help page is currently visible, the last one displayed is displayed again.
GO FORWARD HELP PAGE navigates forward in the list of help pages that have been displayed.
OBJECT INFO makes an info window using the object selection in the Objects dialog if the object is a section, community, Midi performance object, or stockpile. Otherwise it brings the Object Info window to the front if it is open. Info describes an object's type, number of events, and total duration (if relevant).
LISP contains a submenu with different topics for people who want to know how to use Toolbox objects when writing Lisp code.
TUTORIAL opens the AC Toolbox Tutorial in a browser window if possible. This may not work with all browsers. It should work if Safari or Firefox is the default browser.
WHAT'S NEW? opens the release notes for the current version of the AC Toolbox.
DIALOG EXAMPLES is a table containing examples with possible values for each dialog which creates an object in the AC Toolbox. Selecting an item will open the example.
ANNOTATED INDEX is a table which contains the names of generators, tools, and transformers as desired along with brief descriptions of what they do. These items can be searched using a text filter for either names or the description. The generators, tools, and transformers can be selected using a popup menu suggesting various categories. Selecting an item will open the corresponding help window.The option to close a previous help window when a new one is opened is controlled in the options for index.
INDEX is a table of most available online help. This table can be filtered by entering letters or words in the filter dialog. Only items containing these letters or words will be included in the table. Selecting the item will open the help. Dialog examples and Lisp help files are not included in the index.
menu: methods
The menu items are methods (functions) which can be applied to various types of objects. In some cases, there are also methods for applying to a Csound score file or a binary OSC file.
BACKWARDS will reverse an object.
FILTER allows an object to be filtered in a number of different ways. A Csound score file and a binary OSC file can also be filtered.
JOIN will join two or more objects of the same type together. Optionally, shapes or masks could be normalized to the same length before being joined together.
MAKE VARIANT will make a variant of an object. A variant is an object with the same input specification as another object although the values of the object may be different.
SLICE will slice (cut) out a portion of an object. The chosen portion can be specified with percentage values. In the case of a section, the percentages refer to a percentage of the total duration. The chosen portion can also be selected be specifying index values (the first value is 1, the second is 2, etc.).
TRANSFORM allows an object to be transformed by using one or more of the available transformers. For example, the pitch parameter could be transposed or the rhythm stretched. A Csound score file and a binary OSC file can also be transformed.
menu: other
KILL
Stops all processes which are running, including playback and the rendering of Csound or OSC files. It does not stop runaway functions.
ADD COMMENT
Short comments can be added to the dialogs associated with an object. The comment will be saved with the object in the environment for future reference. To edit a previously made comment, click on it. Only one comment can be added to a dialog. ADD COMMENT adds the comment to the front dialog if that dialog can be used to define an AC Toolbox object.
CSOUND FILE OPTIONS
Creates a dialog box which can be used to set options for writing and rendering Csound files. There is an option to automatically generate names. Sample format and audio header type can be chosen. The choice between rendering the Csound file to an audio file or in realtime can be made. Other command line flags can also be specified. A button is available to open the Csound manual in a browser. Another button opens a dialog for using the Csound utilities pvanal and hetro. Csound5 or higher is assumed to be installed in /usr/local/bin.
RENDER CSD
Renders the most recent CSD file from the current session. This is particularly useful if Csound CSD files are rendered in real time. This item makes it easy to render them again (and again) If no CSD file has been rendered in the current session, a file can be chosen to render. Options for rendering are stored in the CSD file. If the file has the option for rendering to a file stored in its CSD file, changing the option to In Realtime in the Csound File Options will not change how the existing CSD file is rendered.
USE OPEN ORC FILE
If the top (selected) window is a Csound orchestra file (with extension .orc), that file is chosen as the orchestra file for rendering subsequent Csound score objects.
SOUND FILE INFO
Prints basic information about a chosen sound file. This only works when the Csound utility SNDINFO has been installed. Usually that program is installed during a standard Csound install.
OSC FILE OPTIONS
Creates a dialog box which can be used to set options for the writing and rendering of binary OSC files. Most options are only relevant if the OSC file is also rendered to an audio file by the AC Toolbox using the SuperCollider scsynth application. In that case, the audio header, sample format, and number of channels can be chosen. In this dialog, the automatic file naming procedure for OSC files can be also turned on or off.
KYMA SLIDERS
Creates an interface with 1 or more sliders which can be used to control Kyma. The interface can be configured to work with any number of sliders in any order. The sliders in the AC Toolbox will be connected to the controllers specified in Kyma as !cc01, !cc02, etc. Capybara/Pacarana must be selected in the Midi Setup for this option to be available. Also, the Toolbox should play something with Kyma at least once for this interface to be active.
GENERAL MIDI
Creates a dialog box which can be used to select instruments for specified channels on a General Midi device. This only works if a General Midi device (such as QuickTime) is available. The Current button shows the most recent instrument selections per channel in a window.
LISTENER
A Listener window is opened. Lisp expressions, such as (+ 2 2) can be evaluated in this window.
menu: tools
PLAY
If the object is a section, Midi object, or a community, it can be played. This item plays the object selected in the Objects dialog (Tools>Show Objects). The Objects dialog must be open for an object to be played.
If however, the dialog for Play Selection/Loop is the top dialog, the section specified in that dialog is played. If the Play Selection/Loop dialog is not on top, the selected object in the Objects dialog will be played.
While the object is playing, selecting this item again will stop performance.
PLAY SELECTION/LOOP
A dialog is produced to play a section or Midi object. It is possible to select the start and end points in the object to play. Playing can also loop the selection. The Begin and End times should be set before playback starts.
Events in the selected part of the object can be plotted.
MAKE OBJECT (OR DO ACTION)
The object specified in a dialog can be made with this menu item (or keyboard shortcut) as an alternative to clicking on the Make button. In most other dialogs, the function associated with the button in the lower right corner will be applied with this menu item.
PLOT
Sections and communities can be plotted in various ways. A parameter of a Csound score file or an OSC file can be displayed. 'Other' allows generators, lists, stockpiles, etc. to be plotted. 'Selected Object' plots the most recently selected object in the Objects dialog. This is often the object that was just made; it can therefore be plotted without having to use the button in the Objects dialog.
HISTOGRAM
Sections and communities can have histograms made of the values for the parameters pitch, rhythm, and velocity. If the option 'Print instead' is checked, the values and their frequencies are printed in a window instead of plotted. A histogram can also be made of a Csound score file or a binary OSC file. 'Other' allows a histogram of generators, lists, stockpiles, etc.
TEXT SCORE
A text score is a simple, text representation of the values present in a section.
SELECTED OBJECT AS TEXT
A text version of an object's values is printed. This is available in any case for sections, stockpiles, controllers, and midi performance objects.
FOR EXAMPLE
A generator, tool, or lisp expression can be entered.
A generator is applied a number of times and the results are printed in a window. This allows one to see some examples of using a particular generator. The 'Options' button lets the user change the number of times a generator is applied, specify the number of values that are printed on one line, etc.
If a tool or a Lisp expression is entered in this dialog, the result of applying the expression is printed to a window.
CTRL-CLICKing the DO IT button allows that data to be plotted or used for a histogram.
TEST VALUE
Creates a dialog with boxes where numbers can be entered when a stream is being played. These numbers can be read in the stream by using the generator test-value. See the help for test-value for an example. The only purpose of this dialog is to send values to the test-value generator.
STREAM SLIDERS
Creates an interface with a number of sliders which can be used to provide data when a stream is being played. The data is read and mapped using the generator slider-value. The only purpose of the sliders is to send data to a slider-value generator. See the help for slider-value for an example.
SECTION->CSOUND
Translates an existing section to a Csound file. File options can be chosen in the Csound File Options dialog.
SECTION->OSC FILE
Translates an existing section to a binary OSC file. If desired, the file will be rendered and the resulting audio file can be opened for performance. The rendering is done with scsynth (which is part of the SuperCollider distribution). SuperCollider must be installed in order for the OSC file to be rendered. Options concerning writing, rendering and performing files can be chosen in the OSC File Options dialog.
SHOW OBJECTS
A dialog shows a table with all objects in the environment. The objects in the table can be listed according to their creation time or alphabetically. A popup menu contains the names of all the types of Toolbox objects. When a type is chosen, a table is presented listing all objects of that type that are in the current environment. An object can be chosen from the table, the input of the object can be examined, and various other actions can be requested.
REMOVE OBJECTS
A table containing all objects in the current environment is presented. An object can be chosen and removed from the environment. Default objects such as wilhelmus are not presented in this table.
REMOVE ALL OBJECTS
All objects in the environment (except for default objects such as wilhelmus) are removed. There is a query to make sure you want to do this.
menu: window
CLOSE WINDOW
The top (active) window is closed.
CLEANUP WINDOWS
All AC Toolbox windows except the Objects dialog are closed.
CLEANUP WINDOWS AND OBJECTS
All AC Toolbox windows except the Objects dialog are closed. If objects have been defined, the user is asked if all objects should be removed. This item is intended as a convenience so that the Remove All Objects menu item does not have to be invoked separately.
EXAMPLES WINDOW TO FRONT
If an examples file was loaded and the window listing the examples is open, that window is brought to the front.
The remaining menu items are the titles of windows which exist within the AC Toolbox. Windows may be chosen by selecting a menu item.
(message commands ...)
Message is intended for use with bundle for specifying OSC commands for OSC score objects. The message can contain any number of valid SuperCollider Server commands (example 1).
See the help for BUNDLE for a description.
EXAMPLE 1:
(print-result
(bundle 0 (message "/b_allocRead" 0 "sounds/a11wlk01-44_1.aiff")))
(metric-fractions generator)
Returns a closure. When applied, a fractional value < 1 is returned. GENERATOR should return an integer value. METRIC-FRACTIONS returns 1 divided by that value until the sum would be 1. The number 4 would produce 1/4 1/4 1/4 1/4 (example 1). After the sum is 1, a new divisor is chosen.
GENERATOR can be a generator, list, stockpile, etc. If it produces a non-integer value, that value is truncated to be an integer. (examples 2-3).
The purpose of this generator is to simplify the rhythmic organization of groups of values.
EXAMPLE 1: (for-example (metric-fractions (random-value 1 5)))
EXAMPLE 2: (for-example (metric-fractions '(2 3 4)))
EXAMPLE 3: (for-example (metric-fractions (random-choice '(2 3.5 4.2))))
(metric-pattern n value &optional lower-limit upper-limit)
Returns a list consisting of N values. Each value is an integer divisor of VALUE. Each value is repeated until the sum of the repetitions is equal to VALUE. Then a new divisor is chosen at random.
LOWER-LIMIT is a threshold for the smallest possible divisor that may be chosen.
UPPER-LIMIT is a boundary for the largest possible divisor that may be chosen (examples 1-2).
EXAMPLE 1: (for-example(metric-pattern 40 48))
EXAMPLE 2: (for-example(metric-pattern 40 48 10 24))
(metric-values value &optional lower-limit upper-limit)
Returns a closure. When applied, one value that is an integer divisor of VALUE is returned. Each divisor is repeated until the sum of the repetitions is equal to VALUE. Then a new divisor is chosen at random (example 1).
LOWER-LIMIT is a threshold for the smallest possible divisor that may be chosen. If none is provided, it defaults to 1.
UPPER-LIMIT is a boundary for the largest possible divisor that may be chosen. If none is given, it will equal the value produced by VALUE.
VALUE, LOWER-LIMIT, and UPPER-LIMIT may vary over time. Changes only take effect when a new divisor is chosen (examples 2-3).
Care should be taken when specifying lower and upper limits to make sure that at least one divisor is possible within those limits.
EXAMPLE 1: (for-example (metric-values 48) :number 40)
EXAMPLE 2: (for-example (metric-values '(48 30 35)) :number 40)
EXAMPLE 3: (for-example (metric-values 48 10 20))
microtones
Microtones are expressed as floating-point numbers. 60 is c4. 60.5 is a quarter-tone higher. Any value after the decimal point is possible but may not be meaningful.
To generate floating-point numbers, it is sufficient for most generators or tools to use a floating-point number for one or more of the input parameters (examples 1-2).
If symbols such as c4 are desired to express pitch values, a floating-point value can be produced by enclosing the symbol in the expression float (example 3).
QuickTime (available to all users) and a Capybara or Pacarana (available to some users) can perform microtones. The fractional resolution of the Capybara and Pacarana is higher that the resolution of Quicktime. These output options can be selected via File>>Midi Setup. Other output options will round off the pitch values to integer values (example 4).
To avoid using microtones, do not specify floating-point numbers for pitch (example 5).
Microtones can also be printed in a Text Score via the menu item Tools>>Text Score. There is a check box to allow fractions to be printed.
Section data can be formatted for musical notation using FOMUS (menu item 'File>Write FOMUS File'). FOMUS allows the formatting of output data using quartertones. LilyPond will print quartertones. Applications reading MusicXML data may or may not respond to requests for quartertones.
A list or stockpile of desired microtones can be specified and used as the input to a generator ending with -choice: (example 6).
FROM produces numbers between two limits with a specified step size between values. It could be used to create a list of quarter-tones, etc. (example 7).
ROUND-OFF will round-off input values to multiples of some unit. This unit does not have to be an integer value. Floating-point values can be rounded off to units of .5, .25, etc. (examples 8-9).
A descending MASK1 can be defined (examples 10-11).
This mask can be used to produce values rounded to quarter tones (example 12).
If a mask should be used to read an arbitrary set of microtones (which are not spaced at equal steps from each other), READ-FROM could be used. The stockpile being read is spread on the Y-axis and the mask is used to read from those values. Mask values are considered positions on the Y axis expressed as percentages.
Example 13 uses MASK1.
Various generators and tools produce floating-point values as their standard output. SPECTRUM->PITCH is an example of this. It includes a key word ROUND to allow rounding output to semitones (integers), quartertones (multiples of 0.5), etc..
DEFINE-SCALE returns a closure (generator) which can be used to generate a scale, e.g. to fill a stockpile. The list of intervals can include floating-point numbers (examples 14-17).
EXAMPLE 1: (for-example (random-value 60 72))
EXAMPLE 2: (for-example (random-value 60.0 72))
EXAMPLE 3: (for-example (random-value (float c4) c5))
EXAMPLE 4: (fill-template data-section micro1 100 50 1
(random-value 60.0 63) 64 1)
EXAMPLE 5: (fill-template data-section integers1 100 50 1
(random-value 60 63) 64 1)
EXAMPLE 6: (for-example
(random-choice
'(70.6 71 70.2 67.2 69.8 35.7 53.8 67.7 66.8 54.8)))
EXAMPLE 7: (for-example (random-choice (from 60 72 :step .5)))
EXAMPLE 8: (for-example (round-off (random-value 60.0 72) .5))
EXAMPLE 9: (for-example (round-off (random-value 60.0 72) .25))
EXAMPLE 10: (fill-template specify-mask mask1 '(100 20) '(80 0))
EXAMPLE 11: (plot mask1)
EXAMPLE 12: (for-example
(round-off (convert mask1 20 60.0 72) .5))
EXAMPLE 13: (for-example
(read-from '(35.7 53.8 54.8 66.8 67.2
67.7 69.8 70.2 70.6 71)
mask1 20))
EXAMPLE 14: (define my-scale (define-scale '(1 2 2.5 1)))
EXAMPLE 15: (for-example (my-scale c3) :number 8)
EXAMPLE 16: (fill-template generate-stockpile my-stockpile 24 (my-scale c2))
EXAMPLE 17: (for-example my-stockpile)
midi controller input
The generator EXTERNAL-VALUE reads Midi controller input. The input is mapped between a LOW and HIGH value.
The menu item External-value in the Other menu controls what is used in the EXTERNAL-VALUE generator. If the choice is CONTROLLER NUMBERS, the number of the Midi controller is used regardless of which channel it is received on. The generator (external-value 1 c2 c4) would map the values of Midi controller 1 to be between the Midi note numbers for c2 and c4.
If the choice is CONTROLLER CHANNELS, the channel of the MIDI controller is used regardless of which controller it is. The generator (external-value 1 c2 c4) would map the values of the Midi controller using channel 1 to be between the Midi note numbers for c2 and c4.
See the help for the generator EXTERNAL-VALUE for more information.
midi controller output
Midi controller data can be organized into a MIDI-CONTROLLER-OBJECT either setting just one controller value or changing controller values in a way similar to a data section or density section. Only 7-bit controllers are supported.
A MIDI CONTROLLER VALUE OBJECT will set a Midi controller to one specified value.
When the object made with example 1 is played, the Midi pan controller will be set to 0 which is as far left as it will go. To reset all Midi controllers, the menu option Kill and Reset can be chosen.
A MIDI CONTROLLER DATA OBJECT is specified in a manner similar to the specification of a data section. It represents rhythm as a multiple of a clock unit, and allows controller values and controller numbers to be specified in the customary toolbox manner: as a constant, a list, a stockpile, a function, a generator, etc. The template to produce such an item can be created by selecting the DEFINE>MIDI OBJECT >CONTROLLER DATA menu item (example 2).
The object with contain 100 controller values. Every 100 milliseconds (rhythm 1 * clock unit of 100), a new value generated by random-value will be output when the object is played. The values are assigned to controller number 7 and Midi channel 1.
If the controller should be reset at the end of the object, check the RESET box in the template and enter the value to which the controller should be reset (0-127). After the last value specified for the section, the reset value will be sent.
A MIDI CONTROLLER DENSITY OBJECT is similar to a density section. A certain amount of time (expressed in seconds) is filled with attack points. The attack points are specified using a function which produces values between 0.0 and 100 per cent of the available time. Each attack point will be assigned a controller value, number, and channel all of which can be expressed in the customary manner (constant, list, stockpile, generator, etc.). A controller maintains its value until it receives a new one therefore there is no separate parameter for duration. The template to produce such an item can be created by selecting the CONTROLLER DATA menu item.
In example 3, thirty seconds will be filled with 100 events. The attack points are chosen with random-value to be between 0.0 and 100 per cent of the available time (30 seconds). At each attack point, a controller value between 0 and 127 is sent to controller 7 on Midi channel 1.
To reset the controller at the end of the object, check the RESET box
and enter a reset value.
Attack points can also be entered as a list of values between 0 and 100 (percent). In that case, the number of values entered in the list will determine the number of attack points. The parameter number would be ignored in this case.
Example 4 contains only 11 events, one corresponding to each percentage in the attacks, and not the 100 events indicated in the number parameter.
If a Capybara has been selected as the output device in the Midi Setup, controller values may be floating-point numbers. Currently, controller 1 will be sent to !cc01 in the Capybara. controller 2 will go to !cc02, etc.
Midi controller objects can be combined with other Midi objects and sections in parallel or sequential sections.
EXAMPLE 1: (fill-template make-midi-controller-value-object
pan-left 0 10 1)
EXAMPLE 2: (fill-template controller-data-object data1 100 100 1
(random-value 0 127) 7 1)
EXAMPLE 3: (fill-template controller-density-object dense1 30 100
(random-value 0.0 100)
(random-value 0 127) 7 1)
EXAMPLE 4: (fill-template controller-density-object dense2 30 100
'(0 10 20 30 40 50 60 70 80 90 100)
(random-value 0 127) 7 1)
midi files
IMPORTING MIDI
A Midi file can be imported and used as a section or Midi object. A Midi file containing notes should be imported as a section. A file containing only MIDI controller data should be imported as a controller object. A file containing only program change information should be imported as a program object. A file containing combinations of the above should be imported as a section.
To import a Midi file, use the menu item FILE>IMPORT MIDI.
EXPORTING MIDI
A section or a Midi object can be exported to a Midi file. Midi file formats 1 and 0 are supported. File format 1 supports multiple tracks. The AC Toolbox will write each Midi channel to a separate track. File format 0 uses only one track. Note that Midi files only support the use of integer values for pitch and velocity. If a section being exported contains floating-point values for these parameters, they will be rounded off when exported.
To export a Midi file, use the menu item FILE>EXPORT MIDI.
If the Midi file is to be used in a notation program, the tempo setting may be important to get useful input in the notation program. The tool clock->mm can be used to convert a clock unit in milliseconds to a metronome indication.
EXAMPLE 1: (print-result (clock->mm 100))
midi object
A midi object contains Midi controller values or program changes.
midi objects: filtering
The filter template has no button for filtering midi objects. Instead the option for OTHER filter should be chosen. An expression which will produce an appropriate filter expression should be entered. The idea is similar to what is used with transform: a filter expression is encapsulated in a specifier which indicates which parameter is to be filtered.
E.g.
(controller-filter 'value (low-pass 60))
would create a low-pass filter for controller values.
To see an example of this usage, evaluate example 1 and then select SET PARAMETERS.
The various filters should be entered as a Lisp expression:
(low-pass threshold)
(high-pass threshold)
(band-pass low high)
(band-reject low-high)
(bank low1 high1 low2 high2 ...)
(shot-gun percentage)
The available specifiers:
(controller-filter 'value filter)
(controller-filter 'number filter)
(controller-filter 'channel filter)
(program-filter 'number filter)
(program-filter 'channel filter)
EXAMPLE 1: (fill-template
filter cont2 cont1
(other (controller-filter 'value (low-pass 60)))
'whatever nil)
midi objects: transforming
The transform dialog has no box for choosing a transform for a controller value, for example. To be able to transform a controller value, the whatever box should be used together with a function that specifies that the transform should be applied to the controller value. This function should 'encapsulate' the transform function (example 1).
Other parameters can be transformed by encapsulating a transform in another specifier:
(controller-transform 'number transform)
(controller-transform' channel transform)
The specifier functions for controllers only affect controller messages. If a section contains both note messages and controller messages, only the controller messages will be transformed by a controller-value.
Create a section containing both note messages and controller messages (examples 2-4).
If all three objects were made, a midi-section called p3 should exist. To transpose the pitches in this section by 12 and to transpose the controller-values by 60 see example 5.
To transform program change commands in a midi-program-object or in a section, the whatever parameter should contain a transform encapsulated in an appropriate specifier (example 6). Available specifiers are:
(program-transform 'number transform)
(program-transform 'channel transform).
EXAMPLE 1: (fill-template
transform dense2 dense1
:whatever (controller-tranform 'value (transpose 12)))
EXAMPLE 2: (fill-template data-section
ds1 200 50 (random-value 1.0 2)
(random-value c2 c4) mf 1)
EXAMPLE 3: (fill-template controller-data-object
cont1 50 300 1
(random-value 0 60)
7 1)
EXAMPLE 4: (fill-template parallel-section p3 cont1 ds1)
EXAMPLE 5: (fill-template transform tran1 p3
:pitch (transpose 12)
:whatever (controller-transform
'value (transpose 60)))
EXAMPLE 6: (fill-template transform data3 data2
:whatever (program-transform
'number (compress 25 16)))
midi output using a capybara/pacarana
Midi output can be directed to a Capybara or Pacarana Sound Computation Engine via its firewire interface. Pitch, velocity, and controller data can be floating-point numbers in that case. Integer values may also be used. Program changes can be sent as well.
To select the Capybara or Pacarana as output destination, use Midi Setup. If Capybara/Pacarana does not appear in the output menu, make sure that the firewire interface is on and connected. The button Hunt Capybaras/Pacaranas can be used to take (another) look for the interface.
To use Midi output via a Capybara/Pacarana, Kyma must be started and an appropriate sound loaded in the Capybara. Appropriate means in this context, any sound which responds to incoming Midi data by using expressions such as !Pitch, !KeyDown, etc. Polyphony requires using the MidiVoice object or specifying polyphony on a timeline. Controller data can currently only be sent to !cc01, !cc02, etc. Midi controller 1 in the AC Toolbox will be sent to !cc01 in Kyma.
The AC Toolbox currently is limited to dealing with the first 100 voices on a Capybara or Pacarana.
It is the responsibility of the user to ensure that the Capybara or Pacarana can respond to the data sent by the AC Toolbox. In particular, the user should check the Midi channel for incoming data.
midi program change
Midi program changes can be realized through a MIDI-PROGRAM-OBJECT. Each object has a name, one or more program change messages (program and channel) and relative times at which they should occur.
The most simple of the objects can be created by selecting PROGRAM CHANGE in the MIDI OBJECT menu. One program change and one channel number may be entered. The resulting object can be used in a sequential section to make a program change between sections.
A PROGRAM-DATA-OBJECT is specified similarly to a data section. Rhythm is a multiple of a clock unit in centiseconds. A program change and channel are selected at points corresponding to each rhythmic value.
Using example 1, an object with 10 events will be created. Each event occurs contains a program change command. An events occurs every 200 milliseconds (clock unit 200 * rhythm 1).
If a data section called section1 existed and you wanted a program change for every note of that section, first a program-data-object could be defined and then joined with the section in a parallel section. The rhythm values of section1 could be extracted and used as input for the program-data-object (examples 2-4).
A PROGRAM-DENSITY-OBJECT is specified similarly to a density section. A length of time is specified in sections. A number of attack points are calculated within that time. For each point, a program change and channel are specified (example 5).
If a density section called dense-section1 existed and you wanted a program change for every note in that section, a program-density-object could be defined and then joined with the section in a parallel section. The attack points of section2 can be extracted with (extract 'attack section2) which returns a list of attack points expressed as a percentage value between 0 and 100 (examples 6-8).
Midi program objects can be combined with other Midi objects and/or sections in parallel or sequential sections.
Program changes can also be realized as a stream. Make and play a PROGRAM STREAM to produce program changes in real-time.
EXAMPLE 1: (fill-template program-data-object data1 200 10 1
(random-value 1 32) 1)
EXAMPLE 2: (fill-template data-section section1 100 20
(random-value 1 3)
(random-value c2 c4) mf 1)
EXAMPLE 3: (fill-template program-data-object data2
(get-rhythmic-unit section1)
(get-length section1)
(extract 'rhythm section1)
(random-value 1 32) 1)
EXAMPLE 4: (fill-template parallel-section p1 data2 section1)
EXAMPLE 5: (fill-template program-density-object program1 30 10
(random-value 0.0 100)
(random-value 1 32) 1)
EXAMPLE 6: (fill-template
density-section dense-section1 30 20
(random-value 0.0 100) 50 (random-value c2 c4) mf 1)
EXAMPLE 7: (fill-template program-density-object program2
(get-object-duration dense-section1
:seconds t)
20 (extract 'attack dense-section1)
(random-value 1 32) 1)
EXAMPLE 8: (fill-template parallel-section
p2 dense-section1 program2)
midi setup
The AC Toolbox uses CoreMidi for Midi input/output. It is also possible to use QuickTime Musical Instruments or a Capybara or Pacarana Sound Computation Engine for output. When launched, the Toolbox tries to connect to the most recent Midi setup. If this is not possible, for instance if the devices previously used are not available, the Toolbox will connect to the first thing it finds.
A user can choose from the available input/output possibilies using the menu item MIDI SETUP. The resulting dialog box allows devices to be chosen. Only one input and one output can be specified for use with the AC Toolbox. The choices are put into effect when the user hits the ACCEPT button.
QuickTime and Capybara/Pacarana output accepts floating-point values for pitch. Output to all other destinations will be rounded to integer values.
When the generator External-value is used, an external Midi controller should be attached to an available input port or selected as an input if it appears in the pop-up menu for MIDI SETUP.
If an object is played after the external or virtual Midi connections have been changed, the Toolbox will try and adjust the Midi settings. It may however be necessary to adjust the settings in the the MIDI SETUP dialog. If the dialog is still open, hitting the RESCAN button will update the input and output menus.
Capybara/Pacarana output is only possible via a firewire interface for a Capybara or Pacarana. If a Capybara/Pacarana has previously been selected for output in the AC Toolbox, the program will initialize it on startup if the firewire interface is available. Otherwise, select the button Hunt Capybaras/Pacaranas to look for one. Make sure the interface is on before requesting it.
(midi->hz note-number &key base)
Returns a closure. When applied, a Midi note-number is converted to a frequency value in Hz (example 1).
NOTE-NUMBER may be a constant, list, generator, etc. (examples 2-4).
Keyword BASE is a reference frequency for A4 (or A3, depending on the preference chosen). It defaults to 440.0 Hz (example 5).
This generator could be useful in preparing Csound score files.
EXAMPLE 1: (print-result (make (midi->hz a4)))
EXAMPLE 2: (for-example (midi->hz 60))
EXAMPLE 3: (for-example (midi->hz (major 60)))
EXAMPLE 4: (for-example (midi->hz '(c4 a4 c5)))
EXAMPLE 5: (for-example (midi->hz 60 :base 415))
(midi->notename input &key float)
Returns a closure. When applied, a Midi note number is converted to its alphanumeric representation.
E.g. Midi notenumber 60 is c4. (example 1). The choice for C3 for Midi notenumber 60 (middle C) can be made in the Preferences dialog.
INPUT may be a constant, list, stockpile, generator, etc. (example 2)
When keyword FLOAT is bound to t, the fractional part of a note is printed in parentheses. This is useful if the Midi value being converted is a floating point number and insight into a possible translation to microtones is desired (examples 3-4).
EXAMPLE 1: (print-result (make (midi->notename 60)))
EXAMPLE 2: (for-example (midi->notename (random-value 40 80)))
EXAMPLE 3: (for-example (midi->notename (random-value 40.0 80)))
EXAMPLE 4: (for-example (midi->notename
(random-value 40.0 80) :float t))
(midi-articulation &optional ms)
A tool to either report or adjust the current Midi articulation time. This is the time subtracted from the duration of all notes to increase the time between a note off command and the next note on command.
MS is the time in milliseconds.
To report the current value, see example 1.
Occasionally, a Midi program may require an additional time between notes in order to repeat notes 'properly'. QuickTime Musical Instruments (in some versions) is such a program.
Example 2 will decrease all note durations by 1 millisecond, causing a gap between notes of 1 millisecond. This gap should be enough to allow notes to repeat properly if there had been such a problem.
Changes made with this tool are remembered in the preference file. To set the value to zero, use example 3.
EXAMPLE 1: (print-result (midi-articulation))
EXAMPLE 2: (midi-articulation 1)
EXAMPLE 3: (midi-articulation 0)
midi: repetition problem
Some versions of QuickTime Musical Instruments and perhaps other programs may require additional time between notes in order to repeat correctly. The tool MIDI-ARTICULATION can correct this problem (example 1).
This will subtract one millisecond from each duration when a section is played.
EXAMPLE 1: (print-result (midi-articulation 1))
(mingle stockpile1 stockpile2 ...)
or
(mingle number1 stockpile1 number2 stockpile2 ...)
Returns a list made from interleaving 2 or more stockpiles, lists, sections, etc. If 2 stockpiles are mingled, the resulting list would contain element1 from stockpile1, element1 from stockpile2, element2 from stockpile1, element2 from stockpile2, etc. (example 1).
If the stockpiles are not the same length, the process continues after one stockpile is empty with the elements of the remaining stockpile(s) (example 2).
An unlimited number of stockpiles can be mingled (example 3).
The simplest form of using mingle just specifies a number of stockpiles and one value is taken from each in turn. It is possible to take more values from each stockpile each time. To do that, the second syntax description in the header should be used. For each stockpile, a number indicating the number of elements to take from the stockpile should be specified. If this syntax is used, all stockpiles must have a number specifying how many elements to take (example 4).
The numbers can change over time using a generator (but not a list or stockpile since they would be mingled) (example 5).
It is also possible to mingle the notes in two or more sections. If SECTION1 and SECTION2 exist, they could be mingled in example 6.
EXAMPLE 1: (print-result (mingle '(1 2 3) '(a b c)))
EXAMPLE 2: (print-result (mingle '(1 2 3) '(a b c d e)))
EXAMPLE 3: (print-result
(mingle '(1 2 3) '(10 20 30 40)
'(100 200 300 400 500) '(a b c d)))
EXAMPLE 4: (print-result
(mingle 1 '(1 2 3 4 5)
2 '(100 101 102 103 104 105 106 107 108)))
EXAMPLE 5: (print-result
(mingle (random-value 1 2) '(1 2 3 4 5)
(random-value 2 3)
'(100 101 102 103 104 105 106 107 108)))
EXAMPLE 6: (fill-template note-section
section-m 100 100
(mingle section1 section2) 1)
(mirror center)
Returns a closure. When applied, the value being transformed is mirrored around CENTER. If CENTER is 60, and the value is 55, the result is 65. If the value is 65, the result is 55 (example 1).
CENTER may vary over time using a generator, etc. (example 2).
EXAMPLE 1: (show-transformation (mirror 60)
'(60 62 64 65 59 56 55))
EXAMPLE 2: (show-transformation
(mirror (line 7 60 70))
'(60 62 64 65 59 56 55))
(mix-chords chords number-per-chord)
Returns a closure. When applied, a chord is returned. The closure returns chord1, a mixture of chords 1 and 2, chord2, a mixture of chords 2 and 3, chord3, etc. This can be considered a form of interpolation between chords. A chord is represented as a list of values.
first chord: (49 83 58 69)
second chord: (58 51 60 66)
mixture: (49 83 51 60)
The mixture contains 2 values randomly chosen from each chord.
Example 1 demonstrates the use of a list of chords for CHORDS. NUMBER-PER-CHORD is the number of values taken from each chord. This examples returns the first chord from the list, then a chord made up of 2 values from the first chord and 2 values from the next chord in the list. Then the next chord from the list is returned, followed by a mix of that chord and the following one. The last chord is mixed with the first one.
The generator alternates between a specified chord and a mixture.
NUMBER-PER-CHORD can be a constant, list, generator, etc. Example 2 will mix 3 values from chord 1 and 1 value from chord 2.
CHORDS can be a generator that produces a chord. Suitable generators include MAKE-CHORD, FREQUENCY-SHIFT-CHORD, HARMONIC-CHORD, INTERPOLATE-CHORDS, RING-MODULATE-CHORD, and SPECTRUM->CHORD (examples 3-6).
Chords can be filtered for repetitions and other intervals with CLEANUP-CHORD (example 7).
Chords can be combined into one chord with JOIN->CHORD (example 8).
Chords can be converted to a different range with CONVERT2 (example 9).
This generator is based on a technique used by Tristan Murail. See
Hirs, R. (2009). Frequency-based compositional techniques in the music of Tristan Murail. In R. Hirs and B.Gilmore (eds.), Contemporary compositional techniques and OpenMusic. Paris: IRCAM/Editions Delatour.
EXAMPLE 1: (for-example (mix-chords
'((49 83 68 69)
(58 51 60 66)
(77 67 74 52)) 2)
:number-per-line 2)
EXAMPLE 2: (for-example (mix-chords
'((49 83 68 69)
(58 51 60 66)
(77 67 74 52)) '(3 1))
:number-per-line 2)
EXAMPLE 3: (for-example
(mix-chords
(make-chord (series-value 40 80) 4)
2)
:number-per-line 2)
EXAMPLE 4: (fill-template generate-stockpile chords
4 (make-chord (series-value 40 80) 4))
EXAMPLE 5: (fill-template data-section before 2000 4
1 chords f 1)
EXAMPLE 6: (fill-template data-section after 2000 7
1 (mix-chords chords 2) f 1)
EXAMPLE 7: (show-help 'cleanup-chord)
EXAMPLE 8: (show-help 'join->chord)
EXAMPLE 9: (show-help 'convert2)
(mm metronome)
Converts a metronome indication into a value in milliseconds that is appropriate to use for a clock unit in a section specification (examples 1-2).
It can also be used for some Midi objects and streams.
When used with streams, the metronome value can change over time (example 3). This example controls the clock value using stream slider 1. Stream sliders can be accessed with the menu item Tools>/Stream Sliders.
EXAMPLE 1: (print-result (mm 120))
EXAMPLE 2: (fill-template data-section my-section (mm 140) 20
1 c2 ff 1 0)
EXAMPLE 3: (fill-template data-stream stream1
(mm (slider-value 1 120 600))
1 (rv 40 80) f 1)
(more-than &rest constraints)
Returns a function appropriate for use with WITHOUT. It limits the number of times certain values can be used.
The constraints are the number of times a value can be used, followed by the value that should be constrained. When that number of a certain value has been chosen, WITHOUT will not allow any more of that value to pass.
In example 1, no more than one 3 will be allowed. In example 2, no more than two 60s and two 67s will be allowed. Note that any number of constraints can be specified as long as they are in the form: number value number value ...
It is possible that less than the allowed number of a certain value is chosen (example 3).
At the end of the constraints, it is possible to use the keyword :pitch-class followed by a non-nil value. It that case, the pitch class of values will be compared to the pitch class of the constrained values. In example 4, no more than two Cs will be allowed. Note that c2 is 36, c3 is 48 and c4 is 60.
This tool is related to NO-MORE-THAN which can be used independently to produce a list (example 5).
EXAMPLE 1: (for-example
(without (more-than 1 3) (rv 1 3)))
EXAMPLE 2: (make-histogram
(without (more-than 2 60 2 67) (rv 60 67)))
EXAMPLE 3: (for-example
(without (more-than 100 1) (rv 1 100)))
EXAMPLE 4: (for-example
(without (more-than 2 c4 :pitch-class t)
(rc '(c2 c3 c4 g4 a4 b4))))
EXAMPLE 5: (for-example
(no-more-than '(2 60 2 67) (rv 60 67) :n 20))
(morph thing1 thing2 index &key round exponential curve)
Returns a closure. When applied, the next value from THING1 and the next value from THING2 are morphed (interpolated). If INDEX is 0, the value from THING1 is returned (example 1). If the INDEX is 1, the value from THING2 is returned (example 2). Otherwise a value between the two values is returned proportional to the value of INDEX (example 3).The value returned will always be between the two source values. INDEX is clipped to be in the range 0-1.
THING1, THING2, and INDEX can be a list, stockpile, generator, constant, etc. (examples 4-6).
ROUND defaults to nil, meaning the value is not rounded (or quantized). If ROUND is t, the value is rounded to an integer value (examples 7-8). If ROUND is a number, that number is used to quantize the result (example 9).
By default, the interpolation is linear. For an exponential interpolation, bind keyword EXPONENTIAL to t (example 10). In that case the value for curve is 2.
If a value is bound to CURVE to control the steepness of the curve (example 11), an exponential interpolation is assumed.
This generator is a simpler approach to morphing than the generator MUTATE.
EXAMPLE 1: (for-example (morph '(1 10 20) '(10 20 50) 0))
EXAMPLE 2: (for-example (morph '(1 10 20) '(10 20 50) 1))
EXAMPLE 3: (for-example (morph '(1 10 20) '(10 20 50) 0.25))
EXAMPLE 4: (for-example (morph 10 0 .25))
EXAMPLE 5: (plot (morph (convert sine-shape 100 1 100)
(convert expo-shape 100 1 100)
0.60))
EXAMPLE 6: (plot (morph (line 100 1 100)
(convert sine-shape 100 1 100)
(rc '(0 0.5 1)))
:plot nil)
EXAMPLE 7: (for-example (morph '(1 10) '(4 19) 0.5 :round t))
EXAMPLE 8: (fill-template data-section ds1 100 100 1
(morph (line 100 40 80) (convert sine-shape 100 40 80)
(rc '(0 0.5 1)) :round t)
f 1)
EXAMPLE 9: (for-example (morph '(1 10) '(4 19) 0.5 :round 0.5))
EXAMPLE 10: (plot (morph 0 1 (line 100 0.0 1) :exponential t))
EXAMPLE 11: (plot (morph 0 1 (line 100 0.0 1)
:curve 4))
(ms number generator &optional predicate)
This tool is a shortcut for MAKE&SORT.
It is primarily intended for use in Csound score objects and OSC scores. The START parameter can use this tool to generate a number of start values for events and sort the start times in ascending order (the default situation) (examples 1-1). This can be important if objects such as shapes, masks or stockpiles should be presented in the correct order.
This tool can also be used when ascending lists of numbers are required, e.g. in the transformers INSERT-REST and REPLACE-BY-INDEX.
See the documentation for MAKE&SORT for more information and examples (example 3).
EXAMPLE 1: (for-example (random-value 1 50))
EXAMPLE 2: (for-example (ms 20 (random-value 1 50)))
EXAMPLE 3: (show-help 'make&sort)
(multiple-bandwidths low high ...)
Returns a list containing all integer values between and including LOW and HIGH. There can be several LOW/HIGH pairs and the list will include all integers between them (examples 1-2).
This tool can be used in conjunction with generators with the suffix choice (examples 3-4).
EXAMPLE 1: (for-example (multiple-bandwidths 1 10 20 25))
EXAMPLE 2: (for-example (multiple-bandwidths c1 f#1 d3 a3 g#4 c5))
EXAMPLE 3: (for-example
(random-choice (multiple-bandwidths 20 25 38 43 74 77)))
EXAMPLE 4: (for-example
(beta-choice (multiple-bandwidths 20 25 38 43 74 77).3 .3))
musicxml
MusicXML is an interchange format which can be read by various music notation programs including Sibelius and Finale. Information about MusicXML can be found via example 1.
The AC Toolbox can write data in a format readable by FOMUS, a music notation formatting tool. FOMUS, in turn, can produce a MusicXML file which can be read by Sibelius, etc.
A notation program may not realize all features of MusicXML.
EXAMPLE 1: (open-url "http://www.recordare.com/xml.html")
(mutate source target index mutation-type
&key clumping start offset
override low high)
Returns a closure. When applied one value of the mutant is returned.
MUTATE is based on the morphological mutation functions developed by Larry Polansky and described in the ICMC Proceedings of 1991 and 1992 and in the Journal of New Music Research 25(4). A mutation function creates a transformation (cross-fade) between a source object and a target object.
MUTATE allows the transformation of a source object (list, stockpile, or shape) into a target object (list, stockpile, or shape) of the same length. The source can 'cross-fade' into the target in different ways and to different degrees. The degree of the mutation is expressed with an INDEX value between 0-1. 0 is the minimum mutation. 1 is the maximum mutation.
Different types of mutation functions have been defined.
CONTOUR MUTATIONS transform the source into the target on the basis of the interval direction (or sign).
MAGNITUDE MUTATIONS use the size of the interval (the magnitude), either signed or unsigned.
Five types of mutations are available in the AC Toolbox. They can be indicated by the numbers 1 - 5, by the abbreviations used by Polansky, or by a nickname.
TYPES OF MUTATIONS
Number, Polansky, Nickname
1, LCM, contour
2, IUIM, some-source
3, ISIM, some-target
4, UUIM, all-source
5, USIM, all-target
TYPE 1, LINEAR CONTOUR MUTATION (LCM), uses the sign of the target and the interval of the source if an interval is to be mutated. The number of intervals mutated is determined by the index (examples 1-4).
Source: 72 60
Target: 67 68
Mutation: 72 84
Where M is the mutant, T the target, and S the source:
Mutated intervals: M(i) = M(j) + T(sign) * S(mag)
Non-mutated intervals: M(i) = M(j) + S(sign) * S(mag)
TYPE 2, IRREGULAR UNSIGNED INTERVAL MAGNITUDE MUTATION (IUIM),
uses the sign of the source and the interval of the target (examples 5-6).
Source: 72 60
Target: 67 68
Mutation: 72 71
Mutated intervals: M(i) = M(j) + S(sign) * T(mag)
Non-mutated intervals as above.
TYPE 3, IRREGULAR SIGNED INTERVAL MAGNITUDE MUTATION (ISIM),
uses both the sign and the interval of the target (examples 7-8).
Source: 72 60
Target: 67 68
Mutation: 72 73
Mutated intervals: M(i) = M(j) + T(sign) * T(mag)
Non-mutated intervals as above.
TYPE 4, UNIFORM UNSIGNED INTERVAL MAGNITUDE MUTATION (UUIM),
mutates all interval magnitudes of the source by a percentage of the difference of the source interval magnitudes and the target interval magnitudes. The percentage is determined by the index. In this mutation, the absolute value of the difference is used. In Type 5, the actual value of the difference is used (examples 9-10).
Source: 72 60
Target: 67 68
Mutation: 77 54
Note that the first value is also mutated. The initial previous value for the source and for the target is 0.
Mutation: M(i) = M(j) + S(sign)
* (S(mag) + index * |T(mag) - S(mag)|)
TYPE 5 UNIFORM SIGNED INTERVAL MAGNITUDE MUTATION (USIM),
mutates all interval magnitudes of the source by a percentage of the difference of the source interval magnitudes and the target interval magnitudes. The percentage is determined by the index. This is a simple crossfade (example 11-12).
Source: 72 60
Target: 67 68
Mutation: 67 68
The initial previous value for the source and for the target is 0.
Mutation: M(i) = M(j) + Sint + index * (Tint - Sint)
where Sint = S(sign) * S(mag)
and Ting = T(sign) * T(mag)
The degree of the mutation is expressed with INDEX. 0 is no mutation. 1 is the maximum mutation. The effect of changing the index can be seen in examples 13-15.
INDEX can be a constant value, a list, a stockpile, or a closure. If INDEX is not a constant, its value will change for each mutation.
The mutations which are made may be evenly spread throughout the mutation or they may be 'clumped' together. The CLUMPING factor (0-1) together with the index controls the 'spread' of the mutations. With an index of 0.5 and a clumping factor of 1, the mutations would be maximally clumped (example 16).
The default clumping value is 0. Clumping can be a constant value, a list, a stockpile, or a closure. If clumping is not a constant, its value will change for each mutation.
START controls the place in the mutation where clumping begins. 0 is the beginning of the mutation and 1 is the end of the mutation (example 17).
The default value for start is 0.
OFFSET is the initial value in the mutation. By default it is 0 and can probably be left at this value.
OVERRIDE can be t or nil. By default it is nil. If it is t, a solution is used to the theoretical problem that an interval or a sign would be 0. If it is nil, this imperfection is not corrected. (See Polansky (1992) for a discussion.)
A mutation could result in very large or very small values. If the mutation is being mapped into MIDI note numbers for example, a limit on the minimum and maximum value should be placed. By default the smallest possible result of this function is 0 and the highest is 127. These values can be changed with the keywords :LOW and :HIGH. Values below or above these values will be clipped (example 18).
Mutations can be combined. When a type 1 mutation is performed, followed by a type 2 mutation, the target is reached when the index is 1. See the help for COMBINE-MUTATION for more information.
This generator is based on code contributed by Maarten van Walstijn.
EXAMPLE 1: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 1)))
EXAMPLE 2: (plot '(72 60 63 65 66 67 70 72)
:min 50 :max 100 :title "Source" :replace nil)
EXAMPLE 3: (plot
'(67 68 67 65 63 70 58 58)
:min 50 :max 100 :title "Target" :replace nil)
EXAMPLE 4: (plot
(produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1 1))
:min 50 :max 100 :title "Type 1" :replace nil)
EXAMPLE 5: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 'some-source)))
EXAMPLE 6: (plot
(produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1 2))
:min 50 :max 100 :title "Type 2" :replace nil)
EXAMPLE 7: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 'ISIM)))
EXAMPLE 8: (plot
(produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1 3))
:min 50 :max 100 :title "Type 3" :replace nil)
EXAMPLE 9: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 4)))
EXAMPLE 10: (plot
(produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1 4))
:min 50 :max 100 :title "Type 4" :replace nil)
EXAMPLE 11: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 5)))
EXAMPLE 12: (plot
(produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1 5))
:min 50 :max 100 :title "Type 5" :replace nil)
EXAMPLE 13: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0 1))
:recycle nil)
EXAMPLE 14: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 1))
:recycle nil)
EXAMPLE 15: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
1 1))
:recycle nil)
EXAMPLE 16: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 1 :clumping 1)))
EXAMPLE 17: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 1 :clumping 0.5 :start 0.5)))
EXAMPLE 18: (print-result (produce 8
(mutate '(72 60 63 65 66 67 70 72)
'(67 68 67 65 63 70 58 58)
0.5 3 :low 65 :high 80)))
(mv top bottom n new-top new-bottom
&key conversion generator distance round)
This generator is a shortcut for MASKS&VALUES.
When applied, a point on a top line and a point on a bottom line are produced. A returned value is chosen randomly between those two points.
The two lines can be seen as describing a tendency mask. This generator could produce an endless series of mask segments and values chosen from them.
The first point on the top line is TOP. The first on the bottom line is BOTTOM. The next point will move along those lines so that the Nth point will be NEW-TOP and NEW-BOTTOM.
After N points have been produced, new values for N, NEW-TOP, and NEW-BOTTOM are generated. Points will be produced between the current values and the new values. Then new values for N, NEW-TOP, and NEW-BOTTOM are produced. And so on.
The output of the generator is a value chosen between the current points on the two lines.
N, NEW-TOP, NEW-BOTTOM and DISTANCE can vary over time and therefore can be constants, lists, stockpiles, generators, etc (example 1).
Additional examples can be found in the documentation for MASKS&VALUES (example 2).
EXAMPLE 1: (plot (mv 80 40 100
(rv 30 90)
(rv 30 90))
:number 500)
EXAMPLE 2: (show-help 'masks&values)
(no-more-than constraints generator &key (n 100) pitch-class (stop 500))
Returns a list of N values produced by applying GENERATOR. CONSTRAINTS should be specified to limit the occurence of certain values.
If CONTRAINTS is the list '(1 3 2 1), there will be no more than 1 occurence of the value 3 and 2 occurences of value 1 (examples 1-2). Depending on the values produced by GENERATOR, there could be fewer of the constrained values.
CONSTRAINTS can be a list or stockpile.
GENERATOR can be a generator, list, or stockpile.
N has the default value of 100. It can be set to any other integer (example 3).
There can be any number of constraints as long as they are expressed as number value number value ... (example 4).
CONSTRAINTS may contain symbols such as c4 for the values (example 5).
Values that are not constrained will occur until a total of N values have been produced (example 6). In this example, after one 3 and two 1s have been chosen, all the remaining values with be 2.
If N values cannot be produced using the given constraints, the function will stop after STOP attempts (example 7).
When N is bound to nil, the function will stop as soon as all constraints have been met (example 8).
When PITCH-CLASS is bound to t, the pitch class of the value is compared to the pitch class of the constraint (example 9). In this example, no more than two Cs will occur, regardless of their octave.
If behavior similar to NO-MORE-THAN is wanted as a generator instead of in the form of a tool that produces a list, see MORE-THAN which can be used with the generator WITHOUT (example 10).
EXAMPLE 1: (for-example
(no-more-than '(1 3 2 1) (rv 1 3)))
EXAMPLE 2: (make-histogram
(no-more-than '(1 3 2 1) (rv 1 10)))
EXAMPLE 3: (for-example
(no-more-than '(2 60) (rv 60 72)
:n 20))
EXAMPLE 4: (make-histogram
(no-more-than '(5 60 3 64 7 67) (rv 60 72))
:print t)
EXAMPLE 5: (for-example
(no-more-than '(2 c4 3 g4) (rc '(c4 e3 g4 a4 b4))
:n 20))
EXAMPLE 6: (for-example
(no-more-than '(1 3 2 1) (rv 1 3) :n 20))
EXAMPLE 7: (for-example
(no-more-than '(1 60) (rv 60 60)))
EXAMPLE 8: (for-example
(no-more-than '(2 60 1 64 1 67) (rv 60 67)
:n nil))
EXAMPLE 9: (for-example
(no-more-than '(2 c4) (rc '(c1 c3 g3 a3 b3))
:n nil :pitch-class t))
EXAMPLE 10: (for-example
(without (more-than 1 3 2 1) (rv 1 3)))
(noise-choice n sequence type)
Returns a closure. When applied, one element of the sequence is returned. The choice of element is made according to a fractional noise distribution.The type of fractional noise is determined by TYPE which can range from 0 to -4. 0 is white, -1 is 1/f (or pink), -2 is brownian, and any value < -2 is black (examples 1-5).
N is the (estimated) total number of values to generated with this generator.
TYPE can vary over time.
EXAMPLE 1: (for-example (noise-choice 20 '(a b c d e f g h i) 0))
EXAMPLE 2: (for-example (noise-choice 20 '(a b c d e f g h i) -.5))
EXAMPLE 3: (for-example (noise-choice 20 '(a b c d e f g h i) -1))
EXAMPLE 4: (for-example (noise-choice 20 '(a b c d e f g h i) -2))
EXAMPLE 5: (for-example (noise-choice 20 '(a b c d e f g h i) -4))
(noise-value n a z type &key round (scale 1))
Returns a closure. When applied, one number between A and Z is returned according to a fractional-noise distribution. The type of fractional noise is determined by TYPE which can range from 0 to -4.
0 is white, -1 is 1/f (or pink), -2 is brownian, and any value < -2 is black. TYPE does not have to be an integer. Type -1.5 is between pink and brown.
The type of the result is determined by the type of A and Z. N is the approximate number of values to be generated with this generator. A, Z, and TYPE may vary over time.
100 values of various types of noise (examples 1-6):
Example 1 is white noise (type 0).
Example 2 has -.5 for type.
Example 3 is 1/f noise (type -1).
Example 4 has -1.5 for type.
Example 5 is brownian noise (type -2)
Example 6 is black noise (type -3).
Example 7 plots several types of noise, each with a different range.
To quantize the result with another unit, bind ROUND to a quantization unit (example 8).
In example 9, the value for TYPE changes every 100 values.
In example 10, the values for A and Z continuously change. Since the result of using generator LINE is a real number, the values for NOISE-VALUE are rounded to semitones (1).
Due to the nature of the algorithm used to produce the values for this generator, values A and Z will probably never be reached. One way to deal with this feature is to use CONVERT to produce a number of values and map them to the range A to Z (example 11).
Another way to change the range of this generator is to bind the keyword SCALE to a value other than 1 (the default). SCALE multiplies the result of the algorithm before it is mapped to the range A to Z. If necessary, the result is clipped to be in the range A to Z (examples 12-13).
EXAMPLE 1: (plot (noise-value 100 1 100 0)
:title "0" :min 1 :max 100 :replace nil)
EXAMPLE 2: (plot (noise-value 100 1 100 -.5)
:title "-0.5" :min 1 :max 100 :replace nil)
EXAMPLE 3: (plot (noise-value 100 1 100 -1)
:title "-1" :min 1 :max 100 :replace nil)
EXAMPLE 4: (plot (noise-value 100 1 100 -1.5)
:title "-1.5" :min 1 :max 100 :replace nil)
EXAMPLE 5: (plot (noise-value 100 1 100 -2)
:title "-2.0" :min 1 :max 100 :replace nil)
EXAMPLE 6: (plot (noise-value 100 1 100 -3)
:title "-3.0" :min 1 :max 100 :replace nil)
EXAMPLE 7: (plot-many 100 "Types (bottom to top): 0,-1,-2,-3"
(noise-value 100 1 50 0)
(noise-value 100 50 100 -1)
(noise-value 100 100 150 -2)
(noise-value 100 150 200 -3))
EXAMPLE 8: (for-example (noise-value 100 1.0 100 -2 :round 0.25))
EXAMPLE 9:
(fill-template data-section nv-section1 100 400 1
(noise-value 400 40 80 (group '(0 -1 -2 -3) 100)) f 1)
EXAMPLE 10:
(fill-template data-section nv-section2 100 200 1
(noise-value 200
(line 200 40 60) (line 200 80 65) -1.5)
f 1)
EXAMPLE 11: (plot (convert (noise-value 200 40 80 -.5)
200 40 80))
EXAMPLE 12: (plot (noise-value 200 40 80 -.5)
:min 40 :max 80)
EXAMPLE 13: (plot (noise-value 200 40 80 -.5 :scale 2)
:min 40 :max 80)
notation for a score
The AC Toolbox can convert section data to data appropriate for FOMUS, a music notation formatting tool. FOMUS in turn can produce data suitable for the LilyPond notation program or for the interchange format MusicXML which can be read by Sibelius, Finale, and other programs.
In the best case, the result can be considered a rough image of some note data that may be useful for informing compositional decisions.
FOMUS is intended to rationalize pitch and rhythm data to achieve a result more useful than importing Midi files into a notation program.
Various options can be entered via the dialog created by 'File>Write FOMUS File'. A discussion of their use can be found in the help (found under the ? button) in the previously-mentioned dialog. Further information can be found in the FOMUS documentation.
The user should install FOMUS (example 1) and a suitable notation program such as LilyPond (example 2) or a program that can read MusicXML. Additional information about MusicXML can be found via example 3.
Note that not all programs respond with equal sensitivity to the commands of MusicXML. Various features may not be realized.
LilyPond (in connection with FOMUS) does respond to data for quartertones.
The FOMUS installer puts FOMUS in /usr/local/bin. This is where the AC Toolbox assumes it is.
LilyPond (if used) should be in the Applications folder because that is where FOMUS expects to find it. It may be necessary to double-click LilyPond the first time it is used before trying to use it with FOMUS.
EXAMPLE 1: (open-url "http://fomus.sourceforge.net/")
EXAMPLE 2: (open-url "http://lilypond.org")
EXAMPLE 3: (open-url "http://www.recordare.com/xml.html")
note section
A section where notes are expressed as a combination of the parameters rhythm, pitch, velocity, and channel. Notes can be made with note structures (a-note, in-sequence, etc.) or with generators which can deal with notes, e.g. chaotic-notes.
note structure
A note structure is a note, a rest, a delay, or some combination of these structures. Note structures allow the specification of a known group of pitches, chords, and rests.
(note-channel note-structure)
This tool is primarily intended to program Lisp functions that manipulate notes. It also pops up occasionally for use with other tools, such as derive-transition-table.
Given a note structure, note-channel will return the channel (example 1).
Get-stockpile will return a list of note structures when applied to other note structures or to a section (example 2).
The tools NOTE-PITCH, NOTE-RHYTHM, and NOTE-VELOCITY also exist.
EXAMPLE 1: (print-result (note-channel (a-note 1 60 64 1)))
EXAMPLE 2: (print-result
(mapcar #'note-channel (get-stockpile wilhelmus)))
(note-pass-filter)
Produces a filter that will filter out anything that is not a note, e.g. controller values or program changes, from a section.
This filter should be used with the method FILTER.
Choose OTHER as the filter type then use (note-pass-filter) to produce the filter. The parameter should be WHATEVER. If the start times of the notes are not to be changed, the check box LEAVE GAPS should be checked.
If Section1 exists, example 1 will filter out everything but note information.
EXAMPLE 1: (fill-template filter section1f section1
(other (note-pass-filter))
'whatever t)
(note-pitch note-structure)
This tool is primarily intended to program Lisp functions that manipulate notes. It also pops up occasionally for use with other tools, such as derive-transition-table.
Given a note structure, note-pitch will return the pitch (example 1).
GET-STOCKPILE will return a list of note structures when applied to other note structures or to a section (example 2).
The tools NOTE-RHYTHM, NOTE-VELOCITY, and NOTE-CHANNEL also exist.
EXAMPLE 1: (print-result (note-pitch (a-note 1 60 64 1)))
EXAMPLE 2: (print-result
(mapcar #'note-pitch (get-stockpile wilhelmus)))
(note-rhythm note-structure)
This tool is primarily intended to program Lisp functions that manipulate notes. It also pops up occasionally for use with other tools, such as derive-transition-table.
Given a note structure, note-rhythm will return a rhythmic value (example 1).
Get-stockpile will return a list of note structures when applied to other note structures or to a section (example 2).
The tools NOTE-PITCH, NOTE-VELOCITY, and NOTE-CHANNEL also exist.
EXAMPLE 1: (print-result (note-rhythm (a-note 1 60 64 1)))
EXAMPLE 2: (print-result
(mapcar #'note-rhythm (get-stockpile wilhelmus)))
(note-velocity note-structure)
This tool is primarily intended to program Lisp functions that manipulate notes. It also pops up occasionally for use with other tools, such as derive-transition-table.
Given a note structure, note-velocity will return the velocity (example 1).
Get-stockpile will return a list of note structures when applied to other note structures or to a section (example 2).
The tools NOTE-PITCH, NOTE-RHYTHM, and NOTE-CHANNEL also exist.
EXAMPLE 1: (print-result (note-velocity (a-note 1 60 64 1)))
EXAMPLE 2: (print-result
(mapcar #'note-velocity (get-stockpile wilhelmus)))
objects: code object
A code object is a place to store Lisp code. When this object is applied, the code is evaluated and can be used in various Toolbox expressions. The code must be evaluated before it is available for use. A code object can be saved in the environment, together with other objects. When an environment is loaded, the code object is made but is not evaluated. To use the code contained in the object, it must be explicitly evaluated (with the Apply button).
It is also possible to develop and evaluate Lisp code in the Lisp Editor (File>Text>New). This code is saved to a text file which must be loaded before it is available. It is not saved as part of the environment.
An example of a code object can be found in Help>Dialog Examples. It is called Code Object: Code1.
objects: community
A community is a group of sections joined in name only. A community can provide a mechanism for manipulating sections according some grouping.
The idea of a community is that all members act together while retaining their individual identities.
A community is an useful way to make a transformation involving several sections. Or to produce a group of sections which are variants of one input specification.
objects: controller
A controller is used to control parameter values on a larger scale. It maintains state, outside the scope of an object definition. A controller remembers what it has done and the next time it will provide the next value.
A controller can be used as an input in an edit box in another object. Each time that object is made (or varied), the next value from the controller will be produced.
A controller could be used to determine how many values each variant of a generated sequential section should have. A controller can have a list of values or a generator or a function as input. Each time the controller is used, the next value from the list or generator will be used.
Imagine that 10 sections will be created. The number of values per section is determined by a controller. If the controller is a list '(10 20 30), then the first section created will have 10 values, the second section 20 values, the third section 30 values, the fourth section 10 values, and so on. If a controller is not used and a list with '(10 20 30) is entered directly into the NUMBER edit box, each time the object is made, the first value (10) will be used.
objects: csound objects
Csound objects hold information that can be used to generate a score file for Csound. The object does not contain the score file but merely the information that can be used to generate one.
Csound objects may be combined in sequence or in parallel.
When combined in sequence, each Csound object in the sequence is applied to produce part of the data for a score file. Each time an object is applied, it produces new data (unless it only contains deterministic input). The data from one object comes after another in time.
When combined in parallel, each Csound object starts at the same time (or later if an offset is provided).
When Csound objects are combined, the start time for the data may be adjusted to correspond with the sequential or parallel nature of the combination. In these cases, the calculation times for any function generation statements (f statements) included in the header are not changed.
objects: mask
A mask is represented by two lines. It is a field which changes over time. Values can be calculated to be within a mask. Calculating values within a mask allows parameter values to change in time. CONVERT is a tool that can be used with masks to convert them to some useable parameter values.
objects: midi objects
Midi objects allow other Midi commands (MIDI controller values and program changes) to be created. These objects can be played or used to create a Midi file. They also can be mixed with other midi objects or sections in a parallel section.
A controller density object allows a time to be filled with Midi controller values. A controller data object produces Midi controller values in a fashion similar to a data section. A controller value object sets a Midi controller to a fixed value. A multi Midi controller object allows several controllers to be described in one object.
Program density objects, program data object, and program change objects produce Midi program change commands.
Midi objects can be combined in parallel sections.
objects: note structure
A note structure is a note, a rest, a delay, or some combination of these structures. Note structures can be combined in sequence or in parallel. A note structure could also contain a section. Note structures can be used in defining a structured section or a note section. Note structures allow the specification of a known series of pitches, chords, and rests.
A note is made with (a-note rhythm pitch velocity channel) (examples 1-2).
RHYTHM values are multiples of a clock unit that is specified when a section is made.
PITCH can be MIDI note numbers or a known symbol, such as C4.
If PITCH is a list, a chord is produced.
VELOCITY is a MIDI value (0-127) or a known symbol, such as MF.
CHANNEL is specified between 1-16.
A rest is made with (a-rest rhythm).
Rhythm values are multiples of a clock unit that is specified when a section is made. When used within another structure, this object represents a rest of a certain length (example 3).
A delay is made with (a-delay time-in-milliseconds).
The TIME-IN-MILLISECONDS represents an actual amount of time for a rest and is not a multiple of a clock time.
Example 4 would wait 1 second in a note structure.
To join note structures in sequence:
(in-sequence structure1 structure2 ...)
The note structures included in the sequence are interpreted to occur one after another (in sequence). An indefinite number of structures can be included in sequence (example 5) .
To join note structures in parallel (at the same time):
(in-parallel structure1 structure2 ...)
The note structures included in parallel are interpreted to occur at the same time (example 6).
Note that both IN-SEQUENCE and IN-PARALLEL accept sections as input. Several sections could occur in parallel as follows: (in-parallel section1 section2 section3)
EXAMPLE 1: (print-result (a-note 1 c4 mf 1))
EXAMPLE 2: (print-result (a-note 1 60 64 1))
EXAMPLE 3: (print-result (a-rest 2))
EXAMPLE 4: (print-result (a-delay 100))
EXAMPLE 5: (print-result (in-sequence (a-note 1 60 mf 1)
(a-rest 3)
(a-note 1 67 mf 1)))
EXAMPLE 6: (print-result (in-parallel (a-note 2 c4 mf 1)
(a-note 1 c#4 f 2)))
objects: osc scores
OSC score objects hold information that can be used to generate a binary OSC file. The object does not contain the score file but merely the information that can be used to generate one.
OSC scores may be combined in sequence or in parallel.
When combined in sequence, each OSC object in the sequence is applied to produce part of the data for an OSC file. Each time an object is applied, it produces new data (unless it only contains deterministic input). The data from one object comes after another in time.
When combined in parallel, each OSC score starts at the same time (or later if an offset is provided).
An OSC Score Bunch object contains one or more bundles (of OSC messages). This object may be convenient if other OSC score objects need to include additional bundle information (such as a message for allocating and filling a buffer).
The tool INSIDE-OSC can be used to update parameters during one score event.
objects: scheme of variations
A scheme of variations contains the names of objects that are to be made in a certain order. When the scheme is applied, those objects are made in that order. If an object is made as part of a scheme, the previous output of that object is lost.
A scheme of variations is useful when you want to specify dependencies of objects upon each other. E.g. if a shape is changed, the sections using that shape should also be redefined.
A scheme of variations is also useful when you want to work in a top-down fashion. First, the specifications for all objects will be made. The specifications can be made in an order that is convenient and logical to the user without worrying if the objects that are needed have already been defined or not. Finally, all object names should be included in a scheme. Later the objects will be made in the order specified in the scheme of variations.
objects: section
An important activity when using the Toolbox to create note information is the definition of sections. A section is a general term referring to part or all of a musical composition involving note data. A section can be listened to, exported as a MIDI file, imported from a MIDI file, printed as a text score, plotted, examined via histograms, combined with other sections (in sequence, in parallel, or starting at certain times). A section can be transformed in many ways.
A section contains a list of notes represented with MIDI values, their durations expressed in milliseconds, and their start time relative to the beginning of a section.
A section can contain one or more notes. In this way it can fulfill many different roles: note, phrase, section, voice, movement, composition, etc.
Different ways of defining sections have been included.
In a DATA SECTION, input for each of the parameters (rhythm, pitch, velocity, and channel) is separate.
In a NOTE SECTION, notes are expressed as a combination of those four parameters.
In a STRUCTURED SECTION, an object called a note structure must be entered.
In a DENSITY SECTION, time is the paramount parameter. Time is filled with either a function or a shape.
Sections can be combined in sequence (sequential section), in parallel (parallel section), or by specifying start times (timed section). A parallel section can be generated by varying an existing section several times and combining those outputs in parallel (generate parallel section). A sequential section can be generated in a similar manner (generate sequential section).
Examples of appropriate input for each of these types of sections can be found via the menu item 'Help>Dialog Examples'.
objects: shape
A shape is an abstraction reflecting some motion over time. A shape can be drawn with a mouse, expressed as a series of evenly spaced values, or created using a generator.
Shapes can be used to create values for various input parameters. Shapes can be used to determine pitch in a data section. Or to express the tempo changes in a transformation of a section, etc. CONVERT is a tool that can be used with shapes to convert them to some useable parameter values.
Some default shapes have been included in the environment. They can be seen Objects dialog (Tools>Show Objects).
objects: stockpile
A stockpile is a collection of values that are available to be used. A user may wish to define various stockpiles of source material and them make choices from these stockpiles using generators. A stockpile is the standard input to a generator ending with -choice, e.g. random-choice.
Stockpiles can be specified value for value, can be created using a generator, or they can be constructed with some other available tool. A combination of existing stockpiles can also be generated.
objects: stream
Streams can go on forever. Like water from a faucet, a stream continues until it is turned off. Several streams can be played at the same time as a parallel stream. Data streams and Note streams produce note on and note off commands. Controller streams produce Midi controller values. Multi-controller streams can produce Midi controllers values for up to five Midi controllers. Program streams produce Midi program change commands.
Streams can be combined in parallel by making a parallel stream and specifying the streams to combine. A parallel stream can also be generated by cloning an existing stream, such as a data stream, a number of times with the dialog Generate Parallel Stream.
Streams can be controlled externally by a Midi controller. If a stream uses the generator EXTERNAL-VALUE it will read and scale values from a Midi input device.
Streams can also receive values from the Test Value dialog. If a stream uses the generator TEST-VALUE, it will read values from boxes in the Test Value dialog.
Streams can be started and stopped with the play dialog or in the show objects dialogs for streams or all objects.
(on-the-fly object1 operator1 object2 &rest expressions)
Returns a closure. When applied, OPERATOR1 (e.g. +) is applied to one result from OBJECT1 and one from OBJECT2. The objects may be constants, lists, stockpiles, or generators as is customary in the AC Toolbox.
The functionality is similar to the generator COMBINE except that infix notation is used and the operator does not require a function quote (#'). Also, more than one operation can be done in series. Infix notation has the operator between the 2 operands. In Lisp, normally you have the function first and then the data to which it is applied (examples 1-4).
Since ON-THE-FLY is a generator, it produces one value each time it is applied. In the example with the stockpile, each time the generator is applied, the next value from the stockpile is read and 100 is added to it. In the example with the list, each time the generator is applied, the next value from the list is read and added to a new random number produced by the generator rv.
Several operators can be used. They will be evaluated from left to right, as is the case with SuperCollider and unlike the normal custom of mathematics (example 5).
Semitone frequency values between A 440 Hz and an octave higher could be produced (example 6). (from 0 1 :step 1/12) produces a list of values from 0 to 1 at a distance of 1/12. expt in this example raises 2 to each power from the list produced by FROM. That result is multiplied by 440. Each time the generator is applied, the next value from FROM is returned and used in this expression.
ON-THE-FLY expressions can be nested. The preceding formula for frequencies could be rewritten as in example 7.
To manipulate other objects such as shapes, they should first be converted to lists. Example 8 multiplies a sine shape by a random value.
Examples-9-10 can be used to generate a shape object.
Pitch deviation could be generated with on-the-fly (examples 11-12).
Values can be quantized using the operator ROUNDQ. The next value should be the quantization unit (examples 13-14).
Alternatives to using ON-THE-FLY are APPLY-FUNCTION, and COMBINE.
A tool that is similar is CAL. It wil produce a fixed number of results. ON-THE-FLY will produce a new result each time it is applied (examples 15-16).
OTF is a shortcut for ON-THE-FLY (example 17).
EXAMPLE 1: (for-example (on-the-fly 2 * 2))
EXAMPLE 2: (fill-template construct-stockpile
stock (from 1 10))
EXAMPLE 3: (for-example (on-the-fly stock + 100))
EXAMPLE 4: (for-example (on-the-fly '(10 20 30) + (rv -1.0 1.0)))
EXAMPLE 5: (for-example (on-the-fly 3 + 2 * 2))
EXAMPLE 6: (for-example
(on-the-fly 2 expt (from 0 1 :step 1/12) * 440)
:number 13)
EXAMPLE 7: (for-example
(on-the-fly 440 * (on-the-fly 2 expt (from 0 1 :step 1/12)))
:number 13)
EXAMPLE 8: (plot
(on-the-fly (convert sine-shape 100 0.0 1) * (rv -1.0 1)))
EXAMPLE 9: (fill-template generate-shape mul-shape 100
(on-the-fly (convert sine-shape 100 0.0 1) * (rv -1.0 1)))
EXAMPLE 10: (plot mul-shape)
EXAMPLE 11: (fill-template data-section ds1
100 100 1 (on-the-fly 60 + (rv -5.0 5.0)) mf 1)
EXAMPLE 12: (fill-template data-section ds2 100 100 1
(on-the-fly (convert expo-shape 100 48 72)
+ (rv -5.0 5.0)) mf 1)
EXAMPLE 13: (for-example
(on-the-fly (from 1 20) + (rv -1.0 1) roundq 0.25))
EXAMPLE 14: (for-example (on-the-fly (line 15 1.0 20) * 2 roundq 1))
EXAMPLE 15: (for-example (cal '(10 20 30) + (rv -1.0 1)))
EXAMPLE 16: (for-example (on-the-fly '(10 20 30) + (rv -1.0 1)))
EXAMPLE 17: (for-example (otf '(10 20 30) + (rv -1.0 1)))
(open-url string)
OPEN-URL will open an url supplied as a string in a browser window.
Example 1 makes an internet connection and opens (if possible) the browser page from the AC Toolbox. If the tool does not open the browser, try opening the browser 'by hand' before evaluating the expression.
EXAMPLE 1: (open-url "http://www.actoolbox.net")
osc
OSC (OpenSound Control) is a protocol for communicating among computers, synthesizers, etc. which was developed at CNMAT, Berkeley. Among its uses is the network control of audio programs.
For more information, see example 1.
EXAMPLE 1: (open-url "http://www.cnmat.berkeley.edu/OpenSoundControl/")
osc files: filtering
Binary OSC files can be filtered using the dialog produced by 'Methods>Filter>OSC File'. The result of the filtering operation is a new file. The original file is not changed.
Select an OSC file by clicking on the 'Select' button.
It is possible to filter up to four parameters in the file using this dialog. If a parameter is to be filtered, enter the argument name as it occurs in the Synthdef. Arguments names are case sensitive. Select a filter type for that argument using the corresponding popup menu. Parameters, such as a threshold value for a low-pass filter must be specified. To do this, click the button 'Set Parameters' and fill in the appropriate value(s).
If the filter type is 'None', the corresponding argument will not be filtered.
When a file is filtered, OSC bundles are examined. If a bundle is allowed to pass, it is copied to a new file. If the bundle is filtered away, it is not copied.
If a low-pass filter with a parameter of 500 is being applied to argument 'freq', any bundle containing a 'freq' value <= 500 will be allowed to pass. Otherwise the entire bundle is ignored.
If more than one filter have been specified, a choice must be made on how to combine the results of the filters to determine if a bundle should be copied or not. If 'Or' is selected, a bundle is copied if one ore more of the filters would allow it to be copied. If 'And' is selected, it is copied only if all of the filters would allow it to be copied.
Combining filters with 'And' can be useful when filtering different arguments, e.g. when selecting only those bundles where 'dur' is below a certain value and 'freq' is above another value.
Only one filter may be used per argument. Filters can however be combined in a lambda expression as a parameter for the 'Other' filter. To apply first a low-pass filter and then a high-pass filter, the following expression could be used in Other filter:
#'(lambda (x) (and (funcall (high-pass 900) x) (funcall (low-pass 1000) x)))
More information about writing Lisp expressions to use for a filter of type 'Other' can be found in Help>Lisp>Your Own.
When the filtered file is made, it will be rendered or not according to the various options in the OSC File Options dialog.
OSC files that were made using INSIDE-OSC for one or more the parameters cannot be filtered.
osc files: transforming
Binary OSC files can be transformed using the dialog produced by Methods>Transform>OSC File. The result of the transformation is a new file. The original file is not changed.
Select an OSC file of either type clicking on the 'Select' button.
It is possible to transform up to four parameters in the file using this dialog. If a parameter is to be transformed, enter the argument name as it occurs in the Synthdef. In the corresponding edit box, fill in a transformer expression such as (transpose 500) which would add 500 to the value of the corresponding arg. Available transformers can be found in the Annotated Index (Help>Annotated Index).
Argument names are case sensitive.
A transformer is applied to the specified argument of every bundle in the OSC file. Other arguments are not changed.
Only one transforer can be applied to an argument. COMPOSE can be used to combine transformers. To add 1000 and then a random deviation of 10% to a value, the following could be entered as a transformer:
(compose (random-deviation 10) (transpose 1000))
When the transformed file is made, it will be rendered or not according to the various options in the OSC File Options dialog.
The transformation can be limited to be only between specified start times. This is done with the tool AT-OSC-TIME.
osc score
An OSC score object contains the specification to generate a binary OSC file which can be rendered to an audio file.
osc score bunch
One or more bundles of OSC messages. Bundles are expressed with the bundle tool. A score bunch can be used together other OSC score objects.
(osc-frame time-in-seconds)
Returns a closure. When applied, a time value in seconds is converted to a frame number for use in reading buffers in OSC messages.
The time value is multipled by the current sampling rate that is used for rendering the binary OSC files to audio.
In a synthdef, ugens such as PlayBuf have an argument for the frame position to start playback. OSC-FRAME can be used to calculate this position.
TIME-IN-SECONDS can change over time (examples 1-2).
EXAMPLE 1: (for-example (osc-frame 0.5))
EXAMPLE 2: (for-example (osc-frame (random-value 1.0 10))
:number-per-line 1)
osc: parallel objects
OSC score objects can be combined in parallel in 2 ways. The groups of objects can be specified by name or the group can be generated using a generator etc. to determine the order of the available scores. In both cases, each time another score object is applied, it is generated anew.
SPECIFY OBJECTS AND THEIR OFFSET
To specify a group of score objects to be joined in parallel, use the OSC Scores>Parallel scores' menu item. In the space for score objects, the names of score objects can be entered (example 1).
As many objects as desired can be entered. The objects can be OSC score objects, sequential OSC score objects, parallel OSC score objects and/or OSC Score bunches.
The start of an object can be delayed by a time specified as a number (in seconds). If no offset is desired, no number need be entered. The time offset is not the time between objects (as is the case with a sequential score) but the time since the beginning of the parallel score object (example 2).
In example 2, osc1 and osc2 will start at the same time. The second instance of osc1 will start 3 seconds later. Note that the two applications of osc1 may result in different events (depending on the way that osc1 was specified). If score1 contains generators with random aspects, the files will probably be different.
GENERATE OBJECTS AND THEIR OFFSET
To generate a group of score objects to occur in parallel, use the menu item Osc Scores>Generate parallel scores.
The number of score objects to be generated, something to produce an offset value (from the beginning of the parallel object), and a generator etc. to choose the group of score objects should be entered (example 3).
The offset value can be a constant, list, generator, etc. If the offset is 0, all scores will start at the same time. In any case, the first score always starts at time 0. The offset is applied to the start time of the remaining scores.
The scores can be chosen with a generator as in the above example. A list could be given in which case the scores occur in the same order as they occur in the list (example 4).
The name of a single score could be used (example 5).
EXAMPLE 1: (fill-template create-parallel-osc-score-object
osc-par1 osc1 osc2)
EXAMPLE 2: (fill-template create-parallel-osc-score-object osc-par2
osc1 osc2 3 osc1)
EXAMPLE 3: (fill-template generate-parallel-osc-score-object
gen-osc-par1 3
(random-value 0.0 2)
(random-choice '(osc1 osc2)))
EXAMPLE 4: (fill-template generate-parallel-osc-score-object
gen-osc-par2 3
(random-value 0.0 2)
'(osc1 osc2))
EXAMPLE 5: (fill-template generate-parallel-osc-score-object
gen-osc-par3 3
(random-value 0.0 5)
osc1)
osc: score objects
An OSC score object can be used to specify an algorithm to generate a binary OSC file. When an object is specified, the algorithm is saved but no file is generated. When an object is applied, the specification is saved and a binary OSC file is generated. This file can be rendered to an audio file within the AC Toolbox which in turn will use SuperCollider Server (scscynth) to do this. To render a binary OSC file, SuperCollider must be installed.
OSC score objects can be joined in sequence or in parallel which means that when applied, several objects will be generated and the values saved as part of one file.
Sequential OSC objects are described in the help for OSC: Sequential Objects.
Parallel OSC objects are described in the help for OSC: Parallel Objects.
The remainder of this text describes the use of the dialog box for an OSC score object.
An OSC score will generate a binary file containing bundles of OSC messages. Each bundle includes a time indication when the message should be sent. Messages typically will assign one or more arguments used in a SuperCollider synthdef some value at the specified time. Synthdefs used in conjunction with the AC Toolbox are assumed to have a duration parameter and are expected to turn themselves off after that amount of time.
INCLUDE
An OSC file might need to send other bundles in additional to those that are generated. These bundles could do things such as allocate and read buffers. Such bundles can be specified in Include. A bundle specification looks like this:
(bundle 0 (message "/b_allocRead" 0 "sounds/a11wlk01-44_1.aiff"))
One or more bundles may occur in Include. Instead of specifying bundles, the name of an OSC score bunch object containing one or more bundles can be entered in Include. Note that these two forms cannot be mixed. Either bundles are enter as shown above OR the name of a OSC score bunch is entered. An OSC score bunch can be made with menu item Define>OSC Scores>Bunch of Bundles.
If no additional bundles are needed, Include may be left blank.
SYNTHDEF
Synthdef is the name of an available SuperCollider synthdef. The synthdef is compiled in the SuperCollider language and written to the default synthdefs folder. Once the synthdef has been compiled, it remains available for subsequent use.
The following synthdef is used in these examples. It should be compiled in the SuperCollider language application.
(
SynthDef("sine1",{ arg freq = 440, amp = 0.2, dur = 1.0, attack = 0.25, decay = 0.25;
var ss = 1 - attack - decay;
Out.ar(0,
SinOsc.ar(freq, 0,amp)
* EnvGen.kr(Env.linen(attack,ss, decay,1), timeScale: dur, doneAction: 2)
)
}).writeDefFile;
)
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
LAYERS
In the OSC file, one or more layers can be produced. Layers are parallel combinations of outputs. The parameter LAYERS may be a constant, list, generator, etc.
NUMBER
Number is the number of events in a layer. It may be a constant, list, generator, etc.
START
If start is a constant number, the first start-time in the file will be this value. Subsequent values for the start-time of events will be the previous value plus the previous duration. If start is a generator, list, etc., the values for all of the actual start-times will be produced with it. Start-times are expressed in seconds.
DURATION
Duration is the length of each event and is expressed in seconds.
The argument name for duration should be the name used in the synthdef. Each synthdef used in combination with an OSC score object should have a duration parameter. The name of the parameter does not matter, but it should be able to turn off the synthdef. One way to do this is with doneAction: 2 in an envelope specification.
The argument value may be a constant, list, generator, etc.
EXAMPLE
In example 1, a score object will be made using synthdef sine1 with only three arguments specified: dur, freq, and amp. The arguments names are the names used in the synthdef. A duration must be specified. If other arguments are not specified, the default values in the synthdef will be used. The duration argument needs to specified in the fields labeled Duration. The order of the other arguments does not matter.
When the specify button is used, the information in this dialog is saved as an object. When the apply button is used, the information is saved and a binary OSC file with 50 events is produced. By default, this binary file will also be rendered to an audio file. Various options concerning the audio header, sample format, etc. of the audio file can be set using OSC File Options (Other>OSC File Options).
RESTS
Negative durations produce rests. The values produced for the other arguments are lost (if there is a rest). This produces 'gaps' in the file as if holes had been shot in it. The file will only contain the events which are not rests (example 2).
UNTIL-TIME
UNTIL-TIME can be used to determine the number of values to be calculated. UNTIL-TIME indicates that events should be generated until a certain length of time in seconds has been reached. It can only be used if START is a constant value.
When the score file from example 3 is made, events will be generated until 10 seconds have been filled. The last event is not truncated to fit within the 10 seconds but is allowed its full duration. This could mean that the total length of the score is longer than 10 seconds.
The use of UNTIL-TIME assumes that duration is expressed in seconds.
In example 3, FROM-NUMBER was used to convert line-shape for P4. (from-number) returns the number of events calculated to fill 10 seconds.
USING A GENERATOR FOR START
In example 4, the start-times of the events are randomly chosen between 0.0 and 20 seconds. Note that the events are no longer in chronological order. If that is important, for instance because a mask or shape is being used in another parameter, the start-times should be sorted using make&sort. An example using make&sort is given later.
USING A SHAPE TO DETERMINE THE DENSITY
DENSITY-OF-START-TIMES makes a list of start times by mapping a shape to represent density varying between a minimum and maximum value.
In example 5, LINE-SHAPE represents a linearly increasing density that is mapped between 1 event per second to 10 events per second in the course of 10 seconds.
The NUMBER parameter is related to the number of events generated by the DENSITY-OF-START-TIMES expression by using (from-start-times) as input.
SEVERAL LAYERS
In example 6, generators are made again for each layer. This means that they forget their history and start at the beginning (though not necessarily with the same results). In this example, freq uses the WALK generator. The walk for each layer will start at 440 Hz. SCALE-BY-LAYERS scales the maximum amplitude value per layer according to the number of layers.
SHAPES OR MASKS
If one of the parameters is to be derived from a shape or a mask, it is important that the start-times be in ascending order. If a constant value is used for start-time, there is no problem. If a generator is used for start-time, it is possible that the order of the shape or mask is destroyed after the events are sorted. To prevent this, you should sort the start-times using the tool MAKE&SORT.
In examples 7-8, twenty values made by the generator RANDOM-VALUE are sorted and returned in a list.
EXTRA
The dialog for extra may contain names and values for additional arguments. Data for an unlimited number of parameters can be included in this dialog. Data should be in the form: name value. NAME should be the argument name. VALUE may be a generator, list, constant, etc. (example 9)
Synthdef sine1, as defined above, recognizes the parameters attack and decay. Those arguments will be used. Sine1 does not recognize the parameters niks, nada, etc. These are just used to show how 'real' parameters could be specified if needed.
RELATING PARAMETERS
Amplitude can be derived from frequency by using a lookup table. Frequency values are entered in the table with the desired amplitude for that frequency. Generator LOOKUP will use a frequency value as input and return the amplitude value related to the nearest frequency.
Example 10 defines a frequency stockpile.
Example 11 defines an amplitude lookup table.
The chosen frequencies can be seen with example 12.
Some related amplitude values can be seen with example 13.
An OSC score object can be made using both (example 14).
PER LAYER
This box can be used to indicate which (if any) objects that have already been defined should be remade before each layer is calculated. When an object is remade, the input specification is used to make a new output which replaces the previous output of that object.
For example, the frequency stockpile made in the previous example could be
remade for each layer. Each layer would have a new choice of frequency values
but each layer could relate its frequencies to the amplitude table (example 15).
Several objects can be remade per layer. If only 1 layer is specified, the objects are remade before the first layer is calculated.
PER SCORE
This box can be used to indicate which (if any) objects that have already been defined should be remade before each score object is calculated. When an object is remade, the input specification is used to make a new output which replaces the previous output of that object.
When an object is remade per score, this would allow all layers to use the same object but each time the score is applied, a new object would be made for use in all layers.
OVERLAPPING START TIMES
The generator OVERLAP can be used to guarantee that start times for adjacent events will overlap. The amount of overlap can be a time value in seconds (example 16).
The amount can also be expressed as a percentage of the previous duration (example 17).
Note the use of FROM-OVERLAP for the duration parameter when the generator OVERLAP is used.
UPDATING PARAMETERS
A parameter value can be changed during an event by using INSIDE-OSC. This will generate new values and send them to the current event according to the times created by the rhythm parameter of INSIDE-OSC. Example 18 produces a frequency glissando using INSIDE-OSC. A new frequency value is sent to the current event every 0.01 seconds. The event has a duration between 1-10 seconds followed by a rest of between 1 and 1.5 seconds.
MISCELLANEOUS
When an OSC score object generates a file, the name can be supplied by the user or the AC Toolbox can be asked to supply a name. In the latter case, the prefix entered in the OSC File Options dialog will be used for the file name, followed by consecutive, increasing numbers. The choice of which format to use and the available options can be specified in the dialog created by Other>OSC File Options.
Various choices regarding the rendering of the OSC binary file to an audio file can be specified in the OSC File Options dialog. These options include the type of audio header (aiff or wav), the sample format (including 16, 24, and 32-bit integers as well as 32-bit floating point numbers), the sample rate, etc.
SuperCollider produces text when a binary OSC file is rendered. If there is some mistake, such as a buffer file cannot be found, looking at this text can be useful. The text is printed in the Text Output window. On the other hand, if thousands of events are generated for the OSC file, printing the text indicated when each event started might be considered a waste of time. For these reasons, it is possible to turn printing on and off in the OSC File Options dialog.
EXAMPLE 1: (fill-template osc-score-object osc1
50 "sine1" nil nil nil 1 0
"dur" (random-value 0.05 0.1)
"freq" (series-value 900 1000)
"amp" 0.3)
EXAMPLE 2: (fill-template osc-score-object osc2
50 "sine1" nil nil nil 1 0
"dur" '(1 -1)
"freq" '(100 200 300 400 500)
"amp" 0.3)
EXAMPLE 3: (fill-template osc-score-object osc3 (until-time 10)
"sine1" nil nil nil 1 0
"dur" (random-value 0.1 0.2)
"amp" 0.3
"freq" (series-value 415 466))
EXAMPLE 4: (fill-template osc-score-object osc4
10 "sine1" nil nil nil 1
(random-value 0.0 20)
"dur" (random-value 0.5 1)
"amp" 0.3
"freq" (random-value 100 1000))
EXAMPLE 5: (fill-template osc-score-object osc5
(from-start-times) "sine1" nil 'nil 'nil 1
(density-of-start-times 10 line-shape 1 10)
"dur" (random-value 0.5 1) "amp" 0.1
"freq" (random-value 220 880))
EXAMPLE 6: (fill-template osc-score-object osc6
100 "sine1" nil nil nil 5 0
"dur" (random-value 0.1 0.2)
"amp" (scale-by-layers 0.5)
"freq" (walk 440 (random-value -10.0 10)
100.0 2000))
EXAMPLE 7: (for-example (make&sort 20 (random-value 0.0 10)))
EXAMPLE 8: (fill-template osc-score-object osc7
20 "sine1" nil nil nil 1
(make&sort 20 (random-value 0.0 10))
"dur" (random-value 1.0 2)
"amp" 0.2 "freq"
(convert line-shape 20 200.0 400))
EXAMPLE 9: (fill-template osc-score-object osc8
20 "sine1" NIL 'NIL 'NIL 1 0 "dur" 1 "amp" 0.5
"freq" (RANDOM-VALUE 400.0 800) "attack" 0.01
"decay" (RANDOM-VALUE 0.2 0.7)
"niks" 1 "nada" 0.2
"nothing" (RANDOM-VALUE 1.0 20000000)
"whatever" 10 "something" '(10 20))
EXAMPLE 10: (fill-template generate-stockpile freqs
100 (random-value 100.0 3000))
EXAMPLE 11: (fill-template construct-stockpile amp-table
(make-lookup-table 100 0.5 800 0.3 1200 0.1
2000 0.01))
EXAMPLE 12: (for-example freqs)
EXAMPLE 13: (for-example (lookup freqs amp-table :interpolate t))
EXAMPLE 14: (fill-template osc-score-object osc9
100 "sine1" nil nil nil 1 0
"dur" (random-value 0.1 0.2)
"freq" freqs
"amp" (lookup freqs amp-table :interpolate t))
EXAMPLE 15: (fill-template osc-score-object osc10
100 "sine1" nil '(freqs) nil 5 0
"dur" (random-value 0.1 0.2)
"freq" freqs
"amp" (scale-by-layers
(lookup freqs amp-table :interpolate t)))
EXAMPLE 16: (fill-template osc-score-object osc11
10 "sine1" NIL NIL NIL 1
(overlap 0 (random-value 0.5 1.5) 0.25)
"dur" (from-overlap) "amp" 0.4
"freq" (random-value 100.0 1000))
EXAMPLE 17: (fill-template osc-score-object osc12
10 "sine1" nil nil nil 1
(overlap 0 (random-value 0.5 1.5) 50 :percent t)
"dur" (from-overlap) "amp" 0.2
"freq" (random-value 100.0 1000))
EXAMPLE 18: (fill-template osc-score-object osc13
10 "sine1" nil nil nil 1 0
"dur" (take 1 (rv 1.0 10) 1 (rv -1 -1.5))
"freq" (inside-osc 0.01
(generate-line 400
(rv 100 1000)
(rv 50 3000) :exponential t))
"amp" 0.1)
osc: sequential objects
OSC score objects can be combined in sequence in 2 ways. The sequence of objects can be specified by name or the sequence can be generated using a generator etc. which will choose from among available scores. In both cases, each time another score object is applied, it is generated anew.
SPECIFY A SEQUENCE OF OBJECTS
To specify a sequence of score objects, use the OSC Scores>Sequential scores menu item. In the space for score objects, the names of score objects can be entered (example 1).
As many objects as desired can be entered. The objects can be OSC score objects, sequential OSC score objects, parallel OSC score objects and/or OSC Score bunches.
A time delay between objects can be specified as a number (in seconds). If no delay is desired, no number need be entered (example 2).
In example 2, a gap of 3 seconds will occur between the end of osc2 and the beginning of osc1. Note that the two applications of osc1 may result in different events (depending on the way that osc1 was specified). If osc1 contains generators with random aspects, the files will probably be different.
If an OSC score bunch object is used, it should come before any other score object which may need the results of the message it sends.
GENERATE A SEQUENCE OF OBJECTS
To generate a sequence of score objects, use the menu item OSC Scores>Generate Sequential Scores.
The number of scores to be generated, something to produce an offset value (between the scores), and a generator etc. to choose the sequence of scores should be entered (example 3).
The offset value can be a constant, list, generator, etc. If the offset is 0, there will be no time gap between the end of one score and the beginning of another.
The scores can be chosen with a generator as in the above example. A list could be given in which case the scores occur in the same order as they occur in the list (example 4).
The name of a single score could be used (example 5).
Note that the times indicated in any bundles in the Include box, will be adjusted to correspond to the beginning of the score in which they occur.
EXAMPLE 1: (fill-template create-sequential-osc-score-object
osc-seq1 osc1 osc2)
EXAMPLE 2: (fill-template create-sequential-osc-score-object
osc-seq2 osc1 osc2 3 osc1)
EXAMPLE 3: (fill-template generate-sequential-osc-score-object
gen-osc-seq1 5
(random-value 1.0 2)
(random-choice '(osc1 osc2)))
EXAMPLE 4: (fill-template generate-sequential-osc-score-object
gen-osc-seq2 5
(random-value 1.0 2)
'(osc1 osc2))
EXAMPLE 5: (fill-template generate-sequential-osc-score-object
gen-osc-seq3 5
(random-value 1.0 3)
osc1)
(otf object1 operator1 object2 &rest expressions)
OTF is a shortcut for ON-THE-FLY (example 1).
See the help for generator ON-THE-FLY for more information (example 2).
EXAMPLE 1: (for-example (otf '(10 20 30) + (rv -1.0 1)))
EXAMPLE 2: (show-help 'on-the-fly)
(overlap start-time duration amount &key percent)
Returns a closure. When applied, a start time and duration are calculated for a CSound or OSC file.. The start time for the next event in the score file will overlap the previous one by AMOUNT. The time unit for START-TIME, DURATION and AMOUNT is seconds (example 1).
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
In the score file made by example 1, each event begins 0.25 seconds before the previous one is finished. Note that overlap is used for the START parameter.
Since DURATION is typically not a constant value, FROM-OVERLAP can be used to fill in the generated durations for the Csound score dialog parameter DURATION (example 2).
A similar output could be realized as an OSC score object (example 3).
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
If START-TIME is a generator, it is applied once to calculate the initial start time (example 4).
DURATION and AMOUNT can be a constant value, generator, stockpile, etc.
If the keyword PERCENT is bound to t, AMOUNT is considered to be a percentage in the range 0-100. That percentage of the previous duration will determine where the next event will be begin (examples 5-6).
The value for AMOUNT can also be negative which means there will not be an overlap, but rather a gap (example 7).
OVERLAP is intended to produce granular textures with a guarantee that grains will overlap (unless a negative AMOUNT is used, in which case the guarantee is that grains will not overlap).
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 10 1
(overlap 0 1 0.25)
1 0.6 (random-value 100.0 1000))
EXAMPLE 2: (fill-template csound-score-object score2
"f1 0 8192 10 1
f2 0 8193 20 2 1"
nil nil 1 10 1
(overlap 0 (random-value 0.5 1.5) 0.25)
(from-overlap) 0.6 (random-value 100.0 1000))
EXAMPLE 3: (fill-template osc-score-object osc-score2 10 "sine1" NIL NIL NIL 1
(overlap 0 (random-value 0.5 1.5) 0.25)
"dur" (from-overlap) "amp" 0.5
"freq" (random-value 100.0 1000))
EXAMPLE 4: (fill-template csound-score-object score3
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 2 10 1
(overlap (random-value 0.0 2)
(random-value 0.5 1.5) 0.25)
(from-overlap) 0.3 (random-value 100.0 1000))
EXAMPLE 5: (fill-template csound-score-object score4
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 10 1
(overlap 0 (random-value .5 1.5) 50 :percent t)
(from-overlap) 0.3 (random-value 100.0 1000))
EXAMPLE 6: (fill-template osc-score-object osc-score3
10 "sine1" nil nil nil 1
(overlap 0 (random-value 0.5 1.5) 50 :percent t)
"dur" (from-overlap) "amp" 0.2
"freq" (random-value 100.0 1000))
EXAMPLE 7: (fill-template csound-score-object score5
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 10 1
(overlap 0 (random-value .5 1.5)
(random-value -1.0 -0.5))
(from-overlap) 0.3 (random-value 100.0 1000))
(par parameter)
Returns a closure that can be used when defining a Csound score object. This is the only possible use of this generator. When the closure is applied, the current value for a parameter of a Csound score is returned.
Parameters in Csound scores are basically generated in order, p1,p2,p3 .... PAR can only access a lower-numbered parameter (i.e. one that has already been generated). The creation order of p2 (start time) and p3 (duration) has various dependencies to accomodate constructions such as until-time. Accessing p2 and p3 in those fields might not lead to the desired results.
PARAMETER can be the number of the Csound p-field: 1,2,3,4,5,6,... or the symbols number, instrument, start, duration. Number returns the number of events in this layer of the score. Instrument returns the instrument number. Start returns the start time. Duration returns the duration value. 4 would return the value of p4.
In general, any parameter can access a lower-numbered parameter. In any case, any parameter > 3 can always do that. P5 for instance can access number, instrument, start, duration, and p4.
To have frequency dependent on duration (the longer the duration, the lower the frequency), this expression could be used for the frequency parameter:
(on-the-fly 100.0 / (par 'duration))
The value 100.0 is divided by the value for duration (in p3). If duration is .1, frequency is 1000. If duration is .5, frequency is 200.
Assuming an instrument (such as instrument 2 in test csound.orc in the Support/FileExamples folder) where p4 is for frequency and p5 for amp, PAR could be used as in example 1.
Again assuming frequency as p4 and amp as p5, amp is dependent on frequency in example 2.
For each amplitude value, the frequency value in p4 is read and compared to some boundaries. If p4 > 700, the generator (rv 500 1000) is chosen which produces rather small amplitudes. Otherwise, p4 is compared to 400. If larger, (rv 1000 2000) is used, producing larger amplitudes. In all remaining cases, p4 is <= 400 and (rv 10000 15000) is used for amplitude.
PAR is a generator and can only be used when a generator is appropriate in a Csound score object.
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 50 2 0 (random-value 0.1 0.5)
(on-the-fly 100.0 / (par 'duration)) 0.2)
EXAMPLE 2: (fill-template csound-score-object score2
"f1 0 8192 10 1
f2 0 8192 20 2 1"
nil nil 1 50 2 0
(rv 0.1 0.2) (rv 200.0 1000)
(act-if (par 4) > 700
(rv 0.01 0.05)
else > 400 (rv 0.05 0.1)
else (rv 0.2 0.4)))
parallel section
A section made by combining two ore more sections, communities, or midi objects in parallel. Combining sections in parallel means that the notes of the sections will be layered and heard at the same time. Combining a community in parallel means that the members of the community will be combined in parallel. If a community consists of 5 sections, those 5 sections will be heard at the same time.
A time offset expressed in seconds can be entered between the objects. The following object will delay starting that amount of time. This offset has no effect on other objects.
(pass-stockpile-filter stockpile)
This tool will produce a filter which selects a value if it is found in the stockpile. It should be used with the FILTER method or with FILTER-STOCKPILE.
To use with the FILTER method: choose OTHER as the filter type.
STOCKPILE may be a list or a stockpile object.
If SECTION1 exists, it can be filtered with example 1. Only notes which have a pitch of 60 or 64 or 67 will be passed. Everything else will be filtered out.
Example 2 uses the tool with FILTER-STOCKPILE.
EXAMPLE 1: (fill-template filter section1f section1
(other (pass-stockpile-filter '(60 64 67))) 'pitch t)
EXAMPLE 2: (print-result
(filter-stockpile '(1 2 3 4 5 6 7 8 9 10)
(pass-stockpile-filter '(2 4 6 8))))
(peaks? stockpile)
If STOCKPILE contains data returned by READ-SPECTRUM-FILE, the number of spectral peaks is printed in the Text Output window and also returned as a numerical value.
Example 1 will create a stockpile. Select the sample file 'test spear bassoon.txt' from Support/FileExamples.
Example 2 prints and returns the number of peaks. The purpose of this tool is to remind the user about the number of peaks if it is forgotten for some reason. It also returns the number of peaks in spectra produced by SPECTRUM->MIRROR and LIMIT-SPECTRUM.
To recall the number of tracks in data returned by READ-TRACKS-FILE, use tool TRACKS?.
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (print-result (peaks? spectrum1))
(pendulum x y omega damp bigomega bigA giant &key eye xy (stepsize 0.01) first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x'=y
y'=-omega^2sinx-cy+Acos(Bigomega*t)
The default output variable is X. By using the keyword EYE the variable Y is returned. Both variables will be returned in a list by using the keyword XY.
X and Y set the initial values for place and velocity. OMEGA is the frequency of the non-driven pendulum, while DAMP is its damping. BIGOMEGA and BIGA are the values of the frequency and amplitude of the driving force.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
By setting the values for BIGOMEGA and BIGA to zero,the system behaves like a free oscillating (damped) pendulum (example 1).
A driven pendulum starts off with a transient after which it reaches a steady state oscillation (example 2).
Sometimes the steady state part of the oscillation is reached after a long chaotic transient (example 3).
Sometimes the steady state will never be reached (example 4).
It is not easy to predict the maximum and minimum of the output values. To map the output of this function to useful values, use CONVERT (example 5).
The initial values for X and Y are not returned. If the initial values should be returned as the first result of the generator, keyword FIRST should be bound to t (examples 6-7).
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (pendulum 1.0 1.0 2.5 0.9 0.0 0.0 10))
EXAMPLE 2: (plot (pendulum 1.0 1.0 2.5 0.5 1.4 3.8 10)
:number 300)
EXAMPLE 3: (plot (pendulum 1.0 1.0 2.5 0.5 1.99 3.8 10)
:number 350)
EXAMPLE 4: (plot (pendulum 1.0 1.0 2.5 0.5 1.8 3.8 10)
:number 500)
EXAMPLE 5: (for-example
(convert (pendulum 1.0 1.0 2.5 0.5 1.8 3.8 10) 100 c2 c5))
EXAMPLE 6: (for-example (pendulum 1.0 1.0 2.5 0.9 0.0 0.0 10))
EXAMPLE 7: (for-example
(pendulum 1.0 1.0 2.5 0.9 0.0 0.0 10 :first t))
(pentatonic start)
Returns a closure. When applied, a note number corresponding to the next value in a pentatonic scale is generated. The first value in the series is START. The series could continue indefinitely (examples 1-2).
EXAMPLE 1: (for-example (pentatonic 60) :number 8)
EXAMPLE 2: (for-example (pentatonic 55) :number 8)
(phrase-groupings section parameter new-value-generator &key other)
Determines phrase groupings according to Tenney's theory of Temporal Gestalt Perception of Music (Journal of Music Theory 24,2). In short, this theory states that a new group begins when an interval (of some parameter) is larger than the interval preceding it and the interval following it.
Every time a new group begins, NEW-VALUE-GENERATOR (a generator or a list) should provide a value that will be added to the current value in the section being transformed. If the parameter being transformed is ATTACKS and the parameter being grouped is PITCH, the result would be a rest before each new group begins. Example 1 defines a section that is transformed in example 2.
A rest of between 100 and 300 milliseconds will be added before each group boundary. The boundaries are determined by pitch. If pitch contains chords (i.e. a list of pitches to begin at one time point), the average values of the pitches in a chord is used as the pitch of the chord. (This is not part of Tenney's theory).
PITCH, DURATION, ATTACKS, and VELOCITY are the parameter that can be used with PHRASE-GROUPINGS to determine the phrase boundaries. If a parameter other than attacks is being transformed with this transformer, the key word :OTHER should be true:
(phrase-groupings s1 'pitch 20 :other t)
This transformer currently only works with sections.
EXAMPLE 1: (fill-template data-section s1 100 100 1 (rv 40 80) f 1)
EXAMPLE 2: (fill-template transform s1t s1
:attacks (phrase-groupings
s1
'pitch (random-value 100 300)))
(pick low high &key step)
PICK is a shortcut for the generator SERIES-VALUE.
It returns one value from a set of values between LOW and HIGH each time it is applied. No element of the set is repeated until all elements have been returned once (example 1).
STEP is the distance between the values in the set. The default value is 1. The type of STEP determines the type of the result (example 2).
A repetition check occurs so that no repetition occurs between the last value chosen from one stockpile and the first value chosen from the replenished stockpile.
See the documentation for SERIES-VALUE for more information (example 3).
To make matters confusing, SRV has been added as another shortcut for SERIES-VALUE. SRV is considered to be more consistent with the current naming practice for shortcuts.
EXAMPLE 1: (for-example (pick 1 5))
EXAMPLE 2: (for-example (pick 1 5 :step 0.5))
EXAMPLE 3: (show-help 'series-value)
(pick-editor-font)
This tool allows setting the font of the Lisp editor to a fixed width font. It must be set to a fixed width font (example 1).The choice is not remembered between sessions.
The intended use of this tool is to increase the size of the Lisp editor font for making presentations. Otherwise the only choices are in the preferences for font and dialog size.
EXAMPLE 1: (pick-editor-font)
(piecewise number a b number2 c number3 d ...)
Returns a closure. When applied, the next value is returned. Linear sequences of numbers are produced: NUMBER values are evenly spaced between A and B (example 1).
If one of the numbers in a pair of low and high values is a real number, the resulting numbers will be reals (example 2).
A function indicating how the numbers should be converted to integers can be included as the last argument (example 3).
Additional line segments can be specified by including NUMBER2 and C (example 4). This produces 11 steps from 1 to 11 and 10 back to 1.
Any number of additional segments can be specified (examples 5-6). Note that in example 6, the last segment (20.0 in 5 steps to 1) produces real numbers.
Unlike most generators, PIECEWISE does not have a keyword for ROUND. This is because an unlimited number of segments can be specified as input. The result of this design choice is that quantizing to other units is a bit messy. To do this, a lambda expression could be used as the last argument. In example 7, the values will be quantized with the unit .25.
EXAMPLE 1: (for-example (piecewise 20 1 10))
EXAMPLE 2: (for-example (piecewise 20 1.0 10))
EXAMPLE 3: (for-example (piecewise 20 1.0 10 #'round))
EXAMPLE 4: (for-example (piecewise 11 1 11 10 1) :number 21)
EXAMPLE 5: (for-example (piecewise 10 1 10 5 20 5 1))
EXAMPLE 6: (for-example (piecewise 10 1 5 5 20.0 5 1))
EXAMPLE 7: (for-example (piecewise 20 1.0 5 #'(lambda (x) (roundq x 0.25))))
pitch
Pitch is expressed as midi note numbers (0-127). Pitch may be also be represented as a lettername with an octave: c4 is Midi note number 60. c#4 is 61. df4 is also 61. Via the 'Preferences' dialog, it is possible to assign Midi note number 60 to the symbol c3. All other input symbols for pitch are then adjusted accordingly.
QuickTime and Capybara/Pacarana Midi output can play floating-point numbers (microtones). 60.5 is a quarter-tone higher than 60. Any value after a decimal point may be specified in the AC Toolbox for pitch. Capybara/Pacarana output has a higher fractional resolution than does QuickTime.
Midi output sent to other destinations will be rounded to integers. Pitch data in Midi files is also limited to integer representations.
In a data section, if a single value is a list, it is considered to be a chord:
'((60 64 67) (62 67 69)) represents 2 chords.
(pitch-and-octave pitch octave)
Returns a closure. When applied, a MIDI note number or a chord is produced. PITCH can be in any range, but it is reduced to 0 - 11 as the representation of the pitch class. 0 is C, 1 is C#, etc.
The resulting note number or chord is moved to an octave determined by OCTAVE.
By default, middle C is octave 4. C4 is midi note number 60. This can be changed in the preferences to be octave 3. In that case, c3 is note number 60.
When middle C is octave 4, OCTAVE can have values from -1 to 9.
PITCH and OCTAVE can be constants, lists, stockpiles, or generators (examples 1-4).
The value derived from PITCH may also be a chord (list of pitches) (examples 5-6).
SPREAD can be used as a shortcut for PITCH-AND-OCTAVE (example 7).
EXAMPLE 1: (for-example
(make (pitch-and-octave 0 4)))
EXAMPLE 2: (for-example
(pitch-and-octave 60 (from -1 9)))
EXAMPLE 3: (for-example
(pitch-and-octave (major 60) (random-value 0 4)))
EXAMPLE 4: (for-example
(midi->notename
(pitch-and-octave (major 60) '(3 4 5))))
EXAMPLE 5: (for-example
(pitch-and-octave
(make-chord (series-value 60 71) 3)
(rv 3 5)))
EXAMPLE 6: (for-example
(pitch-and-octave
'((60 64 67) (62 67 71)) (rv 3 5)))
EXAMPLE 7: (fill-template data-section section1 200 24
1 (spread (from 60 72) (rv 2 5))
mf 1)
(pitch-class &rest values)
Pitch-class produces a function that can be used with WITH and WITHOUT. The function will compare the input parameter to the values for specified pitch-classes. In WITH, values from those pitch classes will be allowed. In WITHOUT, values from those pitch classes will be ignored.
Pitch class 0 is C, 1 is C#, etc. In example 1, only Cs and C#s are allowed. In example 2, those pitch classes are not allowed.
Any number of values can be specified for the pitch classes (example 3). Pitch classes should be in the range 0-11.
EXAMPLE 1: (for-example
(with (pitch-class 0 1) '(60 61 62 64 60 61 72)))
EXAMPLE 2: (for-example
(without (pitch-class 0 1) '(60 61 62 64 60 61 72)))
EXAMPLE 4: (for-example
(midi->notename
(with (pitch-class 0 4 7) '(c4 d5 c2 f#3 d#5 e3 g4 g3 a#2))))
(pitch-class-filter pitch-classes)
Will produce a filter that will select a value if its pitch class is found in PITCH-CLASSES. PITCH-CLASSES should be a list or stockpile. It can be used with the FILTER method or with FILTER-STOCKPILE.
With the FILTER method, choose OTHER as the filter-type.
If SECTION1 exists, it can be filtered with example 1. In that example, only pitches in the specified pitch classes (0 4 7) or c, e, g will be passed through.
Example 2 shows the use of this filter with FILTER-STOCKPILE.
EXAMPLE 1: (fill-template filter section1f section1
(other (pitch-class-filter '(0 4 7))) 'pitch t)
EXAMPLE 2: (print-result (stockpile->notename
(filter-stockpile '(c3 c#3 d3 c4 f4 c5)
(pitch-class-filter '(0)))))
(pitch-interval-filter &key intervals (next t))
Produces a filter that will filter out undesired pitch intervals in a section. The intervals can occur in parallel or in sequence.
With the dialog for the FILTER method, choose OTHER as the filter type. Choose WHATEVER as the parameter. If the start times of the notes are not to be changed, the check box LEAVE GAPS should be checked. The keyword INTERVALS can be bound to a constant value (if only one interval is to be filtered) or to a list of values.
Example 1 creates data section ds1. Example 2 shows the text representation of this data section. Example 3 filters pitch repetitions from section ds1. Example 4 shows the text representation. In the pitch column, note that the repetition of note number 62 is missing.
In example 5, ds1 is filtered to removed all unisons and major seconds. Intervals is bound to '(0 2) (examples 5-6).
If keyword NEXT is bound to nil, only intervals occurring at the same time are filtered. Intervals in sequence are not filtered. To demonstrate this, the sections in examples 7-8 can be made. These sections should contain some 'forbidden' intervals that happen both in parallel and in sequence. Example 9 will filter the intervals 0 and 2. Examples 10-11 show the text representations of the unfiltered and the filtered section. The default value for NEXT is t which means that both parallel and sequential intervals are filtered. This is the case in example 9.
In example 12, the keyword NEXT is bound to NIL. This will only filter 'forbidden' intervals that have the same start time but not the intervals that happen in sequence. Example 13 shows the text representation.
The PITCH-INTERVAL-FILTER does not filter pitches that have been entered as lists (chords), either by the user or by the generator MAKE-CHORD. In MAKE-CHORD, it is possible to block intervals when constructing a chord. It is also possible to prevent successive chords from sharing pitches.
PITCH-INTERVAL-FILTER does not work in combination with FILTER-STOCKPILE since start time values are needed.
EXAMPLE 1: (fill-template data-section ds1 100 10 1
'(60 62 62 64 67 69 67 63) mf 1)
EXAMPLE 2: (show-text ds1)
EXAMPLE 3: (fill-template filter ds1f ds1
(other (pitch-interval-filter :intervals 0)) 'whatever t)
EXAMPLE 4: (show-text ds1f)
EXAMPLE 5: (fill-template filter ds1f2 ds1
(other (pitch-interval-filter :intervals '(0 2)))
'whatever t)
EXAMPLE 6: (show-text ds1f2)
EXAMPLE 7: (fill-template data-section ds2 100 50 1
(rc '(60 62 63 64 67 69)) mf 1)
EXAMPLE 8: (fill-template new-generate-parallel-section
ds2-p 4 0 ds2 nil nil nil nil)
EXAMPLE 9: (fill-template filter ds2-pf ds2-p
(other (pitch-interval-filter :intervals '(0 2)))
'whatever t)
EXAMPLE 10: (show-text ds2-p)
EXAMPLE 11: (show-text ds2-pf)
EXAMPLE 12: (fill-template filter ds2-pf2 ds2-p
(other (pitch-interval-filter :next nil :intervals '(0 2)))
'whatever t)
EXAMPLE 13: (show-text ds2-pf2)
(pitch-matrix row &optional factor)
Returns a list of transformations of ROW. ROW should be a list or stockpile. This tool is intended for deriving sets of pitches or intervals.
The result is a list of lists since each transformation of ROW will be a list and all of them are collected into a list.
The results will be in the range 0-11, regardless of the range of ROW (example 1).
By default, the transposition FACTOR for the row will be the inversion of the row (example 2). Looking at the result of example 1, you can see that the first value of each transposition has been taken from the row inversion. Set the AC Toolbox preference (CMD-,) to not close the previous window with for-example if you want to compare outputs of the examples.
The row itself can be used as the transposition factor (example 3).
A generator can be used for FACTOR. The number of transpositions included in the matrix will equal the length of the row (example 4).
A list or stockpile can be used for FACTOR. In that case, the number of transpositions will equal the length of the list or stockpile (example 5).
The pitch-matrix can be stored in a stockpile (example 6).
Values can be read from the pitch-matrix using READ-PERMUTATION. Example 7 reads each transposition of the row in order. Example 8 reads the transpositions from the matrix in random order. Note that the selection of the transposition is random. Once a transposition has been chosen, each value in that transposition is returned in order before a new transposition is chosen from the matrix.
Pitches can be produced from the matrix by using PITCH-AND-OCTAVE or its shortcut SPREAD. This will place the values in the range 0-11 to octaves specified for this generator (examples 9-13).
The matrix can also be read with READ-FROM. The index values for reading from the matrix can be specified in various ways, such as a list of indices, a generator, etc. (examples 14-15).
Generator SELECT-PATTERNS picks a list of values, returns each value in the list one at a time, and then picks a new list. It can be used together with READ-FROM to navigate the pitch-matrix (examples 16-17).
The values in the rows in the matrix can be reversed with RETROGRADE-STOCKPILE (examples 18-19).
The values in the rows in the matrix can be inverted with INVERT-STOCKPILE (example 20). Inversion in this case means that a value in the range 0-11 is subtracted from 12.
The retrograde inversion can be made by combining tools (example 21).
Several matrices can be joined with the method JOIN, available in the Methods menu.
A chord is represented in the Toolbox as a list. A pitch-matrix can therefore also be seen as a list of chords. In that case, the matrix should not be read with READ-PERMUTATION or SELECT-PATTERNS (examples 22-25).
The ROW that is input to pitch-matrix could be a list of chords. The transpositions will be of the entire list of chords. In this case, FACTOR cannot be INVERSION or ROW but should be a list or generator (examples 26-31).
EXAMPLE 1: (for-example
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3))
:number-per-line 1)
EXAMPLE 2: (for-example
(invert-stockpile '(0 8 11 6 9 4 10 2 7 1 5 3)))
EXAMPLE 3: (for-example
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3) 'row)
:number-per-line 1)
EXAMPLE 4: (for-example
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3)
(series-value 0 11))
:number-per-line 1)
EXAMPLE 5: (for-example
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3)
(from 0 4))
:number-per-line 1)
EXAMPLE 6: (fill-template construct-stockpile matrix1
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3)))
EXAMPLE 7: (for-example
(read-permutation matrix1)
:number 144 :number-per-line 12)
EXAMPLE 8: (for-example
(read-permutation matrix1
:random t)
:number 144 :number-per-line 12)
EXAMPLE 9: (for-example
(pitch-and-octave
(read-permutation matrix1) 4)
:number-per-line 12)
EXAMPLE 10: (for-example
(spread (read-permutation matrix1 :random t)
(rv 3 5))
:number-per-line 12)
EXAMPLE 11: (fill-template data-section section1 200 144 1
(spread (read-permutation matrix1) (rv 3 5))
mf 1)
EXAMPLE 12: (fill-template data-section section2 100 144
(random-choice (from 1 3 :step .5))
(spread (read-permutation matrix1 :random t)
(rv 2 6))
mf 1)
EXAMPLE 13: (fill-template data-section section3 100 144
(random-choice (from 1 3 :step .5))
(make-chord
(spread (read-permutation matrix1 :random t)
(rv 2 6))
(rv 1 4))
mf 1)
EXAMPLE 14: (for-example
(read-from matrix1 '(1 2 1 3 1 5))
:number 6
:number-per-line 1)
EXAMPLE 15: (for-example
(read-from matrix1 (beta-value 1 12 .2 .2))
:number 6
:number-per-line 1)
EXAMPLE 16: (for-example
(select-patterns
(read-from matrix1 (beta-value 1 12 .2 .2)))
:number-per-line 12 :number 96)
EXAMPLE 17: (fill-template data-section section4 100 144
(random-choice (from 1 3 :step .5))
(spread
(select-patterns
(read-from matrix1 (beta-value 1 12 .2 .2)))
(rv 2 6))
mf 1)
EXAMPLE 18: (for-example matrix1
:number-per-line 1)
EXAMPLE 19: (for-example (retrograde-stockpile matrix1)
:number-per-line 1)
EXAMPLE 20: (for-example (invert-stockpile matrix1)
:number-per-line 1)
EXAMPLE 21: (for-example
(retrograde-stockpile
(invert-stockpile matrix1))
:number-per-line 1)
EXAMPLE 22: (fill-template construct-stockpile chords
(pitch-matrix '(60 64 67 69 71)))
EXAMPLE 23: (show-text chords)
EXAMPLE 24: (fill-template data-section section5 100 20
(random-choice (from 1 3 :step .5))
(spread chords 4)
mf 1)
EXAMPLE 25: (fill-template data-section section6 100 40
(random-choice (from 1 3 :step .5))
(spread
(read-from chords (rv 1 (get-length chords)))
(rv 3 5))
mf 1)
EXAMPLE 26: (fill-template generate-stockpile some-chords
4 (make-chord (rv 60 71) 4 :block 0))
EXAMPLE 27: (for-example some-chords
:number-per-line 1)
EXAMPLE 28: (fill-template construct-stockpile
some-chords-matrix
(pitch-matrix some-chords (from 0 11)))
EXAMPLE 29: (for-example some-chords-matrix
:number-per-line 1)
EXAMPLE 30: (fill-template data-section section7 200 40
(random-choice (from 1 3 :step .5))
(spread
(select-patterns
(read-from some-chords-matrix (rv 1 12)))
(rv 2 6))
mf 1)
EXAMPLE 31: (fill-template data-section section8 200 100
(random-choice (from 1 3 :step .5))
(spread
(select-patterns
(read-from some-chords-matrix (rv 1 12))
#'random-choice)
(rv 2 6))
mf 1)
(pitch-repetition-filter)
Produces a filter that will filter out repeated pitches from a section. It filters pitches that occur at the same time and pitches that occur in succession.
With the dialog for the FILTER method, choose OTHER as the filter type. Choose WHATEVER as the parameter. If the start times of the notes are not to be changed, the check box LEAVE GAPS should be checked (examples 1-2).
The repetitions of pitches that probably occurred in ds1 are filtered away in ds1f. This results in fewer notes.
Example 3 creates some layers to filter.
Example 4 filters out pitch repetitions.
Examples 5-6 show the difference in the two text versions.
The PITCH-REPETITION-FILTER does not filter pitches that have been entered as lists, either by the user or by the generator MAKE-CHORD. Repetitions within a chord can in that case be removed with the transformer REMOVE-DOUBLES. In MAKE-CHORD, it is possible to block unisons when constructing a chord. It is also possible to prevent successive chords from sharing pitches.
For a filter that allows removing other pitch intervals, see PITCH-INTERVAL-FILTER. PITCH-INTERVAL-FILTER can also be limited to only remove undesired values that occur at the same time but not in sequence.
PITCH-REPETITION-FILTER does not work in combination with FILTER-STOCKPILE since start time values are needed. A stockpile can be filtered with REPETITION-FILTER.
EXAMPLE 1: (fill-template data-section ds1 100 100 1
(rv 60 67) mf 1)
EXAMPLE 2: (fill-template filter ds1f ds1
(other (pitch-repetition-filter))
'whatever t)
EXAMPLE 3: (fill-template new-generate-parallel-section
ds1-p 4 0 ds1 nil nil nil nil)
EXAMPLE 4: (fill-template filter ds1-pf ds1-p
(other (pitch-repetition-filter))
'whatever t)
EXAMPLE 5: (show-text ds1-p)
EXAMPLE 6: (show-text ds1-pf)
(pitch-track data track &key filter)
Returns a list of pitches read from one or more tracks of data produced with READ-TRACKS-FILE.
TRACK can be a constant, a list, or a stockpile with track numbers.
READ-TRACKS-FILE can read track data made by SPEAR or the Csound Hetro utility.
For example 1, select file 'test spear voice.txt' in Support/FileExamples. Example 2 plots one track of pitches. Example 3 plots all of the pitches. Example 4 produces a stockpile of pitches that is used in the sections made with examples 5-6.
Pitch repetitions can be filtered by binding FILTER to t (examples 7-9).
EXAMPLE 1: (fill-template construct-stockpile voice1
(read-tracks-file :round 0.5))
EXAMPLE 2: (plot (pitch-track voice1 4))
EXAMPLE 3: (plot (pitch-track voice1 (from 1 30)))
EXAMPLE 4: (fill-template construct-stockpile track-data1
(pitch-track voice1 4))
EXAMPLE 5: (fill-template data-section track-melody1
100 (get-length track-data1) 1
track-data1 mf 1)
EXAMPLE 6: (fill-template data-section track-melody2
100 100 1
(random-choice track-data1) mf 1)
EXAMPLE 7: (fill-template construct-stockpile track-data2
(pitch-track voice1 '(4 7 10) :filter t))
EXAMPLE 8: (fill-template data-section track-melody3
100 (get-length track-data2) 1
track-data2 mf 1)
EXAMPLE 9: (fill-template data-section track-melody4
100 100 1
(random-choice track-data2) mf 1)
play
To play a section, community, or Midi object, select it in the Objects dialog and then choose play. The Objects dialog can be opened with 'Tools>Show Objects'. The menu item 'Tools>Play' will play the selected item in the Objects dialog if the dialog is opened and the selected object can be played. If playing is not as consistent as desired, make sure that the preference for Scheduler Overdrive is selected.
(plot whatever &key title min max number plot replace 2d)
A visual representation is made of the object WHATEVER.
WHATEVER can be a list, shape, mask, stockpile, section, lexical closure, etc (examples 1-2).
If WHATEVER is a generator, the representation is of the result of applying the closure a number of times. By default this is 100. That number can be changed with the key word NUMBER which is only available for use with a generator. For all other objects it is ignored (example 3-4).
If WHATEVER is a generator or a list, the keyword PLOT can be used display values as points or a line. If PLOT is t, points will be plotted. If PLOT is nil, a line will be drawn between the points (example 5).
TITLE should be a string (example 6).
Normally, the drawing or representation is scaled by determining what the actual minimum and maximum value in the group of numbers to be displayed. This can be overridden with the keywords MIN and MAX if you want to refer to some other range (examples 7-8). If the actual minimum or maximum is outside the values expressed by MIN or MAX, the actual boundary will be used.
If the elements of the list to be displayed are lists with two values, the elements will be treated as x,y pairs and plotted as such (example 9).
If the generator produces lists with two elements, the lists will be treated as x,y pairs and plotted as such (example 10).
If the elements of a list to be displayed or the results of applying a lexical closure are lists with 3 elements, thoses elements will be treated as x,y,z combinations and x,z will be plotted (example 11).
Keyword REPLACE controls whether the previous plot window should be removed after the new one has been made (example 12).
The keyword 2D controls the way that data which is also a list is displayed. Lists of 2 or 3 values in lists or stockpiles can be considered x,y or x.y.z data but also as a chord. This ambiguity can be resolved by binding a value to 2D. The default is t meaning that values will be considered as x,y data (examples 13-17).
EXAMPLE 1: (plot '(1 100 50 75))
EXAMPLE 2: (plot sine-shape)
EXAMPLE 3: (plot (random-value 1 100))
EXAMPLE 4: (plot (random-value 1 100) :number 500)
EXAMPLE 5: (plot (random-value 1 100) :plot nil)
EXAMPLE 6: (plot sine-shape :title "A Sine")
EXAMPLE 7: (plot (random-value 1 50))
EXAMPLE 8: (plot (random-value 1 50) :min 1 :max 100)
EXAMPLE 9: (plot '((0 0) (50 20) (100 50) (40 25)))
EXAMPLE 10: (plot (henon 0 0 1.4 0.3 1 :xy t))
EXAMPLE 11: (plot (lorenz 0.1 0.1 0.1 10 28 3/8 1 :xyz t))
EXAMPLE 12: (plot (rv 1 100) :replace nil)
EXAMPLE 13: (fill-template generate-stockpile henon-stock
10 (henon 0.0 0.0 1.4 .3 1 :xy t))
EXAMPLE 14: (plot henon-stock)
EXAMPLE 15: (fill-template generate-stockpile chords
10 (make-chord (rv 40 80) 2))
EXAMPLE 16: (plot chords)
EXAMPLE 17: (plot chords :2d nil)
(plot-many number &rest arguments)
Plots the output of more than one generator.
For each generator, a NUMBER of values are created.
Each generator is plotted in parallel with the others (examples 1-2).
Lists and/or stockpiles may also be plotted (example 3). When a list or stockpile is plotted, NUMBER is ignored.
Any number of arguments may be plotted.
Lists containing other lists as elements (e.g. chords) cannot be plotted with this tool. That can only be done with the tool PLOT.
If the first value after NUMBER is a string, it will be used as the title for the window (example 4).
PLOT-MANY should be used in the Listener or in a Lisp Editor window.
EXAMPLE 1: (plot-many 100 (line 100 1.0 100 :exponential t)
(line 100 1.0 100 :curve 4))
EXAMPLE 2: (plot-many 200 (rv 1 100) (rv 150 200) (rv 300 400))
EXAMPLE 3: (plot-many 100 '(10 20 50) (rv 50 100))
EXAMPLE 4: (plot-many 100 "Different Types of Noise"
(noise-value 100 1 50 0)
(noise-value 100 50 100 -1)
(noise-value 100 100 150 -2)
(noise-value 100 150 200 -3))
plotting
A selected object in the Objects dialog can be plotted by clicking on the Plot button.
Individual parameters of a section or community can be plotted with the Tools>Plot>Section menu item (available parameters are 'Pitch', 'Rhythm', and 'Velocity'). For data sections and note sections, CTRL-clicking on the title items RHYTHM, PITCH, VELOCITY, or NOTES produces a popup menu which can be used to plot section values.
One parameter of a Csound score file can be plotted over time using the dialog created by Tools>Plot>Csound File.
One argument of an OSC file can be plotted over time using the dialog creaed by Tools>Plot>OSC File.
The output of a number of applications of a generator can be plotted using Tools>Plot>Other. The number of applications can be set in the options for that dialog. The choice between plotting dots or drawing lines can also be made in the options. In many cases, more than one generator can be plotted at the same time. Each generator will receive a different color.
A list or object can also be plotted with Tools>Plot>Other. In some cases, more than one list, stockpile, and/or generator can be plotted using this dialog.
When a text input box is CTRL-clicked, a popup menu is available which can be used to plot the selected text. This can be seen as a shortcut for using the dialog produced by Tools>Plot>Other.
Data produced in the FOR EXAMPLE and HISTOGRAM OTHER dialogs can be plotted with a popup menu made available when the button in the lower right side is CTRL-clicked (or clicked with the right mouse button).
A multi controller midi object is plotted with different colors for each controller. The controllers are plotted according to their order in the object. The order of the colors are: the default plotting color, blue, orange, red, slategrey, pink.
(plus-min value probability)
Returns a closure. VALUE is assumed to be something that could produce a positive value. PROBABILITY is something that could produce a probability value in the range of 0-1. (O is never, 1 is always).
Both VALUE and PROBABILITY can change over time. They can be e.g. a constant, a list, a stockpile, a generator, etc (examples 1-2).
When a value is produced, it may be made a negative number according to the specified probability. Rests in the AC Toolbox are specified as negative numbers. This generator can produce rests or rhythmic values according to the specified probability.
EXAMPLE 1: (for-example (plus-min '(1 2 3 4 5) 0.5))
EXAMPLE 2: (for-example (plus-min (random-value 1 10) 0.3))
popup menus
Buttons and text input boxes often have popup menus providing additional options. These menus are shown by CTRL-Clicking the button or text input box. For example, the button popup menu for a section allows the section to be played, plotted, edited, or to have the Fomus or info windows opened.
The popuup menus associated with text input boxes allow simple editing commands (cut, copy, paste) and can be used to look up help for an expression. Text input in dialogs that produce objects can also be used to explore expressions through plots, histograms, or lists of example values. In this case, the selected expression is used to create values each time the menu item is applied.
Options for the plots, etc., such as the number of values to be created, are set in the dialogs related to Tools > Plot > Other, Tools > Histogram > Other, and Tools > For Example.
(positive-negative value &key pos neg)
Returns a closure. When applied, one value is produced using VALUE which may vary over time. The next value will normally be the negative version of that same value. Then the next value from VALUE is produced. And the next negative version. Etc.
VALUE may be a constant, list, generator, etc.
In examples 1-4, one positive value is followed by one negative value. Using the keywords POS and NEG these numbers can be changed.
If POS is bound to 2, the positive value will occur two times before the negative value occurs (example 5).
If NEG is bound to 3, the negative value will occur three times (example 6).
It is possible to bind values to POS and NEG in the same expression (example 7).
VALUE, POS, and NEG may vary over time (example 8).
EXAMPLE 1: (for-example (positive-negative 1))
EXAMPLE 2: (for-example (positive-negative '(1 2 3 4)))
EXAMPLE 3: (for-example (positive-negative (random-choice '(1 3 4))))
EXAMPLE 4: (for-example
(add-to 60
(positive-negative '(1 2 3 4 5 6 7 8 9 10 11))))
EXAMPLE 5: (for-example (positive-negative '(1 2 3) :pos 2))
EXAMPLE 6: (for-example (positive-negative '(1 2 3) :neg 3))
EXAMPLE 7: (for-example (positive-negative '(1 2 3) :pos 4 :neg 2))
EXAMPLE 8: (for-example (positive-negative (random-value 1 10)
:pos (random-value 1 3)))
(predicate function &rest values)
PREDICATE produces a function appropriate for use with WITH, WITHOUT, or FILTER-STOCKPILE. The first argument should be a function. Zero, one, or two additional arguments are accepted.
If one additional argument is used, the generated value is compared to it.
The predicate in example 1 excludes values less than 60.
If two additional arguments are used, the generated value is used between the two arguments when the predicate is made.
The predicate in example 2 does not allow values between (and including) 60 and 70.
If no additional arguments are used, the function is applied to the generated value (example 3).
The above predicate would not allow even values.
PREDICATE can also be used with WITH (example 4) or FILTER-STOCKPILE (example 5).
In earlier versions of the AC Toolbox, the function argument in predicate had to be preceded by a function quote: #'. This is no longer necessary though it may be used (example 6).
An alternative name for PREDICATE is ANYTHING. This is a tool that works the same as PREDICATE (example 7).
Predicate is the name that is used to describe Lisp functions that test for some condition and indicate if the condition is true or false.
EXAMPLE 1: (for-example
(without (predicate < 60)
(random-value 40 80)))
EXAMPLE 2: (for-example
(without (predicate <= 60 70)
(random-value 40 80)))
EXAMPLE 3: (for-example
(without (predicate evenp)
(random-value 40 80)))
EXAMPLE 4: (for-example
(with (predicate < 60)
(1/f-value 128 40 80)))
EXAMPLE 5: (print-result
(filter-stockpile (from 1 10) (predicate < 5)))
EXAMPLE 6: (for-example
(without (predicate #'< 60)
(random-value 40 80)))
EXAMPLE 7 (for-example
(without (anything < 60)
(random-value 40 80)))
preferences
Several preferences which affect the program can be specified using the dialog made with the menu item AC Toolbox > Preferences. If the preference concerns a window, it will not change the current windows but will only effect new ones.
PEN COLOR
The color of the pen for drawing shapes and masks, as well as for plotting various values can be chosen using one of the available Apple color selection tools.
FONT AND DIALOG SIZE
Three sizes are available for fonts and dialogs. If Big is chosen, most dialogs will be bigger and use larger fonts. This is convenient when using a projector. Small will make most dialogs and fonts smaller. Normal is the standard setting.
EXTERNAL VALUE
The generator external-value can refer to either Midi controller numbers or Midi channels as the first argument to the generator.
EXAMPLES: CLOSE PREVIOUS WINDOW WITH TOOL
The tools plot, make-histogram, and for-example are often used in examples in the help for generators, tools, and transformers. These tools could always close the previous window made by the tool each time a new one is made. This reduces screen clutter. This setting only applies to the tools. It does not affect the settings in the options for various dialogs.
WHEN OPENING OBJECT DIALOGS
Each time an object dialog is opened, the previous dialog can be closed or left unchanged. Closing the previous dialog reduces screen clutter.
SAVE ENVIRONMENT WITH
The AC Toolbox can read environment files written in older formats. Previous versions of the Toolbox (before 4.4) cannot read environments in the current (new) format. If data is to be shared between various versions of the Toolbox, environment files should be saved in the old format. The old format will not save object dialog size and position information.
WINDOW STYLE
Dialogs can either use a textured background or the standard style. This only effects new dialogs.
DATE FORMAT
When environment or example files are saved, a name reflecting the current date may be suggested. A choice can be made among the two possible data formats.
TRANSPARENCY
The transparency of new windows can be changed. Moving the slider to the left reduces transparency.
MIDDLE C (60)
Middle C is Midi note number 60. Many people and programs call this pitch C4. Some call it C3. Adjusting the preference causes the value of all pitch symbols, such as c3, c#3, etc. to be adjusted.
CLEAR-PREFERENCE-FILE
A tool called clear-preference-file can be used to delete the preference file which stores the settings of the preferences mentioned in the Preferences dialog as while information about the size and position of many dialogs. Using this tool will also cause the AC Toolbox to not to save the current values to a file the first time the program is closed after this tool has been used. On subsequent use, the preferences will be saved.
The clear-preference-file can be evaluated using the example found in the help for the tool.
(prime-number &optional n)
Returns a closure. When applied, it will generate the next prime number (example 1). If the optional parameter N is specified, the first result will be the next prime number higher than N (example 2). Otherwise the series starts with 2 as the first prime number.
EXAMPLE 1: (for-example (prime-number))
EXAMPLE 2: (for-example (prime-number 20))
(print-phrase-groupings section parameter to-produce-value)
Returns a closure that can be used with the TEXT-SCORE dialog. A section is studied for phrase groupings according to Tenney's theory (see the help for the transformer PHRASE-GROUPINGS for more information). The parameters that can be analyzed are PITCH, DURATION, ATTACKS, and VELOCITY. TO-PRODUCE-VALUE should be a closure, a list, or a symbol.
The primary use for this tool is to produce a closure for the additional parameter for printing a score. The following form could be entered in the box for EXTRA PARAMETER EXPRESSION (OPTIONAL) if section S1 is being printed:
(print-phrase-groupings s1 'pitch 'group)
The symbol GROUP will be printed on each line where a pitch group begins.
(print-result expression)
This tool is used in help windows. EXPRESSION will be evaluated and the result is printed to a window (example 1).
EXAMPLE 1: (print-result (get-input sine-shape))
(probability-filter low high probability ...)
Probability-filter can be be used with the filter method, filter-stockpile, or the generators WITH or WITHOUT.
The filter allows values between various limits to pass based on separate probability values for set of limits (example 1). In this example, values from 10 to 20 are passed 80% of the time and values from 50 to 60 are passed 20% of the time. All other values are rejected.
This tool is a simple way to say that you want to keep more low values, or only high values, etc.
Probabilities should be in the range 0-1. 0 is never, 1 is always.
Note that this tool is a filter. It does not guarantee that 80% of the values are from 10 to 20. It allows 80% of the available values from 10 to 20 to be included in the final result.
Any number of limits and probabilities can be used. In example 2, only values from 20 to 40 are included 50% of the time.
Examples 3-4 demonstrate the use with the filter method.
EXAMPLE 1: (make-histogram
(with (probability-filter 10 20 .8 50 60 .2)
(random-value 1 100)))
EXAMPLE 2: (make-histogram
(with (probability-filter 20 40 .5)
(random-value 1 100))
:min 0 :max 100)
EXAMPLE 3: (fill-template data-section test1 100 100
1 (rv 40 80) mf 1)
EXAMPLE 4: (fill-template filter test1f test1
(other (probability-filter 40 50 0.8 70 80 0.5))
'pitch t)
(produce n object)
Returns a list of N values derived from OBJECT. If object is a generator, it is applied N times (example 1).
If OBJECT is a list or stockpile, the first N values are taken from the the object (example 2). If the object contains fewer than N values, PRODUCE loops through the available values (example 3).
If N is a generator, stockpile, etc., one value is taken from it to determine n.
EXAMPLE 1: (print-result (produce 10 (rv 1 100)))
EXAMPLE 2: (print-result (produce 2 '(1 2 3 4 5)))
EXAMPLE 3: (print-result (produce 20 '(1 2 3 4 5)))
(produce-pulse produce-indispensability produce-level
&optional max-indispensability-level low-value high-value)
Returns a closure. When applied, the next value reflecting an interpretation of a pulse value is produced.
The standard interpretation is for rhythmic values; 1 or -1 is produced depending if the pulse-value is positive or negative (examples 1-2). If the optional parameters are included, the interpretation is for velocity (or some other parameter). Negative pulse values are 0 and positive values are mapped between LOW-VALUE and HIGH-VALUE (examples 3-4).
The pulse value is determined by how indispensable it is and what the level of thinning is. Both of these concepts come from Clarence Barlow (1987)
If a meter is described as 3*2, it is for example 3/4: 3 divisions of 2. The first pulse is the most important and has the value 5. The least important pulse would have the value 0. Clarence's indispensabilities for 3/4 are '(5 0 3 1 4 2). 6/8 is '(5 0 2 4 1 3).
If the thinning level is 2, all pulses with a indispensability less than 2 are turned into rests, i.e. a negative value (-1). All pulses with an indispensability that is 2 or higher are 1. If the thinning level is a function or a list, the next value is chosen at the beginning of each indispensability list.
The first two parameters to this generator function can be a constant, a list, or a generator. The optional parameters should be constants.
Also see the tool PULSE-HIERARCHY that can be used to generate a list of indispensability values given some metric division.
Barlow, C. (1987). Two Essays on Theory. Computer Music Journal, 11(1), 44-60.
EXAMPLE 1: (for-example (produce-pulse '(5 0 2 4 1 3) 2)
:number 12 :number-per-line 6)
EXAMPLE 2: (for-example (produce-pulse '(5 0 2 4 1 3)
(random-value 1 5))
:number 24 :number-per-line 6)
EXAMPLE 3: (for-example (produce-pulse '(5 0 2 4 1 3) 2 5 50 90)
:number 12 :number-per-line 6)
EXAMPLE 4: (for-example (produce-pulse '(5 0 2 4 1 3)
(random-value 1 5) 5 50 90)
:number 24 :number-per-line 6)
(program-filter parameter filter)
Since the filter template has no button for filtering MIDI program changes that may be in a midi-controller-object or a midi-section, a filter definition will have to be produced if you want to filter MIDI program changes.
Choose OTHER as the filter type then use PROGRAM-FILTER to produce an appropriate filter definition.
PARAMETER can be:
NUMBER
CHANNEL
FILTER can be a Lisp expression reflecting the available filter types:
(low-pass threshold)
(high-pass threshold)
(band-pass low high)
(band-reject low high)
(bank low1 high1 low2 high2 ...)
(shot-gun percentage)
If Midi program object PROG1 exists, it can be filtered with example 1.
Click on SET PARAMETERS to see the filter definition. A low-pass filter for midi program changes will be produced.
EXAMPLE 1: (fill-template filter prog2 prog1
(other (program-filter 'number (low-pass 10)))
'whatever nil)
(program-transform parameter transformer)
This transformer builds another transformer that can be used with the WHATEVER parameter (and only with the WHATEVER parameter) to transform MIDI program change commands. MIDI program change commands are only found in midi-program-objects or midi-sections.
PROGRAM-TRANSFORM 'encapsulates' the other transformer and makes it suitable for use with MIDI program change commands.
The available values for PARAMETER are:
number
channel
NUMBER would transform the MIDI program number.
CHANNEL transforms the MIDI channel assignment for the MIDI
program commands.
The parameter values should be quoted.
TRANSFORMER can be any available transformer such as TRANSPOSE.
If object midi1 exists, it can be transformed with example 1.
EXAMPLE 1: (fill-template transform midi2 midi1
:whatever (program-transform 'number (transpose 12)))
(pulse-hierarchy &rest divisions)
Returns a list of indispensabilities for the pulses of some metric division. Any number of divisions can be specified.
At the level of sixteenth notes
3/4 is 3 * 2 * 2 and should be entered as (pulse-hierarchy 3 2 2)
6/8 is (pulse-hierarchy 2 3 2)
12/16 is (pulse-hierarchy 2 2 3)
This implementation differs with Clarence Barlow's formula in that his way is completely deterministic. This algorithm only assumes that the first pulse is the most indispensable and the remaining pulses at the same level in the hierarchy receive a random value chosen from among the available possibilities (examples 1-2).
See Barlow (1987) and the help for the generator PRODUCE-PULSE.
This tool can be used in combination with PRODUCE-PULSE and with INTERPRET-PULSE.
Barlow, C. (1987). Two Essays on Theory. Computer Music Journal, 11(1), 44-60.
EXAMPLE 1: (print-result (pulse-hierarchy 3 2 2))
EXAMPLE 2: (print-result (pulse-hierarchy 2 3 2))
(pulse-interpolation list1 list2 rate)
Returns a list reflecting the interpolation between list1 and list2. Both lists are indispensability lists (see generator PRODUCE-PULSE for a discussion of indispensability). RATE is the number of times that a list is used before one value is changed.
Thinned values are represented as negative numbers. Other indispensabilities are positive.
To obtain useful results, the input lists should be thinned, otherwise the result will contain no rests and the interpolation is a bit too straightforward. THIN is a tool to thin indispensability lists (see its help).
Example 1 interpolates from a 3/4 measure (5 -1 3 -1 4 -1) to a 6/8 measure (5 -1 2 4 -1 3).
The result of PULSE-INTERPOLATION should be interpreted with INTERPRET-PULSE.
EXAMPLE 1: (for-example
(pulse-interpolation (thin '(5 0 3 1 4 2) 3)
(thin '(5 0 2 4 1 3) 2)
2)
:number-per-line 6)
(quantize unit &optional transformer)
Returns a closure that can be used as a transformer. The value being transformed is rounded off to the nearest multiple of UNIT (example 1).
If this transformer is used with the tempo parameter, both attack and duration values will be changed. If it is only used with duration, the attack times are not changed.
When used for tempo, attack, or duration values, the unit should be expressed in miliseconds (examples 2-5).
QUANTIZE can be applied to the result of another transformer (example 6).
UNIT may vary over time using a generator, etc.
EXAMPLE 1: (show-transformation (quantize 2)
'(0 1 2 3 4 5 6 7 8 9 10))
EXAMPLE 2: (fill-template data-section section1
100 30
(random-value 1.0 3) (random-value c3 g#5)
(random-choice '(pp p mf f)) 1)
EXAMPLE 3: (show-text section1)
EXAMPLE 4: (fill-template transform section1t
section1 :tempo (quantize 50))
EXAMPLE 5: (show-text section1t)
EXAMPLE 6: (show-transformation
(quantize .25 (transpose (rv -1.0 1)))
(from 1 10))
quicktime musical instruments
When QuickTime is selected for Midi output in the Midi Setup dialog, fractional pitch values can be played. 60.5 is a quarter tone higher than Midi note number 60.
Different General Midi instruments can be assigned to different Midi channels via the menu item Other>General Midi.
Some versions of QuickTime may require additional time between notes in order to repeat correctly. The tool MIDI-ARTICULATION can correct this problem.
Example 1 subtracts one millisecond from each duration when a section is played.
EXAMPLE 1: (print-result (midi-articulation 1))
(ramp begin end increment &key conversion (wrap t) round)
Steps from begin to end in steps of increment (example 1). The output wraps around to BEGIN when END has been reached. (I.e. Increment is added to begin) (example 2).
To restart with begin, set keyword wrap to nil (example 3).
Output is a real number if one or more of the arguments is a real number (example 4).
If integer output is desired in such a case, ROUND can be bound to 1 (example 5) or the name of a Lisp conversion function should be given to the keyword (example 6).
EXAMPLE 1: (for-example (ramp 1 20 1))
EXAMPLE 2: (for-example (ramp 1 5 1))
EXAMPLE 3: (for-example (ramp 1 5 1 :wrap nil))
EXAMPLE 4: (for-example (ramp 1 10 1.5))
EXAMPLE 5: (for-example (ramp 1 10 1.5 :round 1))
EXAMPLE 6: (for-example (ramp 1 10 1.5 :conversion #'round))
(random-choice sequence)
Returns a closure. When applied, it will randomly choose one of the elements of the sequence or stockpile. Ideally, it will produce a uniform random distribution (example 1).
RANDOM-CHOICE may be abbreviated to RC (example 2).
EXAMPLE 1: (for-example (random-choice '(a b c d)))
EXAMPLE 2: (for-example (rc '(60 64 67)))
(random-deviation percentage &key round)
Returns a closure. PERCENTAGE is the total percentage of deviation. If for example it is 10, that means that deviation is possible from 5% under the value to 5% above the value (example 1).
To round the result to an integer, bind ROUND to t (example 2). To quantize the result with another unit, bind ROUND to a quantization unit (example 3).
PERCENTAGE may vary over time using a generator, etc. (example 4).
EXAMPLE 1: (show-transformation (random-deviation 10)
'(60 60 60 60))
EXAMPLE 2: (show-transformation (random-deviation 10 :round t)
'(60 60 60 60))
EXAMPLE 3: (show-transformation (random-deviation 10 :round 0.25)
'(60 60 60 60))
EXAMPLE 4: (show-transformation
(random-deviation (line 10 10.0 50))
'(60 60 60 60 60 60 60 60 60 60))
(random-intervals low high &rest intervals)
Returns a closure. When applied, for the first time, a random value between LOW and HIGH is produced. Every subsequent value is randomly chosen from among the available intervals. The chosen interval is either added to or subtracted from the previous value.
The series of numbers produced by this generator will always be within the boundaries specified by LOW and HIGH.
Any number of intervals can be specified. The intervals specified in example 1 are 1,3, and 4 which indicate a minor second, a minor third, and a major third when considered as pitch. Each value in the series of numbers will be up or down one of those intervals.
EXAMPLE 1: (for-example (random-intervals 48 72 1 3 4))
(random-value low high &key round check)
Returns a closure. When applied, it will produce a random value between LOW and HIGH. Integer values for LOW and HIGH produce an integer result (examples 1-2). Otherwise a real result is returned (example 3). LOW and HIGH can change over time (example 4).
To quantize the result with another unit, bind ROUND to a quantization unit (example 5).
To prevent the same random value from being chosen twice in a row, bind keyword CHECK to t (examples 6-7).
RANDOM-VALUE may be abbreviated to RV (example 8).
EXAMPLE 1: (for-example (random-value 40 80))
EXAMPLE 2: (plot (random-value 1 100))
EXAMPLE 3: (for-example (random-value 0.0 1))
EXAMPLE 4: (plot (random-value (line 100 1 40)
(line 100 10 90)))
EXAMPLE 5: (for-example (random-value 40.0 80 :round 0.25))
EXAMPLE 6: (for-example (random-value 1 5))
EXAMPLE 7: (for-example (random-value 1 5 :check t))
EXAMPLE 8: (for-example (rv 40 80))
(ratio-choice value-sequence factor-sequence)
Returns a closure. When applied, an element of the VALUE-SEQUENCE is returned. The FACTOR-SEQUENCE is a list of integer weights specifying the relative frequency of occurance for the corresponding element in the VALUE-SEQUENCE. The first element in the FACTOR-SEQUENCE is the weight for the first element in the VALUE-SEQUENCE, etc. (example 1)
To vary weights over time, use generator CHANGING-WEIGHTS.
EXAMPLE 1: (for-example (ratio-choice '(a b c d) '(5 1 3 1)))
(ratio-value a z factor-sequence)
Returns a closure, When applied, it returns an integer between A and Z. FACTOR-SEQUENCE should contain an integer weight for each value between and including A and Z. That weight indicates the relative frequency of occurance of the corresponding number (examples 1-2).
To vary weights over time, use generator CHANGING-WEIGHTS.
EXAMPLE 1: (for-example (ratio-value 1 4 '(1 5 1 3)))
EXAMPLE 2: (make-histogram (ratio-value 1 4 '(1 5 1 3))
:number 10)
(rc stockpile)
RC is a shortcut (abbreviation) for RANDOM-CHOICE (example 1).
See the help for RANDOM-CHOICE for more information (example 2).
EXAMPLE 1: (for-example (rc '(c4 e4 g4 b4)))
EXAMPLE 2: (show-help 'random-choice)
(read-from stockpile index-values &optional number generator)
Returns a closure. When applied, a value from STOCKPILE is returned. The values are produced in the order determined by INDEX-VALUES. Positions are numbered starting with 1. INDEX-VALUES may be a list or stockpile of index values, a generator, a shape, or a mask.
STOCKPILE can be a list, vector, stockpile, section or any other toolbox object for which a get-stockpile method has been defined.
If INDEX-VALUES is a list or stockpile, the values should be valid indices (from 1 to the length of the stockpile or list) (example 1).
If it is a generator, the generator should also produce valid indices (example 2).
If a shape or mask is used, the Y axis of the shape or mask is converted to produce index values for the stockpile. This means that the stockpile can be considered spread on the Y axis of the shape or mask. NUMBER is the length of the cycle for one application of a shape or a mask (example 3). The default value for NUMBER for a shape or mask is 100.
For a shape or mask, NUMBER can vary over time. The shape or mask is converted to be a number of values. After that number of values, a new number is produced and the shape or mask will have that new length (examples 4-5).
Example 6 defines a mask.
Example 7 uses that mask to produce index values for READ-FROM.
A mask is the only object that uses the optional parameter GENERATOR. By default, a mask chooses between its boundaries using (random-value 0.0 100.0) where 0 and 100 are percentages of the distance between boundaries. GENERATOR could use a different generator producing values in the same range, e.g.
(beta-value 0.0 100.0 .2 .2) (example 8).
Example 9 uses a variable value for NUMBER in combination with a mask.
To determine the length of an object, GET-LENGTH can be used. If Stockpile STOCK1 has been defined, (get-length stock1) will return the number of elements it has. This number is also the maximum index value.
EXAMPLE 1: (for-example (read-from '(a b c) '(2 1 3 3 1 2 1 1 1 1)))
EXAMPLE 2: (for-example (read-from '(a b c d e f g)
(random-value 1 7)))
EXAMPLE 3: (for-example (read-from '(a b c d e f g) sine-shape 20))
EXAMPLE 4: (plot (read-from (from 1 200) sine-shape '(25 50 25)))
EXAMPLE 5: (plot (read-from (from 1 200) sine-shape (rv 10 50)))
EXAMPLE 6: (fill-template specify-mask mask1
'(100 10) (50 1))
EXAMPLE 7: (plot
(read-from (from 40 80) mask1 100))
EXAMPLE 8: (plot
(read-from (from 40 80) mask1 100
(beta-value 0.0 100 .2 .2)))
EXAMPLE 9: (plot
(read-from (from 40 80) mask1 '(50 25 25)))
(read-permutation permutation &key random)
Returns a closure. When applied, one element from a permutation of a group of elements is returned. Each time the generator is applied, the next element from that permutation is returned. This continues until all elements of all permutations have been returned.
PERMUTATION is a list or stockpile made using the tool MAKE-PERMUTATION. See the help for that tool for more information (example 1).
Permutations all always made in a fixed order. A different order can be achieved by entering the elements in a different order (example 2).
Instead of returning each permutation of the elements in the PERMUTATION in their fixed order, a random order can be selected by binding the keyword RANDOM to t (example 3). Random in this case means that no permutation will be repeated until they all have been chosen once.
Note that MAKE-PERMUTATION works best with eight or less elements to permute.
EXAMPLE 1: (for-example (read-permutation
(make-permutation '(1 2 3)))
:number 18 :number-per-line 3)
EXAMPLE 2: (for-example (read-permutation
(make-permutation '(3 1 2)))
:number 18 :number-per-line 3)
EXAMPLE 3: (for-example (read-permutation
(make-permutation '(1 2 3)) :random t)
:number 18 :number-per-line 3)
read-sound-file
has been renamed LOAD-SOUND-FILE.
(read-spectrum-file &key type round base unique peaks)
This tool reads a file that can be used as a static spectrum for deriving pitch material, etc. The file should be either a tracks file (produced by SPEAR or the Csound utility Hetro) or a text with spectral data (produced by Audacity or Amadeus).
The default is to read a SPEAR file. SPEAR is an analysis/resynthesis program using tracks of partials. The data should be exported from SPEAR using the 'text - partials' format. Example 1 reads a SPEAR file, constructs a spectrum with one pitch per track, and stores the data in a stockpile. Select the sample file 'test spear bassoon.txt' in Support/FileExamples. Example 2 plots the spectrum expressed as amplitude over pitch.
A spectrum read with this tool can be used in the following AC Toolbox tools:
spectrum->pitch
spectrum->amp
spectrum->freq
spectrum->structure
spectrum->window
spectrum->mirror
spectrum->range
limit-spectrum
and with the generator: spectrum->chord
Example 3 prints data derived from the spectrum to a window. Peaks are sorted according to amplitude.
If ROUND is nil, the values for pitch are not rounded. If it is bound to 1, semitones are returned; 0.5 returns quarter-tones, etc. The default value is nil. Example 4 shows the spectrum rounded to quarter-tones.
BASE is by default bound to 440.0. It is the value for a4 and used in the conversion process from frequency to note numbers (example 5).
Spectral data may contain pitch duplications (e.g. as a result of a rounding operation). To eliminate these duplicates, bind UNIQUE to t. Select file 'test spear voice.txt' (examples 6-7). Note the difference between the number of tracks and the number of unique pitch values.
Hetro is a Csound utility that decomposes a soundfile into amplitude and frequency tracks. If Csound5 or higher has been installed, Hetro can be called from within the AC Toolbox. In the Csound File Options dialog, press the button for Analysis Programs. Choose the pop-up menu for hetro.
To read Hetro files with READ-SPECTRUM-FILE, the analysis file must be made specifically for the platform being used (either Intel or PPC). Example 8 will read in a Hetro file. Select either 'test hetro (intel).het' or 'test hetro (ppc).het' depending on the platform being used.
Spectra can also be read from text files produced by Audacity or Amadeus. In general, spectral data read from SPEAR files will produce pitch data more similar to the analyzed file.
In Audacity a spectral text file can be created by exporting a spectral plot. To read an Audacity file, TYPE should be bound to audacity. 'test audacity bassoon.txt' is a sample Audacity file in the folder Support/File Examples. Select this file with example 9.
In Amadeus, the spectrum can be saved as a text file (not importable). To read an Amadeus spectrum file, TYPE should be bound to amadeus.
Spectrum files produced with Audacity or Amadeus have a large number of frequency-amplitude pairs. For an Audacity or Amadeus file, the default is to return the 10 peaks with the largest amplitude values. Another number of peaks can be specified with the keyword PEAKS (example 10). This number may be larger than 10. The default value for PEAKS is nil for SPEAR or Hetro files. This will return all peaks. For these files, a smaller number of peaks can be specified but not a larger one.
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (plot spectrum1)
EXAMPLE 3: (spectrum->window spectrum1)
EXAMPLE 4: (spectrum->window (read-spectrum-file :round 0.5))
EXAMPLE 5: (spectrum->window (read-spectrum-file :round 0.5 :base 415))
EXAMPLE 6: (read-spectrum-file :round 1)
EXAMPLE 7: (read-spectrum-file :round 1 :unique t)
EXAMPLE 8: (plot (read-spectrum-file :type 'hetro))
EXAMPLE 9: (spectrum->window (read-spectrum-file :type 'audacity))
EXAMPLE 10: (spectrum->window
(read-spectrum-file :type 'audacity :peaks 20))
(read-text-file &optional name)
Returns a list of values read in from a text file. The file is chosen with the customary dialog box (example 1).
If a file name is provided, it is read without using the file choice dialog (example 2). The name should be in a string.
EXAMPLE 1: (for-example (read-text-file))
EXAMPLE 2: (for-example
(read-text-file "/Users/joe/Desktop/junk.txt"))
(read-tracks-file &key type round filter base average)
Reads a sound analysis file containing tracks and converts the data to a format that can be used with the tool MAP-TRACKS to produce notes.
The sound analysis file can either be a partials text file exported from SPEAR or a hetrodyne filter analysis prepared by the Csound utility Hetro.
TYPE refers to the type of the analysis file. Allowed types are SPEAR and Hetro. The default for type is SPEAR.
READ-TRACKS-FILE is typically either used directly as an input for MAP-TRACKS or it is used to construct a stockpile so that the analysis data can be used several times without reloading the analysis file. Example file 'test spear voice.txt', available in Support/FileExamples, can be loaded to test this tool (examples 1-2).
The number of available tracks is printed in the Text Output window when the file is read.
The track data can be performed with MAP-TRACKS (example 3). See the help for that tool for more information on what can be done with it.
The pitch values from the track data can be rounded by binding the unit to keyword ROUND. 1 rounds to semitones, 0.5 to quarter-tones, nil does not round. nil is the default value (example 4).
FILTER will filter out pitch repetitions in a track. This happens after the values have been rounded. (example 5).
AVERAGE can be bound to a time unit in milliseconds. Pitch data in a track will be averaged across that time unit. The next averaged value is assigned the first start time within the unit (example 6). This reduces the amount of data produced. The data can be further reduced by filtering it in MAP-TRACKS (example 7). Filtering in MAP-TRACKS rather than in READ-TRACKS-FILE is advantageous when averaging because it will also filter duplicate pitches in chords.
BASE is used for converting frequency data to pitches (Midi note numbers). By default it is 440 for a4. To change this value, bind BASE to a different frequency (example 8).
SPEAR (Sinusoidal Partial Editing Analysis and Resynthesis) is a standalone application for analyzing a soundfile into individual sinusoidal tracks (partials). It offers various opportunities to edit this data. THE DATA SHOULD BE EXPORTED FROM SPEAR USING THE 'TEXT - PARTIALS' FORMAT. The AC Toolbox can read this exported text file. The Toolbox does not read the standard sdif format used by SPEAR (example 9).
Track data can also be read from a Hetro analysis file. A different Hetro file is available in Support/FileExamples for each platform. It is called 'test hetro (ppc).het' or 'test hetro (intel).het' (examples 10-11).
HETRO decomposes a soundfile into several sinusoids and outputs a description of the sound in the form of a number of amplitude and frequency tracks. If a harmonic stored by Hetro has an amplitude of 0, it is ignored by READ-TRACKS-FILE. This means that there may be fewer tracks in the file than were specified in Hetro.
READ-TRACKS-FILE assumes that the Hetro analysis was made specifically for the platform (Intel or PPC) that the Toolbox is currently using. Analyzes made on a PPC machine or using Rosetta should not be used with the AC Toolbox on an Intel processor.
If Csound5 or higher has been installed, Hetro can be called from within the Toolbox. In the Csound File Options dialog, press the button for Analysis Programs. In the resulting dialog, choose the pop-up menu item for hetro.
To retrieve the pitch data from one track, see tool PITCH-TRACK.
To treat the track data as a cumulative spectrum with one peak per track, see READ-SPECTRUM-FILE.
EXAMPLE 1: (fill-template construct-stockpile
voice1 (read-tracks-file))
EXAMPLE 2: (plot voice1)
EXAMPLE 3: (fill-template structured-section
section1 1 (map-tracks voice1 (from 1 30) 1))
EXAMPLE 4: (fill-template structured-section
section2 1 (map-tracks (read-tracks-file :round 1)
(from 1 30) 1))
EXAMPLE 5: (fill-template structured-section
section3 1 (map-tracks (read-tracks-file :round 1 :filter t)
(from 1 30) 1))
EXAMPLE 6: (fill-template structured-section
section4 1 (map-tracks (read-tracks-file :round 1 :average 1000)
(from 1 30) 1
:min-vel 30 :max-vel 60))
EXAMPLE 7: (fill-template structured-section
section5 1 (map-tracks (read-tracks-file :round 1 :average 1000)
(from 1 30) 1
:filter t
:min-vel 30 :max-vel 60))
EXAMPLE 8: (fill-template structured-section
section6 1 (map-tracks (read-tracks-file :base 415)
(from 1 30) 1))
EXAMPLE 9: (open-url "http://www.klingbeil.com/spear")
EXAMPLE 10: (fill-template structured-section
section7 1 (map-tracks (read-tracks-file :type 'hetro)
(from 1 10) 1))
EXAMPLE 11 (fill-template structured-section
section8 1 (map-tracks
(read-tracks-file :type 'hetro :round 1
:average 1000)
(from 1 10) 1
:filter t
:min-vel 60 :max-vel 80))
(rearrange stockpile index-rule)
Returns a closure. When applied, a value taken from the stockpile is returned. The order for choosing from the stockpile is determined by the INDEX-RULE. INDEX-RULE can be a list, generator, etc. It should provide an index for reading from the stockpile (the first value in the stockpile has the index 1).
After a number of values that is equal to the length of the stockpile have been returned, the stockpile is replaced with a new stockpile consisting of the previous series of values from the stockpile. The INDEX-RULE is then applied to this new stockpile.
In this way, values from the stockpile can be rotated or rearranged in various ways according to the INDEX-RULE (examples 1-2).
INDEX-RULE can vary over time (example 3).
EXAMPLE 1: (for-example
(rearrange '(a b c d e) '(2 3 4 5 1)))
EXAMPLE 2: (for-example
(rearrange '(a b c d e) '(3 1 4 5 2)))
EXAMPLE 3: (for-example
(rearrange '(a b c d e) (series-value 1 5)))
(rearrange-stockpile stockpile type &optional a b)
Returns a list made by rearranging STOCKPILE according to one of the available types. STOCKPILE should be a list or stockpile. TYPE should one of the following:
shuffle
swap
rotate-left
rotate-right
adjacent
order
A and B are optional parameters that may be needed for certain types of rearrangements.
SHUFFLE rearranges the stockpile in a random order (example 1).
SWAP exchanges values at two locations in a stockpile. Locations are numbered starting with 1. A and B receive the numbers of the locations to be swapped (examples 2-3).
ROTATE-LEFT moves each element in the stockpile one place to the left. The first element in the stockpile moves to the last position. A is the number of rotations (examples 4-5).
ROTATE-RIGHT moves each element in the stockpile one place to the right. The last element in the stockpile moves to the first position. A is the number of rotations (examples 6-7).
ADJACENT swaps the element at location A with the element one place to the right (one location higher) (examples 8-9).
ORDER rearranges the stockpile in the order specified by A. A may be a list, stockpile, generator, etc. with values for locations in the stockpile (examples 10-11). If the order specified by A is longer than the stockpile, the size of the returned stockpile is the length of A (example 12).
A and B may be constant values, a generator, etc. If no value is specified for A, it will have the value 1. If no value is specified for B, it will have the value 2.
The shortcut for REARRANGE-STOCKPILE is RS (example 13).
EXAMPLE 1: (print-result
(rearrange-stockpile '(a b c d e) 'shuffle))
EXAMPLE 2: (print-result
(rearrange-stockpile '(a b c d e) 'swap 1 3))
EXAMPLE 3: (print-result
(rearrange-stockpile '(a b c d e) 'swap 2 5))
EXAMPLE 4: (print-result
(rearrange-stockpile '(a b c d e) 'rotate-left))
EXAMPLE 5: (print-result
(rearrange-stockpile '(a b c d e) 'rotate-left 2))
EXAMPLE 6: (print-result
(rearrange-stockpile '(a b c d e) 'rotate-right))
EXAMPLE 7: (print-result
(rearrange-stockpile '(a b c d e) 'rotate-right 2))
EXAMPLE 8: (print-result
(rearrange-stockpile '(a b c d e) 'adjacent 2))
EXAMPLE 9: (print-result
(rearrange-stockpile '(a b c d e) 'adjacent
(random-value 1 4)))
EXAMPLE 10: (print-result
(rearrange-stockpile '(a b c d e)
'order '(4 2 3 5 1)))
EXAMPLE 11: (print-result
(rearrange-stockpile '(a b c d e)
'order (series-value 1 5)))
EXAMPLE 12: (print-result
(rearrange-stockpile '(a b c d e)
'order '(1 1 2 1 2 3 1 2 3 4 1 2 3 4 5)))
EXAMPLE 13: (print-result
(rs '(a b c d e) 'shuffle))
(reject-channel channel)
Produces a filter that will reject events from one or more specified channels. CHANNEL can be a number or a list.
Example 1 defines a section that alternates its notes among 3 channels. Example 2 will plot that section.
Example 3 filters out all information that is found on channel 2. Example 4 will plot the result.
Example 5 rejects the information in channels 1 and 3. Example 6 plots that section.
This filter assumes WHATEVER was selected as the parameter to be filtered.
This filter differs from selecting CHANNEL as the parameter in the Filter dialog since that is limited to filtering pitches. REJECT-CHANNEL will reject any events in a given channel or channels. A second difference is that REJECT-CHANNEL is a convenient way to filter several channels that are not within some bandwidth (example 5).
The filter SELECT-CHANNEL is also available.
EXAMPLE 1: (fill-template data-section ds1 100 20
(rv 1.0 3) (rv 48 72) f '(1 2 3))
EXAMPLE 2: (plot ds1)
EXAMPLE 3: (fill-template filter ds1-filtered1 ds1
(other (reject-channel 2))
'whatever t)
EXAMPLE 4: (plot ds1-filtered1)
EXAMPLE 5: (fill-template filter ds1-filtered2 ds1
(other (reject-channel '(1 3)))
'whatever t)
EXAMPLE 6: (plot ds1-filtered2)
(reject-pitch-class-filter pitch-classes)
Will produce a filter that will reject a value if its pitch class is found in PITCH-CLASSES. PITCH-CLASSES should be a list or stockpile. It can be used with the FILTER method or with FILTER-STOCKPILE.
With the FILTER method, choose OTHER as the filter-type.
If SECTION1 exists, it can be filtered with example 1. In that example, only pitches not in the specified pitch classes (0 4 7) or c, e, g will be passed through.
Example 2 shows the use of this tool with FILTER-STOCKPILE.
EXAMPLE 1: (fill-template filter section1f section1
(other (reject-pitch-class-filter '(0 4 7)))
'pitch t)
EXAMPLE 2: (print-result
(stockpile->notename
(filter-stockpile '(c3 c#3 d3 c4 f4 c5)
(reject-pitch-class-filter '(0)))))
(reject-stockpile-filter stockpile)
Will produce a filter which rejects a value if it is found in the stockpile. This filter should be used with the FILTER method or with FILTER-STOCKPILE.
To use with the FILTER method: choose OTHER as the filter type.
STOCKPILE may be a list or a stockpile object.
If SECTION1 exists, it can be filtered with example 1. In that case, notes which have a pitch of 60 or 64 or 67 will be filtered out.
Example 2 uses this tool with FILTER-STOCKPILE.
EXAMPLE 1: (fill-template filter section1f section1
(other (reject-stockpile-filter '(60 64 67)))
'pitch t)
EXAMPLE 2: (print-result
(filter-stockpile '(1 2 3 4 5 6 7 8 9 10)
(reject-stockpile-filter '(2 4 6 8))))
relating parameters
The easiest way to relate parameters in an object is to make a stockpile for one of the parameters and then use this to determine the value or behavior for the second parameter.
In a data section, rhythm can be related to pitch by using ON-THE-FLY to calculate a rhythmic value based on a value from the pitch stockpile (examples 1-2). In this case, lower pitches are longer.
Parameters can also be related by using a lookup table. The table will contain a series of keys and values. The keys could be values from one parameter, the values the intended results for the second parameter. Example 3 defines a lookup table which will be used to determine rhythm based on pitch. It is not necessary to have a key for every possible value. The key closest to the one requested will be chosen. Example 4 uses LOOKUP to read a value from the pitch stockpile and to return the value corresponding to the nearest key. Since there are 3 keys in the table, only 3 rhythm values are possible.
It is possible to interpolate between the values of the table. The interpolation is based on the distance of the requested key to its surrounding keys. In example 5, the interpolation results in there being more different rhythmic values.
A lookup table can also relate keys to generators,lists, or stockpiles. Each time the key is referenced, one value from the generator, etc. is returned (example 6).
Tables can also be constructed with CONVERT-TO-LOOKUP-TABLE. With this tool, tables can be derived from shapes, generators, etc.
ACT-IF can be used to relate parameter values. Example 7 defines a new stockpile with random pitches. Example 8 is uses a generator for pitches > 60, uses a constant value if the pitch is equal to 60, and in all other cases (lower values), uses a second generator that will produce longer values. Any number of conditions can be expressed in ACT-IF.
The two objects can be recalculated using a scheme object. When applied, the included objects are remade one at a time, left to right, top to bottom. (example 9).
If a sequential or parallel section is generated, the stockpile can be specified as an Object to Remake (example 10). The stockpile will be remade before each section in the sequential section is made.
Csound score objects and OSC score objects can use stockpiles in a similar way. In both cases, stockpiles can be remade per layer or per score. A scheme is not necessary.
In addition, Csound score objects can use generator PAR. It reads the value of any lower numbered parameter. For example, P5 could read P4, etc. (example 11).
Example 11 can be rendered using 'test csound.orc' which is in the Support/FileExamples folder. P3 is duration, P5 is frequency. In this example, longer durations have lower frequencies.
EXAMPLE 1: (fill-template construct-stockpile pitch1
(from 30 80 :step 5))
EXAMPLE 2: (fill-template data-section section1
1000 (get-length pitch1)
(on-the-fly 1 / pitch1 * 10)
pitch1 mf 1)
EXAMPLE 3: (fill-template construct-stockpile table1
(make-lookup-table 30 1 50 5 80 2.5))
EXAMPLE 4: (fill-template data-section section2
200 (get-length pitch1)
(lookup pitch1 table1)
pitch1 mf 1)
EXAMPLE 5: (fill-template data-section section3
200 (get-length pitch1)
(lookup pitch1 table1 :interpolate t)
pitch1 mf 1)
EXAMPLE 6: (fill-template data-section section4
200 (get-length pitch1)
(lookup pitch1
(make-lookup-table 30 (rv 1.0 2) 50 (rv 2.0 3)
60 (rv 1.0 5)))
pitch1 mf 1)
EXAMPLE 7: (fill-template generate-stockpile pitch2
50 (random-value 40 80))
EXAMPLE 8: (fill-template data-section section5
100 (get-length pitch2)
(act-if pitch2
> 60 (rv 1.0 2)
else = 60 3
else (rv 3.5 5))
pitch2 mf 1)
EXAMPLE 9: (fill-template scheme scheme1
pitch2 section5)
EXAMPLE 10: (fill-template generate-sequential-section
sequential1 3 2 section5 pitch2 nil nil nil)
EXAMPLE 11: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1 50 1 0 (random-value 0.1 0.5)
0.2 (on-the-fly 100.0 / (par 'duration)))
(remake&vary &rest objects)
Returns a closure. When applied, it remakes all but the last object used as an argument in the order indicated. The last argument is varied (but not remade). This is useful if, for example, a stockpile is generated, that stockpile is used in a section, and the section is varied to produce a community.
Stated another way, all objects but the last object are destructively modified. The last object is varied without changing the original object.
For example, if stock1, stock2, and section1 existed:
(remake&vary stock1 stock2 section1)
would redefine stock1 and stock2 and would vary section1 without changing its previous value.
Examples 1-3 produces objects which are used for the community (example 4).
Note that something similar to REMAKE&VARY could also be achieved by using
the dialog GENERATE SEQUENTIAL SECTION.
EXAMPLE 1: (fill-template generate-stockpile pitch1 30
(random-value c2 c5))
EXAMPLE 2: (fill-template generate-stockpile rhythm1 10
(random-value 1.0 2))
EXAMPLE 3: (fill-template data-section s1 100 30 rhythm1 pitch1 mf 1 0)
EXAMPLE 4: (fill-template generate-community com1 4
(remake&vary pitch1 rhythm1 s1))
(remove-doubles &key pitch-class)
Returns a closure for transforming chords. If a pitch value is a list, a new list is returned that contains no double values (example 1).
If the pitch value is not a list, it is returned without change.
To combine remove-doubles with another transformer, use compose (example 2).
In the above example, the values are first transposed, then the double values are removed.
If keyword PITCH-CLASS is bound to t, pitch-classes are examined. Only one pitch per pitch-class is allowed per chord (example 3). Pitches 60 and 36 belond to pitch class 0. Pitches 64 and 76 belongn to pitch class 4.
This transformer assumes that chords are lists of pitches with one duration value. Typically there are made with generators such as MAKE-CHORD, JOIN->CHORD, HARMONIC-CHORD, FM-CHORD, etc. To remove pitch repetitions in sections that have not been made as chords, use the PITCH-REPETITION-FILTER (example 4)
EXAMPLE 1: (show-transformation (remove-doubles)
'(60 (60 64 60 60)))
EXAMPLE 2: (show-transformation
(compose (remove-doubles) (transpose 12))
'(60 (60 64 60 60)))
EXAMPLE 3: (show-transformation (remove-doubles :pitch-class t)
'(60 (60 64 60 36 76)))
EXAMPLE 4: (show-help 'pitch-repetition-filter)
(remove-repetitions generator-or-object &key stop)
Returns a closure. When applied, a new value is derived from GENERATOR-OR-OBJECT. If that value is a repetition of the previously produced value, it is discarded and GENERATOR-OR-OBJECT is asked for a new value. Otherwise the value is returned (examples 1-2).
If GENERATOR-OR-OBJECT keeps producing the same value for STOP number of times in a row, the process is cancelled and an error message appears. The default value for STOP is 100, i.e. the generator will try 100 times to produce a new value before giving up (examples 3-4).
GENERATOR-OR-OBJECT will typically be a generator, a list, or a stockpile.
To remove repetitions from an object that already exists, see REPETITION-FILTER. To remove repetitions in a chord, see REMOVE-DOUBLES.
EXAMPLE 1: (for-example (remove-repetitions '(1 2 3 1 1 1 2 1 1 2)))
EXAMPLE 2: (for-example (remove-repetitions (random-value 1 3)))
EXAMPLE 3: (for-example (remove-repetitions (always 25)))
EXAMPLE 4: (for-example (remove-repetitions (always 25) :stop 20))
(remove-successive)
Returns a closure that is intended to be used in transforming chords. If a pitch value is a list, a new list is returned without the pitches that were in the previous chord (example 1).
If the pitch value is not a list, it is returned without change.
This transformer only works with chords that were explicitedly entered as lists or were created with make-chord. For other sections, use the PITCH-REPETITION-FILTER with the FILTER method.
To remove doubling within a chord entered as a list or made with make-chord, use transformer REMOVE-DOUBLES.
Remove-successive may result in the removal of all pitches from an event. Although this has no effect on the functionality of the Toolbox, it results in the number of events being higher than the number played, plotted, printed, etc. To clean-up the empty events (the ones with no pitch) from a section, use tool clean-up-blanks. This change is destructive and irreversible.
EXAMPLE 1: (show-transformation (remove-successive)
'(60 (60 64 67) (60 64 67) (60 64 69)))
(render-csd &optional open filename print)
This tool can be used to render an existing unified Csound file (with extension csd). The file will be rendered using the options specified in the file and not those of the Csound File Options dialog.
In particular, this means that the various directories, audio header, sample format, as well as the choice of rendering to file or in realtime will be those that were included in the file.
A csd file includes an orchestra definition and that definition is what is used to render the file (example 1).
If the csd file renders to an audio file, that audio file will be opened for performance in the default program for files of that type (aif or wav). If this behavior is not desired, bind open to nil. The file will then be rendered but not opened (example 2).
To render existing csd files using the current Csound File Options, use tool REPLACE-CSD-OPTIONS.
RENDER-CSD is not needed when Csound score objects are applied and rendered. Instead, it could be useful to render a file at a later time. Also when a file is rendered in real time, this tool could be used to render the file again.
FILENAME can be bound to a path for a csd file. RENDER-CSD will otherwise ask for a file name.
Csound files generated by the AC Toolbox can, in any case, be rendered using this tool. The assumption is that all csd files will contain a setting for the SFDIR directory within the file as is the case with files produced by the AC Toolbox.
If PRINT is true, the messages returned from Csound are printed in the Text Output window. The default value for PRINT is the value for for the check box MESSAGES in the Csound File Options.
An existing Csound csd file can also be rendered by selecting the RENDER FILE button in the Csound File Options.
The menu item Other>Render CSD will render the most recent csd file in the current session.
EXAMPLE 1: (render-csd)
EXAMPLE 2: (render-csd nil)
(render-osc &optional infile)
Renders an existing OSC file to audio using the options for sample rate, etc. that are specified in the OSC File Options dialog.
If the OSC file uses an audio input file, that file should be chosen in the OSC File Options dialog.
This tool is not needed when OSC Scores are applied and rendered. It could be useful to render an OSC file without specifying an OSC Score object if the sound file is no longer available. Another use would be to test an OSC file with different audio input files (example 1).
This tool can be used in a Listener window, among other places. INFILE is an optional parameter for a file name to be rendered.
EXAMPLE 1: (render-osc)
rendering csound
If Csound5 or higher has been installed in /usr/local/bin, Csound csd files can be rendered to audio signals or files by the AC Toolbox.
Installation instructions are in the help item for Installing Csound.
The options controlling the way a csd file is rendered can be found in the Csound File Options dialog. A summary of these options can be seen by clicking on the ? button in that dialog.
If the csd file is rendered to an audio file and the option Open Audio File After Rendering has been checked, the file will open in the default program for that file type or in a different application chosen in the Csound File Options.
If no sound can be heard after rendering a Csound file, check the directory specifications in the Csound File Options. If sample or analysis files are needed, the correct directory for such a file must be chosen.
If the directories are correct but still no sound is heard, there may be a syntax error in the Csound specification. When 'Display Messages' is chosen, Csound prints various messages and warning to the Text Output window. This might be useful in tracking errors. Check that all necessary P fields are receiving values. Make sure any function definitions have been made in the header if they are not included as part of the orchestra file.
If files are rendered in realtime, they can be stopped with the Menu item Others>Kill or cmd-K. Performance in realtime may be improved by not printing amplitudes or displaying graphics. Using the 32-bit version of Csound also improves real-time performance.
If the new audio file would have the same name as one which is open in another program such as QuickTime Player, the open file should be closed before rendering the new one.
(repetition-filter)
Produces a filter that will filter out successive repetitions of a value. This filter is intended for use with the FILTER method or with FILTER-STOCKPILE. It can also be used with WITH and WITHOUT.
To use with the FILTER method: choose OTHER as the filter type then use (repetition-filter) to produce the filter.
If SECTION1 exists, example 1 will filter pitch repetitions.
Example 2 demonstrates use with FILTER-STOCKPILE.
EXAMPLE 1: (fill-template filter section1f section1
(other (repetition-filter))
'pitch t)
EXAMPLE 2: (for-example
(filter-stockpile '(1 2 2 2 3 3 4 5 5)
(repetition-filter)))
repetitions: prevent or remove
There are different ways of preventing the generation of repetitions or removing them once they have occurred. The choice depends on the context and the amount of information available when generating a parameter, transforming a parameter, or filtering an object.
The following is an attempt to clarify some of the possibilities to prevent or remove repetitions. More information can be found in the help for the various generators, tools, and transformers.
PREVENTING REPETITIONS
REMOVE-REPETITIONS
This is a generator. The input is another generator or an object from which values can be derived. If the generator produces a repetition (a value that is the same as the preceding one), the value is discarded and the generator is asked for a new value. It is up to the user to make sure that the generator can actually produce non-repeating values (examples 1-2).
DUPLICATES
This is a tool that is used together with the generator WITHOUT. Without produces values that are not excluded by a condition. DUPLICATES is such a condition. It disallows any value which has already occurred. It is not limited to the preceding value but any value in the current series (examples 3-4).
MAKE-CHORD
This generator is to produce chords (pitches) which are represented as a list. Repetitions can be blocked in two different ways.
Within a chord, the interval 0 (unison) can be blocked. This means that the same pitch will not occur in a chord (example 5).
Repetition of pitches in successive chords (i.e. that a pitch in one chord occurred in the previous one) can be blocked by binding the key word allow-repeats to nil (examples 6-7).
BLOCK-INTERVAL
This generator is wrapped around another generator which produces values. One or more intervals can be blocked. If the interval 0 is blocked, the next value cannot be the same as the current one (example 8).
CONVERT
When converting a mask to a list of numbers chosen within that mask, it is possible to block one or more intervals using the parameter INTERVAL-OR-LIST. The interval refers to successive values (examples 9-11).
REMOVING EXISTING REPETITIONS
REMOVE-DOUBLES
This is a transformer for use with the pitch parameter. If a chord contains the same pitch more than once, all but one of the pitches is removed. Chords would have to have been originally expressed as a list or with MAKE-CHORD for this transformer to have effect. If the chords were not made as a list, use the filter PITCH-REPETITION-FILTER with the filter method (example 12).
REMOVE-SUCCESSIVE
This is a transformer for use with the pitch parameter. It compares successive chords. If a pitch in the current chord occurred in the previous one, it is removed. Chords would have to have been originally expressed as a list or with MAKE-CHORD for this transformer to have effect.If the chords were not made as a list, use the filter PITCH-REPETITION-FILTERwith the filter method (example 13).
REPETITION-FILTER
This filter will filter out successive repetitions of a value (in a series). It can be used with the filter method or with FILTER-STOCKPILE (example 14).
PITCH-REPETITION-FILTER
This filter is not limited to filtering a sequence of numbers. It examines the start times of pitch values in a section and removes repetitions that could occur across various layers. Pitch repetitions occuring at the same time or in succession are filtered.
An example involving several layers can be found in the help for this filter.
MAP-TRACKS
Data read from a sound analysis file (made with Hetro or Spear) is mapped to note information. Since the analysis data could include a lot of repetitions once frequency has been mapped to pitch, the pitch-repetition-filter is built into this tool. It can be activated by binding the key word filter to t.
EXAMPLE 1: (for-example (remove-repetitions '(1 2 3 1 1 1 2 1 1 2)))
EXAMPLE 2: (for-example (remove-repetitions (rv 1 4)))
EXAMPLE 3: (for-example (without (duplicates)
(random-value 1 20)))
EXAMPLE 4: (for-example (without (duplicates :diversity 10)
(random-value 1 20)))
EXAMPLE 5: (for-example
(make-chord (rv 60 66) 3 :block 0))
EXAMPLE 6: (for-example
(make-chord (rv 60 66) 3 :allow-repeats nil))
EXAMPLE 7: (for-example
(make-chord (rv 60 66) 3 :block 0 :allow-repeats nil))
EXAMPLE 8: (for-example (block-interval (rv 1 5) 0))
EXAMPLE 9: (fill-template specify-mask mask1 '(20 100) '(1 80))
EXAMPLE 10: (plot mask1)
EXAMPLE 11: (for-example (convert mask1 50 40 80 t 0))
EXAMPLE 12: (show-transformation (remove-doubles)
'((60 64 67) (60 64 60 60)))
EXAMPLE 13: (show-transformation
(remove-successive)
'((60 64 67) (60 65 67) (60 64 69)))
EXAMPLE 14: (for-example
(filter-stockpile '(1 2 2 2 3 3 4 5 5)
(repetition-filter)))
(replace-all with)
Returns a closure. When applied, each element being transformed is replaced with the next value from WITH. WITH may be a constant, list, or generator.
When defining a transformation, pitch could be transformed as follows:
(replace-all 60)
which would replace all pitches in a section with 60 (example 1).
(replace-all (random-value 40 80))
would replace each pitch with a random value between 40 and 80.
EXAMPLE 1: (show-transformation (replace-all 60)
'(40 50 60 70 80))
(replace-as-rhythm with &optional clock-unit)
Returns a closure that can be used to replace one or more of the time parameters of a section: tempo, attacks, and duration. These parameters are replaced by specifying rhythmic values and a CLOCK-UNIT (in milliseconds). CLOCK-UNIT can also be bound to the name of a section or community, in which case the CLOCK-UNIT will be derived from that section or community.
When this closure is applied, each element being transformed is replaced with the next value from WITH multiplied by the CLOCK-UNIT. WITH may be a constant, list, or generator. CLOCK-UNIT may be a number, the name of section to use to derive the clock unit, or it may be left empty in which case it receives the value 1.
Example 1 can be used to create section ex1.
Example 2 transforms the tempo of this section by replacing all attacks and durations with 10 milliseconds.
Example 3 transforms the tempo by replacing attacks and durations with 200 100 200 100 ...
Example 4 transforms the tempo by replacing the attacks and duration by the output of generator times the clock unit of section ex1.
Example 5 transforms only the attacks and does not change the durations.
EXAMPLE 1: (fill-template data-section ex1 100 50
(rv 1.0 2) (rv 50 70) f 1)
EXAMPLE 2: (fill-template transform ex2 ex1
:tempo (replace-as-rhythm 10))
EXAMPLE 3: (fill-template transform ex3 ex1
:tempo (replace-as-rhythm '(2 1) 100))
EXAMPLE 4: (fill-template transform ex4 ex1
:tempo (replace-as-rhythm (random-value 1 5) ex1))
EXAMPLE 5: (fill-template transform ex5 ex1
:attacks (replace-as-rhythm (random-value 1 5) ex1))
(replace-by-index to-produce-index to-produce-value)
Returns a closure. It will transform an object by replacing values at indicated positions with a new value. The two inputs can be generators, lists, constants, or stockpiles.
TO-PRODUCE-INDEX should produce valid index numbers. The index values start from 1. At each of these index values, the content of the object will be replaced with a value that comes from TO-PRODUCE-VALUE.
Example 1 is a section to be transformed.
Example 2 replaces the pitches in notes 1,3,and 5 of a section with a random value. When TO-PRODUCE-INDEX is a list or stockpile, the duplicate values are removed and the remaining values are sorted in ascending order.
Example 3 uses WALK to calculate index values for the replacement. Index values need to be in ascending order. If they are not in ascending order, the highest, non-descending value is the last value transformed.
Example 4 uses PRODUCE to produce a list of index values. REPLACE-BY-INDEX will sort this list and remove duplicate values. This could mean that fewer values than expected are transformed. In this example series-value was used to avoid repetitions.
Another way to avoid repeated values is to filter the output of the generator used for producing the index values. This is done in example 5.
Example 6 produces a stockpile called melody2. Example 7 will insert values from melody2 at random locations.
EXAMPLE 1: (fill-template data-section section1
100 48 1 (chromatic c2) mf 1)
EXAMPLE 2: (fill-template transform trans1 section1
:pitch (replace-by-index '(1 3 5)
(random-value c7 c8)))
EXAMPLE 3: (fill-template transform trans2 section1
:pitch (replace-by-index
(walk 3 (random-value 1 7))
(random-value c7 c8)))
EXAMPLE 4: (fill-template transform trans3 section1
:pitch (replace-by-index
(produce 10 (series-value 1 48))
(random-value c7 c8)))
EXAMPLE 5: (fill-template transform trans4 section1
:pitch (replace-by-index
(produce 10
(without (duplicates) (random-value 1 48)))
g#6))
EXAMPLE 6: (fill-template construct-stockpile melody2
(extract 'pitch wilhelmus))
EXAMPLE7: (fill-template transform trans5 section1
:pitch (replace-by-index
(make&sort 20 (series-value 1 48))
melody2))
(replace-csd-options)
This tool allows the Csound file options present in a Csound (csd) file to be replaced with the options currently specified in the Csound File Options dialog.
It can be used to change the sample format, audio header, etc. or allow a file which was originally rendered in realtime to be rendered to an audio file. The realtime rendering could be used for testing. When something desirable is found, that file could have the options replaced with the options to render to an audio file.
The tool copies an input file to a new output file. The options will be changed in the output file. All other data is copied without change. The tool will ask the user for both the original file and the name for the new file (example 1).
If the option for Render is chosen in the Csound File Options dialog, the new file will be rendered.
This tool does not replace the orchestra file.
EXAMPLE 1: (replace-csd-options)
(replace-if condition value replace-with &optional otherwise)
Returns a closure that replaces a value if a condition is met. CONDITION is applied to the element being transformed and to VALUE. If the result is true, the next value produced from REPLACE-WITH is returned. REPLACE-WITH may be a constant, sequence, or generator.
In example 1, any value > 60 is replaced with 59.
In example 2, any value < 60 is replaced with a random value between 48 and 60.
The optional parameter OTHERWISE can be used to replace a value if the condition is NOT met. Example 3 will replace any values = 60 with 72 and all other values will be 40.
OTHERWISE may be a constant, sequence, generator, etc. In example 4 it is a generator.
In earlier versions of the AC Toolbox, the condition argument had to be preceded by a function quote: #'. This is no longer necessary though it may be used (example 5).
EXAMPLE 1: (show-transformation
(replace-if > 60 59) '(40 50 60 70 80))
EXAMPLE 2: (show-transformation
(replace-if < 60 (random-value 40 60))
'(40 50 60 70 80))
EXAMPLE 3: (show-transformation
(replace-if = 60 72 40) '(40 50 60 70 80))
EXAMPLE 4: (show-transformation
(replace-if = 60 72 (random-value 40 60))
'(40 50 60 70 80))
EXAMPLE 5 : (show-transformation
(replace-if #'>= 50 50) '(40 50 60 70 80))
(replace-value old-value new-value)
Returns a closure. If the value to be transformed is equal to OLD-VALUE, it is replaced with the next value from NEW-VALUE. OLD-VALUE and NEW-VALUE may be a constant, list, generator, etc. (examples 1-3).
If a single value, for instance a single pitch, is to be replaced with a list of values (a chord), then that list should be within a list (example 4).
EXAMPLE 1: (show-transformation (replace-value 60 61)
'(60 62 64 65 60 67))
EXAMPLE 2: (show-transformation (replace-value 60 '(48 72))
'(60 62 64 65 60 67))
EXAMPLE 3: (show-transformation
(replace-value 60 (random-value 48 72))
'(60 62 64 65 60 67))
EXAMPLE 4: (show-transformation (replace-value 60 '((48 72)))
'(60 62 64 65 60 67))
(retrograde-stockpile stockpile)
Returns a list made by reversing STOCKPILE. STOCKPILE may be a list or stockpile (examples 1-2).
If the input is a pitch-matrix, each row (list) in the matrix is reversed (examples 3-4).
This is different from using the method BACKWARDS that would reverse the order of the lists, but not the order of their contents (example 5).
EXAMPLE 1: (print-result
(retrograde-stockpile '(0 8 11 6 9 4 10 2 7 1 5 3)))
EXAMPLE 2: (print-result
(retrograde-stockpile
'(67 70 61 68 66 71 60 62 69 64 65 63)))
EXAMPLE 3: (for-example
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3))
:number-per-line 1)
EXAMPLE 4: (for-example
(retrograde-stockpile
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3)))
:number-per-line 1)
EXAMPLE 5: (for-example
(backwards
(pitch-matrix '(0 8 11 6 9 4 10 2 7 1 5 3)))
:number-per-line 1)
(rewrite symbol rule-system &key reality sequence)
Returns a list of elements produced by applying the rewrite rules described in RULE-SYSTEM. A symbol on the left side of a rule is replaced by the object on the right side. These objects are also rewritten until a symbol is found which does not occur on the left-side. This is a simple implementation of a context-free grammar.
In a classic context-free grammar, the right side could contain one symbol, or more than one symbol joined by OR or AND. In the AC Toolbox implementation, AND is replaced by a list, COLLECT-THINGS or PRODUCE. OR is replaced by the use of a generator which makes choices (RANDOM-CHOICE, BETA-CHOICE, etc.) If a list is created on the right side, each symbol in the list is rewritten.
COLLECT-THINGS gathers the elements into a list. If the element is a generator, it is applied to get a value, otherwise the element is returned without evaluation (example 1).
A rule system can be specified using the template for rule stockpile in the stockpile definition menu.
_________________________________________________
Examples 2 and 3 are a simple examples not involving any actual AC Toolbox objects.
Example 2 is a rule system.
GRAMMAR1 specifies that SENTENCE is rewritten as a list with a noun, verb, and a noun.
NOUN is rewritten as either GEORGE or STUFF.
VERB is rewritten as EATS, DRINKS or TAKES.
Example 3 uses the above rule system and starts rewriting with SENTENCE.
The keyword :reality is bound to NIL since the terminal symbols are not part of reality (i.e. the AC Toolbox environment). If this keyword were bound to t (the default situation) an error message would occur when a symbol is produced which does not exist in the rule system or in the AC Toolbox environment.
The rewriting can start with any lefthand symbol, allowing one to zoom in on any portion of the rule system. Example 4 starts rewriting with NOUN.
_________________________________________________
A rule system for pitch can be defined (examples 5-7).
MELODY is rewritten as a list containing phrase1, phrase2, and phrase1 again.
PHRASE1 is a list of 8 pitches using the symbols for pitches which have been defined in the AC Toolbox.
PHRASE2 is a list selected from a different group of pitches.
Note that when the right side of the rule is made with PRODUCE, a new list is made each time the symbol is rewritten.
When the rule system is rewritten, it is saved as a stockpile (example 6). The section (example 7) using this stockpile can then apply GET-LENGTH to get the number of values created by rewriting. Although in this example the number of values is known in advance, with other systems this might not be the case.
_________________________________________________
The Wilhelmus can be described with a rule system (examples 8-9).
The names of objects defined in the AC Toolbox environment and constructors for such objects (such as A-NOTE) may be used on the right side of a rule (example 8).
WILHELMUS is rewritten as a list with four symbols. Each of those symbols is rewritten as a list with two symbols. Each one of those lists is rewritten as a list of symbols representing notes. Finally each of the symbols representing notes is rewritten with the AC Toolbox tool A-NOTE which produces a note with a rhythm, pitch, velocity and channel value. Since A-NOTE is known by the AC Toolbox, it does not need to be rewritten. Rewriting continues until there is no symbol to be rewritten.
If the the keyword :sequence is t, the rewrite function produces an IN-SEQUENCE note structure. This makes it usable for structured sections (example 9).
To start at a different place in the rule-system in example 9, replace 'wilhelmus with another left-hand symbol, for example 'b.
_________________________________________________
Indeterminacy can be introduced into the rule-system by specifying several choices (examples 10-11).
_________________________________________________
Rhythms can be expressed as a rule system (examples 12-14). DRUM-RULES is a rule system to produce a pattern with 100 symbols. Symbols vary from ONE (which is a single beat) to FIVE (which is a collection of other elements). Negative values for rhythm produce rests.
_________________________________________________
More information about the musical implications of rule systems or grammars can be found in:
C. Roads. (1985). "Grammars as representations for music". In C. Roads and J. Strawn (eds.) The Foundations of Computer Music. Cambridge MA: MIT Press.
EXAMPLE 1: (print-result (collect-things a b (random-value 1 10)
(random-choice '(b c d))))
EXAMPLE 2: (fill-template rule-stockpile grammar1
sentence -> (collect-things noun verb noun)
noun -> (random-choice '(george stuff))
verb -> (random-choice '(eats drinks takes)))
EXAMPLE 3: (print-result (rewrite 'sentence grammar1 :reality nil))
EXAMPLE 4: (print-result (rewrite 'noun grammar1 :reality nil))
EXAMPLE 5: (fill-template rule-stockpile simple-rules1
melody -> (phrase1 phrase2 phrase1)
phrase1 -> (produce 8
(random-choice
'(c3 d3 e3 f3 g2 b2 a2)))
phrase2 -> (produce 8
(random-choice
'(f4 f#4 g4 a4 a#4 b5 c5))))
EXAMPLE 6: (fill-template construct-stockpile pitch1
(rewrite 'melody simple-rules1))
EXAMPLE 7: (fill-template data-section test1 150
(get-length pitch1)
1 pitch1 mf 1)
EXAMPLE 8: (fill-template rule-stockpile wilhelmus-rules
wilhelmus -> (a a b a1)
a -> (first-half-a second-half-a)
b -> (first-half-b second-half-b)
a1 -> (first-half-a1 second-half-a1)
first-half-a -> (n1 n6 n6 n8 n12 n14 n8 n13)
second-half-a -> (n8 n12 n15 n13 n8 n5 n9 n7)
first-half-b -> (n12 n14 n16 n17 n16 n15 n13)
second-half-b -> (n8 n12 n15 n13 n9 n6 n11)
first-half-a1 -> (n1 n5 n3 n5 n8 n13 n10 n6 n4 n1)
second-half-a1 -> (n2 n3 n6 n6 n4 n7)
n1 -> (a-note 2 62 64 1)
n2 -> (a-note 1 64 64 1)
n3 -> (a-note 1 66 64 1)
n4 -> (a-note 2 66 64 1)
n5 -> (a-note 1 67 74 1)
n6 -> (a-note 2 67 64 1)
n7 -> (a-note 6 67 64 1)
n8 -> (a-note 1 69 64 1)
n9 -> (a-note 2 69 64 1)
n10 -> (a-note 4 69 64 1)
n11 -> (a-note 6 69 64 1)
n12 -> (a-note 1 71 64 1)
n13 -> (a-note 2 71 64 1)
n14 -> (a-note 1 72 64 1)
n15 -> (a-note 2 72 64 1)
n16 -> (a-note 6 74 64 1)
n17 -> (a-note 2 76 64 1))
EXAMPLE 9: (fill-template structured-section new-wil 150
(rewrite 'wilhelmus wilhelmus-rules
:sequence t))
EXAMPLE 10: (fill-template rule-stockpile confused-wil
wilhelmus -> (collect-things a (random-choice '(a b))
(random-choice '(a b)) a1)
a -> (first-half-a second-half-a)
b -> (first-half-b second-half-b)
a1 -> (first-half-a1 second-half-a1)
first-half-a -> (produce
8
(series-choice
'(n1 n6 n6 n8 n12 n14 n8 n13)))
second-half-a -> (produce
8
(series-choice
'(n8 n12 n15 n13 n8 n5 n9 n7)))
first-half-b -> (produce
7
(series-choice
'(n12 n14 n16 n17 n16 n15 n13)))
second-half-b -> (produce
7
(series-choice
'(n8 n12 n15 n13 n9 n6 n11)))
first-half-a1 -> (produce
10
(series-choice
'(n1 n5 n3 n5 n8 n13 n10 n6 n4 n1)))
second-half-a1 -> (n2 n3 n6 n6 n4 n7)
n1 -> (a-note 2 62 64 1)
n2 -> (a-note 1 64 64 1)
n3 -> (a-note 1 66 64 1)
n4 -> (a-note 2 66 64 1)
n5 -> (a-note 1 67 74 1)
n6 -> (a-note 2 67 64 1)
n7 -> (a-note 6 67 64 1)
n8 -> (a-note 1 69 64 1)
n9 -> (a-note 2 69 64 1)
n10 -> (a-note 4 69 64 1)
n11 -> (a-note 6 69 64 1)
n12 -> (a-note 1 71 64 1)
n13 -> (a-note 2 71 64 1)
n14 -> (a-note 1 72 64 1)
n15 -> (a-note 2 72 64 1)
n16 -> (a-note 6 74 64 1)
n17 -> (a-note 2 76 64 1))
EXAMPLE 11: (fill-template structured-section confused 150
(rewrite 'wilhelmus confused-wil
:sequence t))
EXAMPLE 12: (fill-template rule-stockpile drum-rules
pattern -> (produce 100 (random-choice '(one two three four five)))
one -> 1
two -> '(1 -1)
three -> '(1 -1 1)
four -> (collect-things two two three three (rc '(two three)))
five -> (collect-things three two three two two))
EXAMPLE 13: (fill-template construct-stockpile rhythm
(rewrite 'pattern drum-rules))
EXAMPLE 14: (fill-template data-section rhythm-section 150
(get-length rhythm) rhythm
(random-choice '(60 61 63 64 66 76 77))
f 10)
(rf stockpile index-values &optional number generator)
This is a shortcut for READ-FROM. When applied, a value from
STOCKPILE is returned. The values are in the order determined
by INDEX-VALUES (examples 1-3).
STOCKPILE may be a list, stockpile, section, etc.
INDEX-VALUES can be a list, stockpile, shape, mask, or generator.
See the documentation for READ-FROM for more information (example 4).
EXAMPLE 1: (for-example (read-from '(a b c d e) '(3 1 5 2 4)))
EXAMPLE 2: (for-example (read-from '(a b c d e)
(series-value 1 5)))
EXAMPLE 3: (for-example
(read-from '(a b c d e f g h i j k)
sine-shape 20))
EXAMPLE 4: (show-help 'read-from)
rhythm
Rhythm is expressed as multiples of the clock unit. 1 is the clock unit. 2 is twice the clock unit, etc. Rhythms do not have to be integers.
Negative values indicate a rest.
(ring-modulate-chord chord1 chord2 &key round name base block0)
Returns a closure. When applied, a chord (expressed as a list of Midi note numbers) is returned. The chord contains a simulation of the ring modulation of each pitch of CHORD1 by all pitches of CHORD2.
The frequency equivalent of each pitch in CHORD2 is added to and subtracted from the frequency equivalent of each pitch in CHORD1.
This generator reflects ideas present in the field of spectral composition.
CHORD1 and CHORD2 should be specified as a list, stockpile, generator, etc. (example 1).
Example 2 can be used to see a table of the frequency equivalents of all Midi notenumbers.
Example 3 produces the frequency equivalent of one notenumber, e.g. 60.
Example 4 produces the notenumber closest to a certain frequency, e.g. 100 Hz.
Both chords may have any number of pitches (example 5).
Note that if the same note number occurs in both chords, the result of subtracting the corresponding frequencies is 0 (example 6).
Note number 0 can be removed by binding the keyword BLOCK0 to t (example 7).
Negative frequencies are reflected to be positive. Frequencies that are lower than 8.175798915643707 Hz which corresponds to Midi notenumber 0 will be converted to notenumber 0 instead of to some fictitious negative Midi number.
CHORD1 and CHORD2 may vary over time (example 8).
If CHORD1 or CHORD2 should consist of only one value but that value should vary over time, use MAKE-CHORD with a chord size of 1. Otherwise the additional values may be seen as part of a chord. In example 9, 60 and 55 are ring modulated, then 62 and 55.
The default value for ROUND is t. This will round off the Midi note numbers to be integers. If real numbers are desired, ROUND should be bound to NIL (example 10). If ROUND is bound to another number, such as 0.5, the values will be quantized using that value. 0.5 rounds to quarter-tones (example 11).
Keyword NAME controls whether pitches are returned as numbers or as note names. When it is bound to T, note names are printed (example 12).
When note names are printed and pitches are real numbers, pitches can be printed with the digits after the decimal point. ROUND should be bound to nil in this case (example 13).
Keyword BASE is for specifying a reference frequency for Midi note number 69 (a4). It defaults to 440.0 Hz (example 14).
Chords can be filtered for repetitions and other intervals with CLEANUP-CHORD (example 15).
Chords can be combined into one chord with JOIN->CHORD (example 16).
Chords can be converted to a different range with CONVERT2 (example 17).
EXAMPLE 1: (for-example
(make (ring-modulate-chord '(60 62) '(43))))
EXAMPLE 2: (show-midi->hz)
EXAMPLE 3: (for-example (make (midi->hz 60))
EXAMPLE 4: (for-example (make (hz->midi 100 :round t)))
EXAMPLE 5: (for-example
(make (ring-modulate-chord
'(60 62 64)
'(10 43 59))))
EXAMPLE 6: (for-example
(make (ring-modulate-chord '(60 62) '(60 64))))
EXAMPLE 7: (for-example
(make (ring-modulate-chord '(60 62) '(60 64) :block0 t)))
EXAMPLE 8: (for-example
(ring-modulate-chord (make-chord (walk 24 3) 3)
'(43 10))
:number-per-line 1 :number 4)
EXAMPLE 9: (for-example
(ring-modulate-chord (make-chord '(60 62) 1)
'(55))
:number 2)
EXAMPLE 10: (for-example
(make (ring-modulate-chord
'(60 62) '(43 10) :round nil)))
EXAMPLE 11: (for-example
(make (ring-modulate-chord
'(60 62) '(43 10) :round 0.5)))
EXAMPLE 12: (for-example
(make (ring-modulate-chord
'(60 62) '(43 10) :name t)))
EXAMPLE 13: (for-example
(make (ring-modulate-chord
'(60 62) '(43 10) :name t :round nil)))
EXAMPLE 14: (for-example
(make (ring-modulate-chord
'(60 62) '(43 10) :base 415)))
EXAMPLE 15: (show-help 'cleanup-chord)
EXAMPLE 16: (show-help 'join->chord)
EXAMPLE 17: (show-help 'convert2)
(ro value unit)
This generator is a shortcut for ROUND-OFF.
It rounds off values produce by VALUE to be multiples of UNIT (examples 1-2). This could be useful in dealing with microtones or in quantizing rhythmic values.
See the documentation for ROUND-OFF for more information and examples (example 3).
EXAMPLE 1: (for-example (ro (random-value 60.0 72) 0.5))
EXAMPLE 2: (for-example (ro (rv 1.0 3) .25))
EXAMPLE 3: (show-help 'round-off)
(roessler x y z mu giant &key eye zet xy xyz (stepsize 0.01) first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
x'=-(y+z)
y'=x+1/5y
z'=1/5+z(x-mu)
The default output variable is X. By using the keyword EYE the variable Y is returned. By using the keyword ZET the variable Z is returned.
X, Y, and Z are initial values. MU is controlling the behaviour of the system.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period (examples 1-4).
It is not possible to predict the maximum and minimum of the output values. To map the output of this function to useful values, use CONVERT (example 5).
The initial values for X, Y, and Z are not returned. If the initial values should be returned as the first result of the generator, keyword FIRST should be bound to t (examples 6-7).
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (roessler 1.0 2.0 0.1 1.0 10) :number 300)
EXAMPLE 2: (plot (roessler 1.0 2.0 0.1 5.7 10) :number 300)
EXAMPLE 3: (plot (roessler 1.0 2.0 0.1 30.8 10) :number 300)
EXAMPLE 4: (plot (roessler 1.0 2.1 0.1 5.7 10 :xy t) :number 600)
EXAMPLE 5: (for-example
(convert (roessler 1.0 2.1 0.1 5.7 10) 100 c2 c5))
EXAMPLE 6: (for-example (roessler 1.0 20.0 0.1 1.0 10))
EXAMPLE 7: (for-example
(roessler 1.0 20.0 0.1 1.0 10 :first t))
(round-off value unit)
Returns a closure. When applied, one value produced from VALUE is rounded off in terms of the units produced by UNIT.
VALUE and UNIT can change over time. They can be constants, lists, stockpiles, generators, etc (examples 1-3).
Among other things, this could be useful dealing with microtones. In example 4, pitch values between 60.0 and 72 are rounded to quarter-tone values.
If VALUE contains chords (lists of pitches), each pitch is rounded (example 5).
ROUND-OFF can be abbreviated to RO (example 6).
ROUND-OFF is a generator. For a tool that rounds one value, seel ROUNDQ (example 7).
Many generators have a keyword ROUND which makes the use of ROUND-OFF no longer necessary (example 8).
EXAMPLE 1: (for-example (round-off '(1 2 3 4 5 6 7 8 9 10) 2))
EXAMPLE 2: (for-example (make (round-off 1.3 0.5)))
EXAMPLE 3: (for-example (round-off (random-value 1 100) 5))
EXAMPLE 4: (for-example (round-off (random-value 60.0 72) 0.5))
EXAMPLE 5: (for-example (round-off '((60 64.75) (66.23 78.2 81.4)) .5))
EXAMPLE 6: (for-example (ro (rv 60.0 72) 0.5))
EXAMPLE 7: (print-result (roundq 3.425 0.25))
EXAMPLE 8: (for-example (random-value 60.0 72 :round 0.5))
(roundq value round)
This tool rounds or quantizes, depending on your viewpoint. VALUE is number to be rounded or a list or stockpile of numbers to be rounded. ROUND controls how the value is rounded.
If ROUND is a number, VALUE will be quantized to that unit (examples 1-2).
If ROUND is t, the Lisp function round will be applied. This rounds the value to an integer (example 3).
If ROUND is nil, VALUE is returned without any change (example 4).
If VALUE is a list or stockpile, a list is returned with the rounded values (example 5).
This tool can also be used with generator ON-THE-FLY (examples 6-7) or transformer TRAN (example 8).
Note that ROUNDQ is a tool and works with one value, list, or stockpile. For a generator, see ROUND-OFF.
EXAMPLE 1: (print-result (roundq 10.4 .5))
EXAMPLE 2: (print-result (roundq 10.4 1))
EXAMPLE 3: (print-result (roundq 10.4 t))
EXAMPLE 4: (print-result (roundq 10.4 nil))
EXAMPLE 5: (print-result (roundq '(1.3 2.8 4.2) .25))
EXAMPLE 6: (for-example
(on-the-fly (from 1 20) + (rv -1.0 1) roundq 0.25))
EXAMPLE 7: (for-example (on-the-fly (line 15 1.0 20) * 2 roundq 1))
EXAMPLE 8: (for-example
(transform-stockpile '(1 1.4 1.6 1.7 2)
(tran * 2 roundq 0.5)))
(rs stockpile type &optional a b)
This is a shortcut for REARRANGE-STOCKPILE. It returns a list made by rearranging STOCKPILE according to one of the available types. STOCKPILE should be a list or stockpile. TYPE should one of the following:
shuffle
swap
rotate-left
rotate-right
adjacent
order
A and B are optional parameters that may be needed for certain types of rearrangements.
SHUFFLE rearranges the stockpile in a random order (example 1).
SWAP exchanges values at two locations in a stockpile. Locations are numbered starting with 1. A and B receive the numbers of the locations to be swapped (examples 2-3).
ROTATE-LEFT moves each element in the stockpile one place to the left. The first element in the stockpile moves to the last position. A is the number of rotations (examples 4-5).
ROTATE-RIGHT moves each element in the stockpile one place to the right. The last element in the stockpile moves to the first position. A is the number of rotations (examples 6-7).
ADJACENT swaps the element at location A with the element one place to the right (one location higher) (examples 8-9).
ORDER rearranges the stockpile in the order specified by A. A may be a list, stockpile, generator, etc. with values for locations in the stockpile (examples 10-11). If the order specified by A is longer than the stockpile, the size of the returned stockpile is the length of A (example 12).
A and B may be constant values, a generator, etc. If no value is specified for A, it will have the value 1. If no value is specified for B, it will have the value 2.
EXAMPLE 1: (print-result
(rs '(a b c d e) 'shuffle))
EXAMPLE 2: (print-result
(rs '(a b c d e) 'swap 1 3))
EXAMPLE 3: (print-result
(rs '(a b c d e) 'swap 2 5))
EXAMPLE 4: (print-result
(rs '(a b c d e) 'rotate-left))
EXAMPLE 5: (print-result
(rs '(a b c d e) 'rotate-left 2))
EXAMPLE 6: (print-result
(rs '(a b c d e) 'rotate-right))
EXAMPLE 7: (print-result
(rs '(a b c d e) 'rotate-right 2))
EXAMPLE 8: (print-result
(rs '(a b c d e) 'adjacent 2))
EXAMPLE 9: (print-result
(rs '(a b c d e)
'adjacent (random-value 1 4)))
EXAMPLE 10: (print-result
(rs '(a b c d e) 'order '(4 2 3 5 1)))
EXAMPLE 11: (print-result
(rs '(a b c d e)
'order (series-value 1 5)))
EXAMPLE 12: (print-result
(rs '(a b c d e)
'order '(1 1 2 1 2 3 1 2 3 4 1 2 3 4 5)))
(rv low high &key round check
RV is a shortcut (abbreviation) for RANDOM-VALUE (example 1).
See the help for RANDOM-VALUE for more information (example 2).
EXAMPLE 1: (for-example (rv 1 10))
EXAMPLE 2: (show-help 'random-value)
(sample generator n)
Returns a closure. When applied, the first value produced by GENERATOR is returned. The next time SAMPLE is applied, GENERATOR is applied N times and only returns the Nth result (examples 1-3).
This generator may give an impression how a process develops over a longer time without having to use a large number of values.
GENERATOR may be a generator, stockpile, etc. (example 4).
If a stockpile is sampled, it may allow a stockpile to be used in different contexts since a smaller number of values could be sampled.
N may vary over time (examples 5-7). This allows the sample to be taken at irregular intervals.
A note section can be made by sampling an existing section (examples 8-9).
EXAMPLE 1: (plot (sine 100 0.0 100))
EXAMPLE 2: (plot (sample (sine 100 0.0 100) 5))
EXAMPLE 3: (plot (sample (walk 50 (rv -5 5) 0 100) 10))
EXAMPLE 4: (for-example (sample (from 1 100) 10))
EXAMPLE 5: (for-example (sample (from 1 100) (rv 2 5)))
EXAMPLE 6: (plot (sample (sine 100 40 80) (rv 10 30)))
EXAMPLE 7: (fill-template data-stream stream1 100 1
(sample (sine 100 40 80) (rv 10 30))
f 1)
EXAMPLE 8: (fill-template data-section section1
100 300 1 (line 300 40 80) f 1)
EXAMPLE 9: (fill-template note-section sampled-section
100 100 (sample section1 (group (rc '(1 10 20 30 40 50)) 10)))
(sbl value &optional factor)
SBL is a shortcut for SCALE-BY-LAYERS.
It can be used in Csound score objects and in OSC scores.
It is intended to scale amplitudes when several layers are made.
VALUE can be a generator, constant, etc. for the amplitude value in one layer. This value is scaled by the number of layers in the object. To scale by a smaller number than the number of layers, specify a number for the optional parameter FACTOR. If FACTOR is for example 0.7 and there are 10 layers, amplitude value will be divided by 7 (10 * .7).
See the documentation for SCALE-BY-LAYERS for examples of usage in Csound objects and OSC scores (example 1).
EXAMPLE 1: (show-help 'scale-by-layers)
(sc sequence &key check)
This generator is a shortcut for SERIES-CHOICE.
It chooses randomly from a list or stockpile (SEQUENCE) without repeating a selection until all have been used once (example 1).
If CHECK is bound to t, no repetition will occur between the last value chosen from one stockpile and the first value chosen from the replenished stockpile (example 2).
See the documentation for SERIES-CHOICE for more information (example 3).
EXAMPLE 1: (for-example (sc '(1 2 3 4 5)))
EXAMPLE 2: (for-example (sc '(1 2 3 4 5) :check t)
:number 100)
EXAMPLE 3: (show-help 'series-choice)
(scale-by-layers value &optional factor)
This generator can be used when creating Csound or OSC files. VALUE is scaled by the number of layers that have been specified or calculated for the LAYERS parameter (example 1).
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
In the object score1, the value of the p4 parameter, which is some instrument could be the amplitude parameter, is scaled (divided) by the number of layers. More layers results in a smaller value for this parameter.
VALUE can be a constant, list, generator, etc (example 2).
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
Assuming for the moment that P4 will be used as an amplitude parameter, it is usually not necessary to divide the amplitude by the number of layers. Some portion of the number of layers is enough, for example 70 % of the value. This amount can be expressed as the optional parameter FACTOR and should be in the range 0-1. The number of layers are multiplied by FACTOR before being used to divide VALUE (example 3).
SCALE-BY-LAYERS can be abbreviated to SBL (example 4).
EXAMPLE 1: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 5 100 1 0 (random-value .1 .2)
(scale-by-layers 1)
(random-value 100.0 1000))
EXAMPLE 2: (fill-template osc-score-object osc-score1
100 "sine1" nil nil nil 5 0 "dur" (random-value 0.1 0.2)
"amp" (scale-by-layers (rv 0.4 0.6))
"freq" (random-value 100.0 1000))
EXAMPLE 3: (fill-template csound-score-object score2
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 10 100 1 0 (random-value .1 .2)
(scale-by-layers 1 .7)
(random-value 100.0 1000))
EXAMPLE 4: (fill-template csound-score-object score1
"f1 0 8192 10 1
f2 0 8192 20 2 1"
nil nil 5 100 1 0 (random-value .1 .2)
(sbl 32000)
(random-value 100.0 1000))
(scale-intervals first intervals allowed-values &key stop)
Returns a closure. When applied the first time, FIRST is returned. Then an interval produced by INTERVALS is added to FIRST. If the resulting value is one of the ALLOWED-VALUES, it is returned. Otherwise a new value is chosen until an acceptable one is found (example 1).
This generator limits output to values produced with generated intervals that are contained in the ALLOWED-VALUES.
FIRST can be a generator or a constant value.
If INTERVALS is a generator, it is applied to get the next interval. If INTERVALS is a stockpile or list, the intervals are used in the order they occur in the list or stockpile.
ALLOWED-VALUES should be a stockpile or a list (examples 2-3).
If no acceptable value is found within STOP number of iterations, the generator cancels and produces an error message (example 4).
The default value for STOP is 100. If you think a few more iterations might help the generator find a solution, STOP can be bound to a higher value (example 5).
It is the responsibility of the user that FIRST is an allowed value.
EXAMPLE 1: (for-example (scale-intervals c4
(random-choice '(1 2 -1 -2))
'(48 50 52 53 55 57 59 60 62 64
65 67 69 71 72)))
EXAMPLE 2: (fill-template generate-stockpile c-major
15 (major c3))
EXAMPLE 3: (for-example (scale-intervals (random-choice c-major)
(random-choice '(1 2 -1 -2)) c-major))
EXAMPLE 4: (for-example (scale-intervals 40
(random-choice '(1 2 -1 -2))
'(48 50 52 53 55 57 59 60 62 64
65 67 69 71 72)))
EXAMPLE 5: (for-example (scale-intervals 40
(random-choice '(1 2 -1 -2))
'(48 50 52 53 55 57 59 60 62 64
65 67 69 71 72)
:stop 500))
(scale-tempo object-to-scale model-object)
Returns a closure that can be used to transform the tempo of an object so that it matches the duration of another object.
OBJECT-TO-SCALE is the object being transformed. Its tempo will be stretched so that the total duration of the transformed object is equal to the total duration of MODEL-OBJECT.
OBJECT-TO-SCALE may be a section, community, or midi object.
MODEL-OBJECT may be a section, community, midi object, or a duration in seconds. This transformation only works with sections, communities, and midi objects.
If section1 and section2 exist, then section1 can be scaled to have the duration of section2. (examples 1-3).
After the transformation, section1t would have the same notes as section1 except with a different tempo. The tempo would have been adjusted so that section1t has the same total duration as section2.
MODEL-OBJECT can also be a duration expressed in seconds. The OBJECT-TO-SCALE will be scaled so that the duration is equal to that amount of time.
In example 4, section1 is scaled to last 30 seconds. The name of the transformed section is section1t.
To scale the tempo of midi objects, use SCALE-TEMPO in a similar way.
If controller-data1 exists, it can be transformed (example 5-6).
EXAMPLE 1: (show-info section1)
EXAMPLE 2: (show-info section2)
EXAMPLE 3: (fill-template transform section1t section1
:tempo (scale-tempo section1 section2))
EXAMPLE 4: (fill-template transform section1t section1
:tempo (scale-tempo section1 30))
EXAMPLE 5: (show-info controller-data1)
EXAMPLE 6: (fill-template transform cd1t controller-data1
:tempo (scale-tempo controller-data1 30))
scheduler overdrive
If the preference for Scheduler Overdrive is selected, Midi scheduling uses more CPU time and may be more consistent (this depends on the density of the object being played). When Scheduler Overdrive is turned off, CPU use decreases but there might be an occasional inconsistency in the output (again depending on the density of the object being played). The best choice is determined by trial and error. As a rule of thumb, do not change the current setting unless you think there is a problem. Slower machines may require Scheduler Overdrive sooner than faster ones.
scheme
A scheme of variations contains the names of objects that are to be made in a certain order. When the scheme is applied, those objects are made in that order.
(SECONDS->SAMPLES SECONDS)
Intended for use when writing sound files (using the File>Write Sound File menu item). It returns the number of samples needed for a length of the specified number of SECONDS (examples 1-2). This expression can be used in the edit box for NUMBER in the OPTIONS dialog.
It can also be used in an expression for the Write Sound File dialog (example 3).
The value for sample rate, specified in the options for the Write Sound File dialog, is used for the calculations.
More information about writing sound files can be found in the Index item 'Writing Sound Files'.
EXAMPLE 1: (print-result (seconds->samples 2.5))
EXAMPLE 2: (fill-template write-sf (sine 100 -10000 10000)
(seconds->samples 2))
EXAMPLE 3: (fill-template write-sf
(take (seconds->samples .5)
(rv -10000 10000)
(seconds->samples .5)
(sine (freq->samples 440) -10000 10000))
(seconds->samples 3))
section
A section contains a list of notes represented with Midi values, their durations expressed in milliseconds, and their start time relative to the beginning of the section.
A section can contain one or more notes. It could be a note, phrase, section, voice, movement, composition, etc.
section->csound
A section can be translated to a Csound csd file using the menu item Tools>Section->Csound.
The orchestra definition selected in the Csound File Options is used.
The Midi channel of the section determines the instrument number.
The start times and durations of the section are used as the start times (P2) and durations (p3) for the file.
The velocity value is translated to a amp value related to the Max Amp specified in the dialog. Pitch is translated to frequency. The default is that P4 is amplitude and P5 is frequency. There is a popup menu item to switch those values.
Looking at the Section->Csound dialog:
SECTION is the name of the section to be translated.
HEADER has the same function as in a Csound Score object.
MAX AMP is used to scale the velocity values of the section to amplitude values in the range 0 to MAX AMP.
BASE is the desired frequency value for a4. This value is used to convert pitch to frequency.
P6-P10 and EXTRA have the same function as in a Csound Score object.
When the specification is applied, a new csd file is made. No object is made since this is seen as a facility to translate data from an AC Toolbox object (a section) to a CSD file.
The resulting file will be rendered as specified in the Csound File Options.
section->kyma
has been removed. Select Capybara as the Midi destination and play sections in real-time through the Flame interface. Check the index item 'Midi output using a Capybara' for a description of this process.
section->osc file
Sections can be translated to data for a binary OSC File using the dialog provided by the menu item Tools>Section->OSC File.
SECTION is the name of the section to translated.
SYNTHDEF is the name of the synthdef which should be in SuperCollider's default directory called synthdefs.
INCLUDE could contain any additional OSC messages that need to be sent (such as for filling a buffer). The bundle tool is used for this.
AMP NAME is the name of the amplitude parameter used in the synthdef. Amplitude values will be converted to values between 0 and Max Amp. Note that Max Amp is per voice and is the number that is mapped to Midi velocity 127..
FREQ NAME is the name of the frequency parameter used in the synthdef. Midi note numbers from the section will be converted to frequencies where Base is the frequency value for note number 69.
DUR NAME is the name of the duration parameter used in the synthdef. All synthdefs used in this dialog need a duration parameter.
EXTRA allows extra pairs of argument names and argument values to be specified. Any number of additional pairs can be specified. An example of such data is:
attack .1 decay (random-value .3 .5)
The OSC file options (Other>OSC File Options) control the way the OSC file is named and rendered. If Render OSC File to Audio is checked, the binary OSC file will be rendered to an audio file of the specified type.
The Midi channel of the section is ignored.
INSIDE-OSC cannot be used for the specification of parameter values when a section is translated to an OSC file.
(select-channel channel)
Produces a filter that will only return events from one or more specified channels. CHANNEL can be a number or a list.
Example 1 defines a section that alternates its notes among 3 channels. Example 2 will plot that section.
Example 3 filters out all information except that from channel 2. Example 4 will plot the result.
Example 5 passes the information in channels 1 and 3. Example 6 plots that section.
This filter assumes WHATEVER was selected as the parameter to be filtered.
This filter differs from selecting CHANNEL as the parameter in the Filter dialog since that is limited to filtering pitches. SELECT-CHANNEL will filter any events in a given channel or channels. A second difference is that SELECT-CHANNEL is a convenient way to filter several channels that are not within some bandwidth (example 5).
The filter REJECT-CHANNEL is also available.
EXAMPLE 1: (fill-template data-section ds1 100 20
(rv 1.0 3) (rv 48 72) f '(1 2 3))
EXAMPLE 2: (plot ds1)
EXAMPLE 3: (fill-template filter ds1-filtered1 ds1
(other (select-channel 2))
'whatever t)
EXAMPLE 4: (plot ds1-filtered1)
EXAMPLE 5: (fill-template filter ds1-filtered2 ds1
(other (select-channel '(1 3)))
'whatever t)
EXAMPLE 6: (plot ds1-filtered2)
(select-generator generator &optional repetitions)
Returns a closure. When applied, a selection is made from the available generators. That choice is then applied to produce a value. Each time the closure is applied, a new selection of a generator is made.
SELECT-GENERATOR allows a parameter to receive values from a a group of different generators. One generator may be used for the first choice, a second for the next choice, etc.
The input parameter GENERATOR should be a generator (usually ending in choice) that will choose from a list of available generators (example 1).
The generators that can be chosen should be included in a list (as done above) and NOT be included in a separate stockpile. This could cause problems when saving and loading an environment.
The optional parameter REPETITIONS controls how ofter a chosen generator is repeated before a new choice is made. It may change over time (example 2).
EXAMPLE 1: (for-example
(select-generator
(random-choice (list
(random-value 1 10)
(random-value 10 20)
(random-value 50 100)))))
EXAMPLE 2: (plot
(select-generator
(random-choice (list
(walk 40 1)
(walk 80 1)))
3))
(select-generator-by-condition value &rest condition-clauses)
Returns a closure. When applied, a value is produced with VALUE. It is compared, in succession, to the conditions expressed as CONDITION-CLAUSES using CURRENT. If a condition is met, the generator contained in the successful clause is applied and the result is returned.
Instead of a generator, the last part of an CURRENT expression could also be a constant, list, stockpile, etc. In that case, the next value (from the list, etc.) is returned.
The last part of an CURRENT expression could be the symbol 'this-element. In that case, the element produced by VALUE is returned.
At least one CURRENT expression must be used. Any number of them can be present. Once a successful condition is found, no other conditions are examined.
VALUE can change over time and therefore can be a generator, stockpile, etc.
CURRENT expressions have three possible forms:
(current function argument generator-or-thing)
(current function generator-or-thing)
(current generator-or-thing)
Example 1 uses the first form.
VALUE comes from the list '(1 2 3 4). The first time 1 is chosen, then 2, etc. The first current expression checks if VALUE is equal to the number 1. If this is the case, the generator (random-value 1 10) is applied. If this is not the case, VALUE is compared to the number 2. If true, the generator (random-value 20 40) is applied. Otherwise if VALUE is greater than 2, the generator (random-value 100 200) is applied. If none of the above conditions are met, the result is nil.
Example 2 using the second form of CURRENT.
EVENP is a Lisp function which is true if the number being checked is even. ODDP is a Lisp function to check if a number is odd. In this case, the number being checked is VALUE, therefore no other argument is needed. This form of CURRENT has only two items: the function for the comparison and the generator. In the above example, if VALUE is an even number, the generator (random-value 1 10) will be applied. If VALUE is an odd number, the generator (random-value 50 100) is applied.
The third form of CURRENT is used to ensure that something will be done if none of the previous conditions were met. Since the generator will always be applied, there is no need to include a condition with this form of current (example 3).
If VALUE is 1, the generator (random-value 1 10) is applied.
If VALUE is 2, then generator (random-value 20 40) is applied.
In all other cases, the generator (random-value 100 200) is applied.
In addition to generators, the last part of an CURRENT expression may be a list, stockpile, etc. or the symbol 'this-element. A list, etc. will return the next value. The symbol 'this-element will return the current VALUE (example 4).
Any Lisp function producing a value which is true or not may be used for the function in CURRENT. (In Lisp, nil is not true, any other value is true.)
Some obvious possibilities for functions are: =, <, >, <=, >=, /=, evenp, oddp. These functions can only be used with numbers. The function names are preceded by a function quote: #'.
VALUE is not limited to numbers. For instance, if a generator should be chosen based on a symbol, the function could be EQUAL (example 5).
Users familiar with Lisp syntax could also use a lambda expression for the function in CURRENT (example 6).
The lambda expression is true if VALUE is even and larger than 2. In that case, the generator (random-value 100 200) would be applied. Otherwise, the generator (random-value 1 10) is applied.
This generator can be used to establish a relationship between parameters. A stockpile of values used for one parameter could be the input used to determine generators for another parameter (examples 7-8). In example 8, lower pitches have larger rhythmic values.
See ACT-IF for an alternative to this generator (example 9).
EXAMPLE 1: (for-example
(select-generator-by-condition '(1 2 3 4)
(current #'= 1 (random-value 1 10))
(current #'= 2 (random-value 20 40))
(current #'> 2 (random-value 100 200))))
EXAMPLE 2: (for-example
(select-generator-by-condition '(1 2 3 4)
(current #'evenp (random-value 1 10))
(current #'oddp (random-value 50 100))))
EXAMPLE 3: (for-example
(select-generator-by-condition '(1 2 3 4)
(current #'= 1 (random-value 1 10))
(current #'= 2 (random-value 20 40))
(current (random-value 100 200))))
EXAMPLE 4: (for-example
(select-generator-by-condition '(1 2 3 4)
(current #'<= 2 '(10 20 30 40))
(current 'this-element)))
EXAMPLE 5: (for-example
(select-generator-by-condition (random-choice '(sax1 flute))
(current #'equal 'sax1 (random-value 1 10))
(current #'equal 'flute (random-value 100 200))))
EXAMPLE 6: (for-example
(select-generator-by-condition '(1 2 3 4 5 6)
(current #'(lambda (x)
(and (evenp x) (> x 2)))
(random-value 100 200))
(current (random-value 1 10))))
EXAMPLE 7: (fill-template generate-stockpile pitches 100
(random-value 40 80))
EXAMPLE 8: (fill-template data-section ds1 100 100
(select-generator-by-condition pitches
(current #'< 60 (random-value 2.0 4))
(current (random-value 1.0 2)))
pitches
(random-value mf ff) 1 0)
EXAMPLE 9: (show-help 'act-if)
(select-generator-by-number number &rest generators)
Returns a closure. When applied, a number is produced that is used to select a generator. Number 1 refers to the first generator, 2 to the second, etc. The selected generator is then applied to return a value.
As many generators as desired can be specified. They are not joined in a list or stockpile.
Instead of a generator, a constant, list, stockpile, etc. could be used.
NUMBER can be a list, stockpile, generator, etc. Its value should be <= the number of generators available.
Example 1 uses list of numbers to choose the generator.
Example 2 uses a generator to choose from the available generators.
A shape could be used to determine the numbers (example 3).
A list and a constant can be used instead of a generator (example 4).
This generator can be used to establish a relationship between parameters. A stockpile of values used for one parameter could be the input used to determine generators for another parameter.
EXAMPLE 1: (for-example
(select-generator-by-number
'(1 2)
(random-value 1 10)
(random-value 100 200)))
EXAMPLE 2: (for-example
(select-generator-by-number
(random-value 1 2)
(random-value 1 10)
(random-value 100 200)))
EXAMPLE 3: (for-example
(select-generator-by-number
(convert line-shape 20 1 4)
(random-value 1 10)
(random-value 100 200)
(random-value 300 400)
(random-value 500 600)))
EXAMPLE 4: (for-example
(select-generator-by-number
'(1 2)
'(1 2 3 4)
50))
(select-patterns selector &optional choice)
Returns a closure. When applied, a value from one of the patterns is returned. Subsequently, the next value from the same pattern is returned. This continues until all values from one pattern have been returned. Then a new pattern is chosen and its values returned one at a time. A pattern is a stockpile or a list.
This generator could be useful when choosing among rhythmic or melodic patterns.
If SELECTOR is a generator which chooses between 2 or more stockpiles or lists, a pattern (list or stockpile) is chosen each time one is needed (examples 1-2).
If SELECTOR is a list of stockpiles or lists, the values are returned from them in their order in the list (example 3).
Examples 4-6 involve using stockpiles.
If CHOICE is bound to a generator, that generator will be used to determine the order of the elements when they are returned from the chosen pattern. In example 7, a random choice is made between the two available lists. The order of the elements for each chosen list is determined by series-choice. Each time a list is chosen, a new order is calculated for the elements. Note the use of a function quote (#') before the generator name for CHOICE.
If CHOICE is bound to a generator, not all values in a pattern may be returned. This depends on the generator which is used. RANDOM-CHOICE may repeat values and not choose some others. In any case, as many values as are in the pattern will be returned.
The generator chosen for CHOICE should expect a list or stockpile as input. This is the case with all of the generators which have -choice as their suffix, such as random-choice, beta-choice, exponential-choice, etc.
If a choice generator requires more parameter values than just the list or stockpile, the CHOICE generator should be structured as a lambda expression (with one input: the list or stockpile) and a call to the generator with the extra parameters (example 8).
EXAMPLE 1: (for-example
(select-patterns (random-choice '((1 2 3) (10 20)))))
EXAMPLE 2: (plot
(select-patterns
(random-choice '((1 2 3) (10 20) (40 41 45)))))
EXAMPLE 3: (plot
(select-patterns '((1 2 3) (10 20))))
EXAMPLE 4: (fill-template specify-stockpile stock1 1 2 3)
EXAMPLE 5: (fill-template specify-stockpile stock2 5 7 10 13)
EXAMPLE 6: (plot
(select-patterns (random-choice '(stock1 stock2))))
EXAMPLE 7: (for-example
(select-patterns (random-choice '((1 2 3) (10 20)))
#'series-choice))
EXAMPLE 8: (for-example
(select-patterns (random-choice '((1 2 3 4 5)
(10 20 30 40 50 60)))
#'(lambda (x) (beta-choice x .3 .3))))
(select-stockpiles counter function choice &rest args)
This generator returns a closure that chooses values from a list or stockpile. Unique with this generator, is that the stockpile being using can be changed while the generator is executing.
COUNTER is the number of values before a new stockpile is chosen. It can be a constant, list, stockpile, generator, etc.
FUNCTION is a function that can choose values from a stockpile. Typically this will be a choice function such as random-choice, beta-choice, etc.
CHOICE is an expression that determines which stockpile will be used as input for FUNCTION. Typically it will be a choice function choosing from a list of possible stockpiles.
ARGS are whatever arguments that might be needed by FUNCTION in addition to the stockpile.
Examples 1-2 define two stockpiles.
Example 3 will use BETA-CHOICE to select values from one of these stockpiles. After 5 values have been chosen, a new choice for stockpile is made. In this example, SERIES-CHOICE is used to pick the stockpile. The two stockpiles will alternate.
In example 4, COUNTER is bound to a generator. Also two lists are added to the possible choices.
If FUNCTION is e.g. RANDOM-CHOICE, no addition arguments are needed at the end of the expression (example 5). Instead of a generator for CHOICE, a list of lists is used in this example. SELECT-STOCKPILES will loop through these lists each time a new stockpile is needed.
SELECT-PATTERNS is another generator that returns values from stockpiles that are chosen while the generator is working. In its basic form, it will return all values in the stockpile and then choose the next stockpile. It can also use a generator to pick from the chosen stockpile. The number of values taken from a stockpile is always the length of the stockpile. See the help for SELECT-PATTERNS for more information.
EXAMPLE 1: (fill-template construct-stockpile stock1
(from 1 20))
EXAMPLE 2: (fill-template construct-stockpile stock2
(from 100 200 :step 10))
EXAMPLE 3: (for-example
(select-stockpiles 5 beta-choice
(sc (list stock1 stock2) :check t) .3 .3))
EXAMPLE 4: (for-example
(select-stockpiles (rv 5 10) beta-choice
(sc (list stock1 stock2 '(500 600 700) '(1000 2000)) :check t) .3 .3)
:number 40)
EXAMPLE 5: (plot
(select-stockpiles (rv 5 10) random-choice
'((10 20 30) (100 200 300 400 500 600) (1000 1500 2000 2500))))
selecting objects with generators
In addition to selecting values, generators can be use to select objects. A generator could be used to determine which stockpile or which mask should be used.
First, two masks should be defined (examples 1-2).
A choice can be made between these two masks with the generator RANDOM-CHOICE and the tool TAKE-ONE. TAKE-ONE returns one value from a generator, stockpile, or controller.
When TAKE-ONE returns a value from a generator, that generator is evaluated and applied to produce a value (example 3).
This can be used to determine pitch in a section (examples 4-5).
If the same mask should be used for both pitch and velocity, it must be chosen somewhere else and accessed by those two parameters. The choice could be made in a stockpile with only 1 value (namely the choice of mask). The pitch and velocity parameters could take one value from that stockpile (which would be the name of the chosen mask) and use it to calculate pitches and velocities (examples 6-8).
Note that in ds2, velocity uses the same mask but reverses low and high. Low values chosen in the mask are converted to high values.
To see the pitch and velocity results, they could be plotted using the 'Tools>Plot>Section' menu item.
Each time the section is made, the same mask is used for both pitch and velocity. If a new choice of mask is desired, the stockpile should be made again.
The process of remaking both the stockpile and the section can be automated with a scheme. A scheme will remake a number of objects in the order specified (example 9).
A disadvantage of making a choice using take-one and a generator, is that the generator is made each time take-one is applied. That means that the generator does not remember what it did previously since it is in fact new. For a random choice this does not really matter. But for a generator which needs to remember, such as SERIES-CHOICE this could be a problem. The choice would not give the expected consistency.
To demonstrate this, the combination of stockpile, section, and scheme will be repeated. This time, the stockpile will use series-choice instead of random-choice (examples 10-12).
Although series-choice should not repeat a value until all have been chosen, if the scheme is applied (creating a new choice) and the results displayed, the same mask will sometimes have been repeated. The reason is that the generator series-choice does not remember since it is made again each time take-one is applied.
To solve this problem, a controller can be used. A controller is an object that remembers. It gets made once. Each time a value is taken from a controller (using take-one) the next value of the generator is produced. A controller exists outside the limits of a section definition or any other dialog (examples 13-14).
If the take-one expression (example 14) is evaluated several times, the mask will alternately be chosen (and their representation printed in the Result window).
This controller can be referenced in a stockpile using take-one. Each time the stockpile is made, the next value from the controller will be returned (examples 15-17).
Now, each time the scheme is applied, a new section will be made using mask1 and mask2 in alternation.
Note that the controller is not remade in the scheme, since the idea is that a controller should remember what it is doing.
The above example using a controller could be reformulated using the combination of TAKE-ONE to produce the next value and GET-MOST-RECENT to read that value again. GET-MOST-RECENT reads the most recent value produced by a controller. This combination assumes that the order in which parameters are calculated is known (example 18).
Using generators to select objects is a useful technique to express relationships between parameters. Rhythmic values could be dependent on pitch choices, etc. Generators such as LOOKUP, SELECT-GENERATOR-BY-CONDITION, and ACT-IF provide mechanisms whereby a stockpile of values from one parameter could guide choices for another one. These generators could be consulted for examples.
Using generators to select objects is also very powerful when generating Csound scores. The above techniques of using take-one with generators, stockpiles, and controllers can be applied to the generation of Csound scores in a similar way to the description using sections. Which one of these techniques is most appropriate depends on the context, e.g. whether objects should be chosen per layer or per score. If a mask is chosen per score and used in several layers, it would probably be convenient to choose the mask with a controller, read that controller in a stockpile and access that stockpile in each layer. Per score, the stockpile could be remade (examples 19-20).
No instrument is available to render these scores. The resulting score can however be plotted using the 'Tools>Plot>Csound File' menu item. Score1 contains 5 layers, all using the same mask. Score2 applies the definition in Score1 four times. Each time a new mask is chosen by remaking the stockpile mchoice3.
EXAMPLE 1: (fill-template specify-mask mask1 '(100 20 5) '(1 1))
EXAMPLE 2: (fill-template specify-mask mask2 '(100 1) '(1 100))
EXAMPLE 3: (plot
(convert (take-one (random-choice '(mask1 mask2)))
100 40 80))
EXAMPLE 4: (fill-template data-section ds1 100 100 1
(convert (take-one (random-choice '(mask1 mask2)))
100 40 80)
mf 1)
EXAMPLE 5: (plot ds1)
EXAMPLE 6: (fill-template generate-stockpile mchoice1 1
(random-choice '(mask1 mask2)))
EXAMPLE 7: (fill-template data-section ds2 100 100 1
(convert (take-one mchoice1) 100 40 80)
(convert (take-one mchoice1) 100 100 40) 1)
EXAMPLE 8: (plot ds2)
EXAMPLE 9: (fill-template make-scheme scheme1 mchoice1 ds2)
EXAMPLE 10: (fill-template generate-stockpile mchoice2 1
(series-choice '(mask1 mask2) :check t))
EXAMPLE 11: (fill-template
data-section ds3 100 100 1
(convert (take-one mchoice2) 100 40 80)
(convert (take-one mchoice2) 100 100 40) 1)
EXAMPLE 12: (fill-template make-scheme scheme1 mchoice2 ds3)
EXAMPLE 13: (fill-template make-controller con1
(series-choice '(mask1 mask2) :check t))
EXAMPLE 14: (print-result (take-one con1))
EXAMPLE 15: (fill-template generate-stockpile mchoice3 1
(take-one con1))
EXAMPLE 16: (fill-template
data-section ds4 100 100 1
(convert (take-one mchoice3) 100 40 80)
(convert (take-one mchoice3) 100 100 40) 1)
EXAMPLE 17: (fill-template make-scheme scheme1 mchoice3 ds4)
EXAMPLE 18: (fill-template data-section ds5 100 100 1
(convert (take-one con1) 100 40 80)
(convert (get-most-recent con1) 100 100 40) 1)
EXAMPLE 19: (fill-template csound-score-object score1
"" nil
'(mchoice3) 5 100 1 0 1
(convert (take-one mchoice3)
100 1 100))
EXAMPLE 20: (fill-template sequential-score-object score2
score1 20 score1 20 score1
20 score1)
sequential section
A section made by combining two or more sections,communities, or midi objects in sequence, i.e. one after another.
(series-choice stockpile &key check)
Returns a closure. When applied, one element of the stockpile or list is returned at random. No element is repeated until all elements of the sequence have been returned once. At that moment, the process starts again (examples 1-2).
CHECK can be bound to t to force a repetition check to occur. In that case no repetition occurs between the last value chosen from one stockpile and the first value chosen from the replenished stockpile (example 3).
If a repetition check is used, the user should make sure that the stockpile from which the selections are made does not contain any repetitions. This could lead to an endless loop since the generator would keep trying to find a different value but none is available.
SERIES-CHOICE can be abbreviated as SC (example 4).
EXAMPLE 1: (for-example
(series-choice '(a b c d e f g h i j k l))
:number 12)
EXAMPLE 2: (for-example
(series-choice '(a b c d e f g h i j k l))
:number 24)
EXAMPLE 3: (for-example
(series-choice '(1 2 3 4 5) :check t))
EXAMPLE 4: (for-example
(sc '(1 2 3 4 5)))
(series-value low high &key step)
Returns a closure. When applied, one element from the set of all values between LOW and HIGH is returned at random. No element of that set is repeated until all elements have been returned once (example 1). At that moment, the process starts again (example 2).
STEP is the distance between values in the set. The first value is LOW. The next value is LOW + STEP (example 3). The default value for STEP is 1. STEP can also be a real number (example 4).
The type of the result is determined by LOW, HIGH, and STEP. If one or more of these parameters is a real number, the result is a real number.
A repetition check occurs so that no repetition occurs between the last value chosen from one set and the first value chosen from the replenished set. In example 5, the last of the series of 5 values will never be the same as the first value in the next series. If LOW and HIGH are equal, there is no repetition check.
LOW, HIGH, and STEP can change over time. The new values for LOW, HIGH, and STEP are only used after all elements of the previous set have been used once. In example 6, SERIES-VALUE will return 5 values between 1 and 5, and then 5 values between 2 and 6, and then 5 between 1 and 5, etc.
In example 7, 5 values will be produced between 1 and 5 with a step size of 1. Then a new set of values will be made between 1 and 5 with a step size of .5. When those 9 values have all been chosen once, a set is made between 1 and 5 with a step size of 1, etc.
In example 8, an ascending line of values if made for LOW. When LINE reaches its last value, it starts again from the beginning.
In earlier versions of the AC Toolbox, if either LOW or HIGH had an expression that was not a number, it was only used once to make an initial value. This behavior is now changed to allow for time-varying parameters. If the old behavior is desired, enclose the generator in a MAKE expression (example 9).
SRV can be used as a shortcut for SERIES-VALUE (example 10). SV is the shortcut for SIEVE and should not be confused with SERIES-VALUE.
EXAMPLE 1: (for-example (series-value 0 11) :number 12)
EXAMPLE 2: (for-example (series-value 60 64))
EXAMPLE 3: (for-example (series-value 60 72 :step 2))
EXAMPLE 4: (for-example (series-value 60 67 :step 0.5))
EXAMPLE 5: (for-example (series-value 1 5))
EXAMPLE 6: (for-example (series-value '(1 2) '(5 6)))
EXAMPLE 7: (for-example (series-value 1 5 :step '(1 .5)))
EXAMPLE 8: (for-example
(series-value (line 20 1 5) 5)
:number 100)
EXAMPLE 9: (for-example
(series-value (make (rv 1 5)) 10))
EXAMPLE 10: (for-example (srv 1 5))
(sf filename)
This tool is a shortcut for SF-NAME.
It adjusts a soundfile name to be in the appropriate format for use in a Csound score file. FILENAME should be a string (example 1).
In Example 1, replace "sax1" with the name of file available in your chosen soundfile directory. This Csound object assumes the sample file is at least 3 seconds long. This score can be rendered using 'test csound.orc' in 'Support/FileExamples'.
A soundfile name could, for example, be the input to the csound unit generator soundin. It could also be the name of an analysis file.
To make a choice between various soundfiles in the score, see the help for the generator GENERATE-SF-NAME.
If the file is a sample file, it should be in the sample directory specified in the Csound File Options. If it is an analysis file, it should be in the analysis directory.
See the documentation for SF-NAME for more information (example 2).
EXAMPLE 1: (fill-template csound-score-object score1
"" nil nil 1 10 3 0
(random-value 0.5 1)
(sf "sax1") (rv 0.0 2) 1
0.1 0.1)
EXAMPLE 2: (show-help 'sf-name)
(sf-name filename)
Adjusts a soundfile name to be in the appropriate format for use in a csound score file. FILENAME should be a string (example 1).
In Example 1, replace "sax1" with the name of file available in your chosen soundfile directory. This Csound object assumes the sample file is at least 3 seconds long. This score can be rendered using 'test csound.orc' in 'Support/FileExamples'.
A soundfile name could, for example, be the input to the csound unit generator soundin. It could also be the name of an analysis file.
To make a choice between various soundfiles in the score, see the help for the generator GENERATE-SF-NAME.
If the file is a sample file, it should be in the sample directory specified in the Csound File Options. If it is an analysis file, it should be in the analysis directory.
The shortcut for SF-NAME is SF.
EXAMPLE 1: (fill-template csound-score-object score1
"" nil nil 1 10 3 0
(random-value 0.5 1)
(sf-name "sax1") (rv 0.0 2) 1
0.1 0.1)
(shake thing deviation &key percent conversion round)
Returns a closure. When applied, a value produced by DEVIATION is added to THING.
THING and DEVIATION can change over time and be generators, constants, lists, stockpiles, etc.
A random value between -10 and +10 is added to 1000 each time the generator in examples 1-2 is applied.
THING can also be a list, generator,etc. (examples 3-4).
If the value produced by DEVIATION should be considered a percentage of the value produced by THING, bind the keyword PERCENT to T (examples 5-6).
If the values for THING and the values produced by DEVIATION are integers, the result of SHAKE will probably be an integer. If one or more of these values are real numbers, the result will be a real number. This is the same as with most AC Toolbox generators (example 7). Note that this example adds a value in the range 0-10. There is no need for DEVIATION to be centered on the value of THING.
To quantize the result with another unit, bind ROUND to a quantization unit (example 8). This example also demonstrates that any generator can be used for DEVIATION.
The output of SHAKE can be converted to a particular data type by bind the appropriate Lisp function to the keyword CONVERSION (example 9).
If both ROUND and CONVERSION are bound to values other than nil, ROUND takes precedence.
SHAKE could be used, for example, as a way to produced layered cloud textures in a Csound or OSC file. Each layer could have THING equal to a different frequency value (examples 10-11).
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
Shake can be used in an OSC score as well (example 12).
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
Granular textures would require the duration specification to be shorter.
JITTER is a generator similar to SHAKE except that deviation always refers to a range of evenly distributed random numbers. A feature of JITTER is that if a symmetrical random deviation around a center frequency is desired, the syntax is more concise. Also it is perhaps easier to express changes in the size of the deviation (examples 13-14).
An advantage of SHAKE is that any generator can be used for DEVIATION and the deviation does not have to be centered around THING (example 15).
EXAMPLE 1: (for-example (shake 1000 (random-value -10 10)))
EXAMPLE 2: (plot (shake 1000 (random-value -10 10)) :min 900 :max 1100)
EXAMPLE 3: (for-example (shake '(100 200 300)
(random-value -10 10)))
EXAMPLE 4: (plot (shake (line 100 100.0 200)
(random-value -10 10)))
EXAMPLE 5: (for-example (shake 1000 (random-value -10 10)
:percent t))
EXAMPLE 6: (plot (shake (line 100 100.0 200)
(random-value -10 10) :percent t))
EXAMPLE 7: (for-example (shake 1000 (random-value 0 10.0)))
EXAMPLE 8: (for-example (shake 1000 (beta-value -10 10.0 .2 .2) :round 0.25))
EXAMPLE 9: (for-example (shake 1000 (random-value -10 10.0)
:conversion #'truncate))
EXAMPLE 10: (fill-template
make-controller controller1
(make-controller (walk 100.0 (random-value 500.0 1000)
100 10000)))
EXAMPLE 11: (fill-template csound-score-object score1
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil '(controller1) 10 200 1
(make&sort 200 (random-value 0.0 10))
(random-value 1.0 3) (scale-by-layers (random-value 0.01 0.05))
(shake (take-one controller1) (random-value -1.0 1) :percent t))
EXAMPLE 12: (fill-template osc-score-object osc-score1
200 "sine1" nil nil nil 10 (make&sort 200 (random-value 0.0 10))
"dur" (random-value 1.0 3)
"amp" (scale-by-layers (random-value 0.01 0.06))
"freq" (shake (take-one controller1) (random-value -1.0 1) :percent t))
EXAMPLE 13: (for-example (jitter 500 10.0))
EXAMPLE 14: (plot (jitter 500 (line 100 20.0 2) :percent t))
EXAMPLE 15: (plot (shake 500 (beta-value 0.0 20 .2 .2)))
shape
A shape is a curve, reflecting some motion over time. The tool CONVERT can be used to convert a shape to useable parameter values.
(shortcut symbol function)
Functions can be renamed, perhaps to some shorter letter combination. This allows the user to define shortcuts for frequently used generators, tools, and transformers.
SYMBOL should be a symbol that is not already bound to a function. If SYMBOL is already bound, an error message will occur and another symbol for the shortcut should be chosen.
FUNCTION is the name of a function with a function quote. If the function quote is omitted or the argument is not a function, an error message occurs (examples 1-2).
In the above example, the shortcut sc is defined for the generator series-choice. Both names can be used for series-choice.
The defined shortcuts only remain valid doing a session with the AC Toolbox. For repeated use, the shortcuts should be saved in a file and read in during the initialization of the AC Toolbox. Use File > Choose Init File to indicate that the file with shortcuts should be read in each time the AC Toolbox is loaded.
Shortcuts cannot be made for generators and tools that were realized as macros. This means that in any case, cal, on-the-fly, otf, and act-if cannot be given a shortcut.
EXAMPLE 1: (shortcut 'sc #'series-choice)
EXAMPLE 2: (for-example (sc '(1 2 3 4 5 6 7 8 9 10)))
(shotgun percentage)
This tool is intended to be used as a filter with e.g. FILTER-STOCKPILE though it can also be used with WITH, WITHOUT, FILTER-AND, FILTER-IF, FILTER-OR, etc.
It randomly removes a percentage of the values (example 1).
PERCENTAGE can change over time.
EXAMPLE 1: (for-example
(filter-stockpile (from 1 20) (shotgun 60)))
(shove to-produce-index to-produce-value)
Returns a closure that can transform a section by shoving values aside to create rests. The two inputs are generators, lists, constants, or stockpiles that can be used to produce the next appropriate value.
To shove aside values, this transformer should be used in the ATTACKS box.
TO-PRODUCE-INDEX should produce valid index numbers for the events in an object (1,2,...). Index values start with 1.
Example 1 is a section to be transformed.
Example 2 will shove aside notes to add rests without discarding any note value. The length of the rest that is added is expressed in milliseconds.
Rests occur after the notes 3, 6, and 10. The attack times for notes 4, 7, and 11 have a random value between 100 and 200 milliseconds added. This creates a rest between the end of the previous note and the start of the current one.
If TO-PRODUCE-INDEX is a list, the values are sorted in ascending order and duplicates are removed.
To produce rests at random locations in a section, the generator WALK could be used to produce the index values (example 3)
The first attack time to be changed is after note 3. After that, the next index to be changed is from 1 to 7 indices further.
When a generator is used to produce the indices, they should be in ascending order.
PRODUCE could also be used to generate a list of indices. SHOVE will remove duplicates and sort them in ascending order (example 4). In this example, series-value is used to avoid duplicates.
Transformer INSERT-REST does something similar to this transformer but it refers to time values instead of indices.
EXAMPLE 1: (fill-template data-section section1
100 24 1 (chromatic c3) mf 1)
EXAMPLE 2: (fill-template transform trans1 section1
:attacks (shove '(3 6 10) (rv 100 200)))
EXAMPLE 3: (fill-template transform trans2 section1
:attacks
(shove (walk 3 (random-value 1 7))
(random-value 100 200)))
EXAMPLE 4: (fill-template transform trans3 section1
:attacks
(shove (produce 4 (series-value 5 20))
(random-value 500 1000)))
(show number function &key title view-size number-per-line scratch)
Prints the results of a NUMBER of applications of a FUNCTION in a window (example 1). Keywords can be used to change the title of the window (example 2), the size of the window (example 3), and the number of values printed on one line (example 4). The keyword scratch can be used to avoid a prompt when closing the window. To designate the window as a scratch window, bind the keyword scratch to t (example 5). The title should be a string. The view-size is a list with x and y values.
NUMBER-PER-LINE can vary over time, i.e. it can be a constant, stockpile, generator, etc (example 6).
SHOW can be evaluated in a Lisp Editor (File > New) or in a Listener (Other > Listener).
EXAMPLE 1: (show 50 (random-value 1 100))
EXAMPLE 2: (show 20 (random-choice '(mary had a little lamb))
:title "My First Poem")
EXAMPLE 3: (show 100 (random-value 50 100) :view-size '(500 300))
EXAMPLE 4: (show 50 (random-value 1 100) :number-per-line 5)
EXAMPLE 5: (show 50 (random-value 1 100) :scratch t)
EXAMPLE 6: (show 20 (random-choice '(do i dare to eat a peach))
:number-per-line (random-value 1 4))
(show-help symbol)
This tool will show the available help information for SYMBOL.
The primary use is in help windows to allow for an easy link to another help item. For example, when one generator might refer to another (example 1).
This is an alternative to using the menu item Help>Lookup Selection.
EXAMPLE 1: (show-help 'random-value)
(show-info name)
Provides information about a section, midi object, community, or stockpile in a window. The information includes the total number of events and the total duration of the object (if relevant).
If section s1 exists, example 1 will provide information about it.
Subsequent definitions of the same type of object will update the information in the window (if the window is still open).
This tool only works with sections, midi objects, communities, and stockpiles. It offers the same functionality as the Info button in the Objects dialog.
EXAMPLE 1: (show-info s1)
(show-midi->hz &key base)
Creates a window showing the Midi note numbers from 0 to 127 and their corresponding value in Hz.
The default value for BASE is 440 Hz for A4 (or a3 depending on the choice made in preferences) (example 1).
To use a different reference frequency base for calculating frequency values, bind keyword BASE to a different frequency value for A4 (example 2).
This tool can be evaluated in a listener (Other>Listener), in the For Example dialog, or in an editor window (File>Text>New).
EXAMPLE 1: (show-midi->hz)
EXAMPLE 2: (show-midi->hz :base 442)
(show-text object)
Prints a text version of the values of some objects. In any case, sections, midi objects, and stockpiles can be printed with this tool.
To make a text version of section1, see example 1.
Example 1: (show-text section1)
(show-transformation transformer list-or-stockpile &key recycle)
Prints the results of applying the TRANSFORMER to each number in the LIST-OR-STOCKPILE. Results are printed in the Listener or to a window.
This tool can be used to show the result of a transformation on a number. Its principle application is in help windows for transformers (example 1).
If the RECYCLE keyword is bound to t, the example data is written to the previous example or show-transformation window (after erasing the previous data). This helps cut down on screen clutter. If the value is nil, a new window is made each time example data is requested (example 2).
The default value for RECYCLE is specified in the Preferences dialog. It uses the value for for-example.
EXAMPLE 1: (show-transformation (transpose 12) '(60 64 66))
EXAMPLE 2: (show-transformation (transpose 12) '(60 64 67) :recycle nil)
(shuffle stockpile &optional size)
Returns a closure. When applied, one value from a reordered version of STOCKPILE is returned.
The stockpile can be treated as one group or divided into several smaller groups. Values are shuffled within the limits of a group.
When all values from the shuffled stockpile (or list or almost any other AC Toolbox object) have been returned, the stockpile is shuffled again.
If there is no value for SIZE, this generator is similar to SERIES-CHOICE but without the key word CHECK (example 1).
If a value is bound to SIZE, the stockpile is segmented into groups with the specified length(s). The values within each group are put in a random order. The shuffled values from the first group are returned, one at a time, then the shuffled values from the second group, etc.
If a stockpile has 10 values:
1 2 3 4 5 6 7 8 9 10
and it is divided into two groups of 3 and one group of 4:
(1 2 3) (4 5 6) (7 8 9 10)
and then shuffled, the result could be:
3 1 2 4 6 5 8 9 7 10
Example 2 demonstrates this with a list of 10 values with the group sizes of 3, 3, and 4. In this example, SIZE is a list of group sizes.
If the sum of the values from SIZE is less than the length of the stockpile, a new group size is produced, e.g. by looping through the list of group sizes, until enough groups have been made (example 3). In this example, the actual groups sizes are 3,2,2,3.
If the sum of the values from SIZE is greater than the length of the stockpile, the last group size is reduced until the total of all group sizes equals the length of the stockpile (example 4). This could result in the last group being very short, perhaps even 1. In this example, the actual group sizes are 3,4,2,1.
SIZE may be a constant, list, stockpile, generator, etc. (examples 5-7).
This technique is adapted from a discussion in
Schipper, C. (2009). First Reflections on my Compositional Process.
Bachelor thesis, Institute of Sonology, The Hague.
EXAMPLE 1: (for-example
(shuffle (from 1 5)))
EXAMPLE 2: (for-example
(shuffle (from 1 10) '(3 3 4))
:number-per-line 10
:number 50)
EXAMPLE 3: (for-example
(shuffle (from 1 10) '(3 2 2))
:number-per-line 10
:number 50)
EXAMPLE 4: (for-example
(shuffle (from 1 10) '(3 4 2 6))
:number-per-line 10
:number 50)
EXAMPLE 5: (for-example
(shuffle (from 1 10) 2)
:number-per-line 10
:number 50)
EXAMPLE 6: (fill-template data-section ds1 100 100 1
(shuffle (from c3 c5) (rv 5 10))
f 1)
EXAMPLE 7: (fill-template note-section ds2 150 62
(shuffle wilhelmus 5))
(si &rest sieves)
SI is a shortcut (abbreviation) for SIEVE-INTERSECTION (example 1).
See the help for SIEVE-INTERSECTION for more information (example 2).
EXAMPLE 1: (for-example (si '(1 3 5 7) '(1 4 7)))
EXAMPLE 2: (show-help 'sieve-intersection)
(sieve mod start lower higher)
Returns a list representing a sieve segment which is a set of increasing integers. It can be used to choose and interprete rhythmic values (see the tools INTERPRET-SIEVE, SIEVE-UNION, and SIEVE-INTERSECTION). A sieve segment can filter an object such as a section by using the tool SIEVE-FILTER. A sieve segment can be considered as pitch data. A sieve segment can be used with the transformer FUNNEL to force the values being transformed to be one of the values of the sieve segment.
A sieve is expressed starting with START. A value is produced every MOD number of values. The resulting list only contains values between LOWER and HIGHER (examples 1-3).
Sieves may indicate or reflect periodicities and symmetries.
SIEVE may be abbreviated sv (example 4).
More information about sieves can be found in:
Ariza, C. (2005). "The Xenakis Sieve as Object: A New Model and a Complete Implementation." Computer Music Journal, 29(2), 40-60.
Xenakis, I. (1992). Formalized Music (revised ed.). Stuyvesant, New York: Pendragon Press.
EXAMPLE 1: (for-example (sieve 2 1 1 30))
EXAMPLE 2: (for-example (sieve 2 2 5 30))
EXAMPLE 3: (for-example (sieve 4 36 36 72))
EXAMPLE 4: (for-example (sv 2 1 1 30))
(sieve-filter sieve &key start-time)
Produces a filter that selects values according to a sieve. The sieve can be interpreted as indices or start-times.
See the help for SIEVE for an explanation of what a sieve is. In short, it is an ascending series of integers.
This filter should be used with the FILTER method or with FILTER-STOCKPILE. The primary use of this filter is to filter sections or stockpiles.
Indices start with 1, i.e. the first value in the object has the index 1, the second index 2, etc. Values with indices found in the sieve will be copied. Others will be not.
SIEVE can be a list, stockpile, or a list produced with the tool SIEVE.
To use with the FILTER method: choose OTHER as the filter type.
Example 1 produces section1.
Example 2 filters that section. One of every 5 values is chosen. More complex sieves can be specified.
SIEVE-FILTER can be used with FILTER-STOCKPILE (example 3).
Example 4 makes section2.
Example 5 combines section1 and section2 in parallel. Some of their start-times will coincide. This can be seen by choosing Edit in the Objects dialog.
Example 6 filters parallel-section my-parallel according to its indices. Some values that occur at the same time are eliminated since they do not occur at the same index position.
Example 7 filters my-parallel according to its start-times.This is specified by binding START-TIME to t. The sieve should contain the allowed start-times. All events with those start-times will pass.
EXAMPLE 1: (fill-template data-section section1 100 80 1
(chromatic 20) mf 1)
EXAMPLE 2: (fill-template filter section1f section1
(other (sieve-filter
(sieve 5 1 1 (get-length section1))))
'whatever t)
EXAMPLE 3: (for-example
(filter-stockpile '(60 61 62 64 65)
(sieve-filter '(1 3 5))))
EXAMPLE 4: (fill-template data-section section2 100
(until-time 7.9) 1.5 (walk 100 -1) mf 1)
EXAMPLE 5: (fill-template parallel-section my-parallel
section1 section2)
EXAMPLE 6: (fill-template filter my-filter1 my-parallel
(other (sieve-filter
(sieve 4 1 1 (get-length my-parallel))))
'whatever t)
EXAMPLE 7: (fill-template filter my-filter2 my-parallel
(other (sieve-filter (sieve 300 0 0 8000)
:start-time t))
'whatever t)
(sieve-intersection &rest sieves)
Returns a list. Input is two or more sieve segments (lists). The result is their intersection, sorted into ascending order. Sieves may be either lists or stockpiles (examples 1-2).
See the help for SIEVE for a bit more information.
SIEVE-INTERSECTION may be abbreviated si (example 3).
EXAMPLE 1: (print-result (sieve-intersection '(1 3 5 7) '(1 4 7)))
EXAMPLE 2: (for-example (sieve-intersection (sieve 3 1 1 20)
(sieve 4 1 1 20)))
EXAMPLE 3: (print-result (si '(1 3 5 7) '(1 4 7)))
(sieve-union &rest sieves)
Returns a list. Input is two or more sieve segments (lists). The result is their union, sorted into ascending order. Sieves may be either lists or stockpiles. (examples 1-2)
See the help for SIEVE for a bit more information.
SIEVE-UNION may be abbreviated su (example 3).
EXAMPLE 1: (print-result (sieve-union '(1 3 5 7) '(1 4 7)))
EXAMPLE 2: (for-example (sieve-union (sieve 3 1 1 20)
(sieve 3 2 2 20)))
EXAMPLE 3: (print-result (su '(1 3 5 7) '(1 4 7)))
(simplify-chords section)
Returns a list of note structures suitable for use in a note section. All notes in SECTION that have the same starting time are gathered into a chord with only one duration (the longest duration of the gathered notes). This may simplify a chordal progression within a section.
This tool is most useful when the notes of a section are to be used as input for a generator such as random-choice, beta-choice, etc., or when the notes of a section are analyzed with a tool such as derive-transition-table.
In particular, this tool may be effective if several sections have been combined in parallel in a parallel section or if a MIDI file has been imported.
If a section consists only of notes of one melodic line or of notes with unique start times, this tool will have no effect.
If section1 exists, it can be simplified with example 1.
SIMPLIFY-CHORDS could be an input to make a note structure, note section, or structured section.
EXAMPLE 1: (fill-template note-section section1a 1 100
(simplify-chords section1) 0)
(sine n low high &optional phase)
Returns a closure. When applied, it returns the next of the N values describing a sine motion between LOW and HIGH. The type of the result is determined by LOW and HIGH (examples 1-3).
N, LOW, and HIGH may vary over time (examples 4-7).
The a new value for N is only generated when the previous period of N values is finished.
PHASE is a value in degrees, presumably between 0 and 360. The default value is 0 (example 8).
EXAMPLE 1: (for-example (sine 20 0 100))
EXAMPLE 2: (for-example (sine 20 -1.0 1.0))
EXAMPLE 3: (plot (sine 100 -1.0 1.0))
EXAMPLE 4: (plot (sine 100 1 (random-value 1 100)))
EXAMPLE 5: (plot (sine '(10 25 50 100) -1.0 1) :number 184)
EXAMPLE 6: (plot (sine (rc '(10 20 30 40)) -1.0 1) :number 500)
EXAMPLE 7: (plot (sine (rc '(20 40 60 75)) 1 (rv 1 100)) :number 500)
EXAMPLE 8: (plot (sine 100 1 100 180))
(skip-rests object-with-rests new-values &key default)
Returns a closure. When applied, it will only take a value from NEW-VALUES if the value from OBJECT-WITH-RESTS is not a rest. If this is used in data sections, values from a pitch series will not be abandoned if a rest is created for rhythm.
A value from OBJECTS-WITH-RESTS is checked to see if it is a negative value (a rest). If so, the default value is returned. Otherwise a value from NEW-VALUES is returned.
OBJECT-WITH-RESTS and NEW-VALUES can be stockpiles, generators, lists, etc.
Typically, OBJECT-WITH-RESTS is defined as a stockpile. This stockpile could be used for the rhythm parameter of a data section. Pitch could use SKIP-RESTS and refer to that stockpile as the OBJECT-WITH-RESTS (examples 1-3).
Instead of defining rhythm as a stockpile, it could be a controller that will generate new rhythmic values. The advantage of this is that the controller would not have to be remade to produce new values. A second and third controller could be synced to the master rhythm controller and used for the rhythm parameter and with skip-rests (examples 4-8).
EXAMPLE 1: (fill-template generate-stockpile rhythm
20 (plus-min 1 0.3))
EXAMPLE 2: (fill-template data-section test1 100 (get-length rhythm)
rhythm (skip-rests rhythm (major c3)) mf 1)
EXAMPLE 3: (print-score test1)
EXAMPLE 4: (fill-template make-controller
master-controller (plus-min 1 0.3))
EXAMPLE 5: (fill-template make-controller rc1
(sync master-controller))
EXAMPLE 6: (fill-template make-controller rc2
(sync master-controller))
EXAMPLE 7: (fill-template data-section test2 100 20
rc1 (skip-rests rc2 (major c3)) mf 1)
EXAMPLE 8: (print-score test2)
(sl number low high &key round)
This generator is a shortcut for SLIDER-VALUE. It returns a generator.
When applied, a value is read from stream slider NUMBER and mapped to be between LOW and HIGH (example 1).
The Stream Sliders dialog is available via menu Tools>Stream Sliders.
The only use of this generator is to supply data to a stream when a stream is played.
More information can be found in the documentation for SLIDER-VALUE (example 2).
EXAMPLE 1: (fill-template make-midi-data-stream test2
(sl 1 10 500) (sl 2 1.0 3)
(rv (sl 3 40 80) (sl 4 40 80))
(sl 5 50 100) 1)
EXAMPLE 2: (show-help 'slider-value)
(slice object low-percentage high-percentage &key by-number)
SLICE returns a new object of the same type as OBJECT. It is a copy of part of an object, specified by percentages, e.g. a slice of a shape, with percentages 0 and 50, slices the first half. For a section, the percentages are related to time values, i.e. 50% of the length of section, not 50% of the number of notes.
The following objects can be sliced: stockpiles, sections, midi-objects, communities, shapes, masks, as well as lists and vectors.
It is the same operator which is available using the Menu item METHODS (example 1).
To copy part of an object by specifying the indices of the items to be copied, the keyword :BY-NUMBER should be T.
If data-section1 exists, it can be sliced with example 2.
This would produce a new section containing notes 1 through 5 of data-section1.
EXAMPLE 1: (plot (slice sine-shape 0 50))
EXAMPLE 2: (define data-section1a
(slice data-section1 1 5 :by-number t))
(slider-value number low high &key round)
Returns a closure. When applied, a number is read from one of the stream sliders (Tools>Stream Sliders) and mapped to between LOW and HIGH.
The only use for this generator is to supply data to a stream that is being played (example 1).
SL is a shortcut for SLIDER-VALUE (example 2).
To quantize the result, bind ROUND to a quantization unit (example 3).
Other possibilities for controlling a stream are EXTERNAL-VALUE and TEST-VALUE. EXTERNAL-VALUE reads from an external Midi controller. TEST-VALUE reads a number from the TEST VALUE Dialog.
EXAMPLE 1: (fill-template make-midi-data-stream test1
(slider-value 1 10 500) (slider-value 2 1.0 3)
(rv (slider-value 3 40 80) (slider-value 4 40 80))
(slider-value 5 50 100) 1)
EXAMPLE 2: (fill-template make-midi-data-stream test2
(sl 1 10 500) (sl 2 1.0 3)
(rv (sl 3 40 80) (sl 4 40 80))
(sl 5 50 100) 1)
EXAMPLE 3: (fill-template make-midi-data-stream test3
(sl 1 20 200 :round 10)
(slider-value 2 1.0 3 :round 0.25)
(rv (sl 3 40 80) (sl 4 40 80))
(slider-value 5 50 100) 1)
spear
SPEAR is an sound analysis/resynthesis program using tracks of partials. These tracks can be exported as text and read into the AC Toolbox (using READ-TRACKS-FILE) to be produce note information. The tracks can also be read with READ-SPECTRUM-FILE in which case one pitch and amplitude value per track will be returned.
To use in the AC Toolbox, track data from SPEAR should be exported as 'text - partial' data to a text file. It is important that the data is exported as text since the AC Toolbox does not read the SDIF formaat.
Select partials in the SPEAR analysis (e.g. by using shift-click) then copy those partials to a new window with File>New From Selection. Using File>Export Format, select the format to be 'text - partial'. The partials can exported to a text file and read in the AC Toolbox. Note that the text file can also be opened in SPEAR and resynthesized.
For more information about SPEAR, see example 1.
EXAMPLE 1: (open-url "http://www.klingbeil.com/spear")
specifying an object without making it
To save an object specification without making the object, hold down the COMMAND key when clicking the MAKE button (Command-Click).
The purpose of this mechanism is to allow objects to be defined in a top-down way, that is before all of their components are defined. Normally, a stockpile would have to be made before it can be used in making a section. If the section is specified, the stockpile can be made later. Once all of the components have been made or specified, they could be made, possibily by using a scheme object.
(spectrum->amp spectral-data &key low high peaks)
Returns a list of velocity values derived from SPECTRAL-DATA. This data was returned by READ-SPECTRUM-FILE. Typically the spectral data is read into a stockpile and used by this and other tools.
Example 1 can be used to read in spectral data (e.g. from the file 'test spear bassoon.txt' found in the Support/FileExamples folder).
When then stockpile in example 1 is made, a number of peaks, starting with the peak with the highest amplitude, will be read in. Example 2 returns a list of the corresponding velocity values.
To limit the number of peaks, PEAKS can be bound to the desired number (example 3).
The velocity values can be mapped to be in a different range. The default range is 30-90 (Midi values) (example 4).
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (for-example (spectrum->amp spectrum1))
EXAMPLE 3: (for-example (spectrum->amp spectrum1 :peaks 5))
EXAMPLE 4: (for-example (spectrum->amp spectrum1 :low 60 :high 100))
(spectrum->chord spectral-data number &key from name sort low high peaks)
Returns a closure. When applied, a list of pitches that could be considered a chord in a data section is returned. The pitches are taken from SPECTRAL-DATA that was read with READ-SPECTRUM-FILE. Typically the spectral data is read into a stockpile and used by this and other tools.
Example 1 can be used to read in spectral data (e.g. using the file 'test spear bassoon.txt' found in the Support/FileExamples folder). The pitch data will be rounded to semitones.
The data can be seen in various formats using spectrum->window (example 2). The choice to round to semitones was made in READ-SPECTRUM-FILE. If there are duplicate pitches in the list (that may have been caused by the rounding process), they can be removed in READ-SPECTRUM-FILE by binding the UNIQUE keyword to t. A different base frequency for a4 can also be specified in READ-SPECTRUM-FILE.
The pitch with the largest amplitude is peak 1.
NUMBER is the chord size. The first NUMBER of pitches from the spectrum are read (and repeated each time this generator is applied). Pitches are sorted according to the largest amplitude (examples 3-4).
To read different pitches from the spectrum, keyword FROM can be bound to a generator, list, etc. specifying which peak number should be read. Examples 5-6 will pick peaks using (series-value 1 11). All 11 numbers will occur once before any are repeated. Then all 11 are again available. In these examples, the 11 peaks will be spread over successive 4-note chords. Peak numbers refer to their amplitude ranking. Peak 1 has the highest amplitude.
If FROM is bound to a list, the values are taken from the list in the specified order. Each time the generator is applied, the next NUMBER of values are taken from the list (examples 7-8).
To sort the peaks in ascending (pitch) order, bind SORT to t. When peaks are sorted, the peak numbers used in FROM refer to the pitch ranking (number 1 is the lowest pitch) instead of the amplitude ranking (example 9).
To sort the peaks in descending (pitch) order, bind SORT to 'down (example 10).
To express the pitches as note names, bind the keyword NAME to t (example 11). If SPECTRAL-DATA is rounded to a unit smaller than a semitone, fractional pitch data will appear in parentheses.
To map the pitches in a chord to a different range, bind LOW and/or HIGH to a new value (examples 12-13).
When pitch data is mapped, the resulting data may contain duplicates of a pitch. One way to remove these duplicates is with the transfomer REMOVE-DOUBLES. TRANSFORM/TIME is a generator that applies a transformer to its other argument (example 14). This may change the number of pitches in a chord.
The number of peaks to be made available from the SPECTRAL-DATA can be bound to PEAKS (<= the number of peaks in SPECTRAL-DATA). If the keyword PEAKS is bound to 5, the 5 peaks with the highest amplitude are available (example 15). If those peaks are sorted, the ascending order of pitches will only contain those 5 peaks with the highest amplitude (example 16).
FROM and NUMBER can vary over time.
If NUMBER changes over time and FROM is not specified, the pitches for each chord will be taken from the beginning of the list of peaks each time (example 17).
If NUMBER varies over time and FROM is specified, the pitches for each chord will be the next group from the peaks indicated by FROM (examples 18-19).
If the number of peaks returned by READ-SPECTRUM-FILE is forgotten, use tool PEAKS? (example 20).
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file :round 1))
EXAMPLE 2: (spectrum->window spectrum1)
EXAMPLE 3: (for-example (spectrum->chord spectrum1 4)
:number-per-line 1)
EXAMPLE 4: (fill-template data-section s1 500 5 1
(spectrum->chord spectrum1 4)
mf 1)
EXAMPLE 5: (for-example (spectrum->chord spectrum1 4
:from (series-value 1 11))
:number-per-line 1)
EXAMPLE 6: (fill-template data-section s2 1000 20 1
(spectrum->chord spectrum1 4
:from (series-value 1 11))
mf 1)
EXAMPLE 7: (for-example (spectrum->chord spectrum1 4
:from '(1 10 2 9 3 8 4 7 5 6 11))
:number-per-line 1)
EXAMPLE 8: (fill-template data-section s3 1000 20 1
(spectrum->chord spectrum1 4
:from '(1 10 2 9 3 8 4 7 5 6 11))
mf 1)
EXAMPLE 9: (for-example (spectrum->chord spectrum1 11
:from (from 1 11)
:sort t)
:number 1)
EXAMPLE 10: (for-example (spectrum->chord spectrum1 11
:from (from 1 11)
:sort 'down)
:number 1)
EXAMPLE 11: (for-example (spectrum->chord spectrum1 5
:from (series-value 1 11)
:name t)
:number-per-line 1)
EXAMPLE 12: (for-example (spectrum->chord spectrum1 4
:from (series-value 1 11)
:low 40 :high 60)
:number-per-line 1)
EXAMPLE 13: (fill-template data-section s4 1000 20 1
(spectrum->chord spectrum1 4
:from (series-value 1 11)
:low 40 :high 60)
mf 1)
EXAMPLE 14: (for-example (transform/time
(spectrum->chord spectrum1 4
:from (series-value 1 11)
:low 40 :high 60)
(remove-doubles))
:number-per-line 1)
EXAMPLE 15: (for-example (spectrum->chord spectrum1 5
:peaks 5)
:number-per-line 1
:number 1)
EXAMPLE 16: (for-example (spectrum->chord spectrum1 5
:peaks 5 :sort t)
:number-per-line 1
:number 1)
EXAMPLE 17: (for-example (spectrum->chord spectrum1 (rv 1 4))
:number-per-line 1)
EXAMPLE 18: (for-example (spectrum->chord spectrum1 (rv 1 4)
:from (from 1 11))
:number-per-line 1)
EXAMPLE 19: (fill-template data-section s5 1000 20 1
(spectrum->chord spectrum1 (rv 1 4)
:from (from 1 11))
mf 1)
EXAMPLE 20: (print-result (peaks? spectrum1))
(spectrum->freq spectral-data &key sort low high peaks)
Returns a list of frequency values from SPECTRAL-DATA. Typically the spectral data is read into a stockpile and used by this and other tools.
Example 1 can be used to read in spectral data (e.g. using the file 'test spear bassoon.txt' found in the Support/FileExamples folder).
When the stockpile in example 1 is made, frequencies are sorted according to descending amplitudes. Example 2 returns a list of the frequency values with the highest amplitude values from the stockpile.
To limit the number of peaks, bind PEAKS to the desired number (example 3).
To sort the frequencies in ascending order, bind SORT to t (example 4).
To sort the frequencies in descending order, bind SORT to 'down (example 5).
To map the frequencies to a different range, specify values for the keywords LOW and/or HIGH (example 6).
If READ-SPECTRUM-FILE rounded the data and if the file that was read was produced by SPEAR or Hetro, then the frequency data will reflect that rounding.
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (for-example (spectrum->freq spectrum1))
EXAMPLE 3: (for-example (spectrum->freq spectrum1 :peaks 5))
EXAMPLE 4: (for-example (spectrum->freq spectrum1 :sort t))
EXAMPLE 5: (for-example (spectrum->freq spectrum1 :sort 'down))
EXAMPLE 6: (for-example (spectrum->freq spectrum1 :low 100 :high 200))
(spectrum->mirror fundamental transposition-interval spectrum &key (low 0) (high 127) round filter)
This tool returns a modified spectrum. Note numbers in the spectrum are mirrored around a specified fundamental value which is expressed as a Midi note number. If a low value is chosen for the fundamental, the spectral intervals descend rather than ascend. This is related to Grisey's concept of subharmonicity.
Example 1 reads a SPEAR file, constructs a spectrum with one pitch per track, and stores the data in a stockpile. Select the sample file 'test spear bassoon.txt' in Support/FileExamples. The stockpile is used in the remaining examples.
Example 2 prints values from this spectrum.
FUNDAMENTAL is a note number which is used to mirror note numbers. Values above FUNDAMENTAL will be mirrored to be below the FUNDAMENTAL. Values below FUNDAMENTAL will be mirrored above FUNDAMENTAL (examples 3-5).
The modified spectrum can be used in any way that the original one was, e.g. with SPECTRUM->CHORD or SPECTRUM->PITCH.
Note numbers outside the range LOW to HIGH (after modification) are discarded. If a low value is chosen for FUNDAMENTAL, many of the mirrored values may be below the default value of LOW (0). A TRANSPOSITION-INTERVAL (expressed in semitones) can be added to the result after the modification has taken place but before the range (LOW-HIGH) is tested. This transposition can allow the modification to be shifted to a more suitable range (example 6).
Spectral values < FUNDAMENTAL can be filtered from the spectrum before modification (example 7). If TRANSPOSITION-INTERVAL is 0, FUNDAMENTAL will be the highest note number in the modified version (example 8).
The value chosen for FUNDAMENTAL is significant. If the value is not known, a decision could be made looking at the data produced by spectrum->window (example 2).
The tool SPECTRUM->RANGE can be used to determine the lowest and highest note numbers in a spectrum (example 9).
ROUND can be nil (no rounding) or a quantization value such as 0.5. It is applied to the note numbers after the modification has taken place (example 10).
The tool PEAKS? can be used to determine the number of peaks remaining after the spectrum has been mirrored (example 11).
Grisey's idea of subharmonicity (where the harmonic series goes down instead of up) is discussed in Rose (1996). The original method is available using the keyword SUBHARMONIC in the generator HARMONIC-CHORD (example 12).
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
Rose, F. (1996). Introduction to the pitch organization of French spectral music. Perspectives of New Music, 34(2), 6-39.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (spectrum->window spectrum1)
EXAMPLE 3: (fill-template construct-stockpile spectrum2
(spectrum->mirror c2 0 spectrum1))
EXAMPLE 4: (for-example (spectrum->pitch spectrum1)
:recycle nil)
EXAMPLE 5: (for-example (spectrum->pitch spectrum2)
:recycle nil)
EXAMPLE 6: (spectrum->window (spectrum->mirror c3 24 spectrum1))
EXAMPLE 7: (spectrum->window (spectrum->mirror c3 24 spectrum1 :filter t))
EXAMPLE 8: (spectrum->window (spectrum->mirror c3 0 spectrum1 :filter t))
EXAMPLE 9: (print-result (spectrum->range spectrum1))
EXAMPLE 10: (spectrum->window (spectrum->mirror c2 24 spectrum1 :round 0.5))
EXAMPLE 11: (print-result (peaks? (spectrum->mirror c2 0 spectrum1)))
EXAMPLE 12: (show-help 'harmonic-chord)
(spectrum->pitch spectral-data &key name sort low high peaks)
Returns a list of pitch values derived from SPECTRAL-DATA that was returned by READ-SPECTRUM-FILE. Typically the spectral data is read into a stockpile and used by this and other tools.
Example 1 can be used to read in spectral data from a SPEAR file (e.g. from 'test spear bassoon.txt' found in the Support/FileExamples folder). Pitch values will be rounded to quarter-tones.
When the stockpile in example 1 is made, the pitch values will be sorted according to descending amplitude values.
Example 2 produces a list of pitch values. Note that the choice to round to quarter-tones was made in READ-SPECTRUM-FILE. A different base frequency for a4 can also be specified in READ-SPECTRUM-FILE. The keyword UNIQUE in READ-SPECTRUM-FILE will remove duplicate peaks (that may have resulted from the rounding process).
To return a list of notenames for the pitches, bind the keyword NAME to t (example 3). If SPECTRAL-DATA is rounded to a unit smaller than a semitone, fractional pitch data will appear in parentheses. If the data is rounded to semitones, there is no fractional data.
To sort the pitches in ascending order, bind SORT to t (example 4).
To sort the pitches in descending order, bind SORT to 'down (example 5).
The number of peaks to return can be bound to PEAKS (<= the number of peaks in SPECTRAL-DATA) (example 6). If you do not remember the number of peaks in SPECTRAL-DATA, use the tool PEAKS? (example 7).
The pitches extracted from SPECTRAL-DATA can be mapped to be in a different range by binding LOW and/or HIGH to another pitch value (examples 8-10). The mapped pitches will be rounded with the same round value used in READ-SPECTRUM-FILE.
Example 11 produces a section with pitches randomly chosen from the available spectral pitches.
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file :round 0.5))
EXAMPLE 2: (for-example (spectrum->pitch spectrum1))
EXAMPLE 3: (for-example (spectrum->pitch spectrum1 :name t))
EXAMPLE 4: (for-example (spectrum->pitch spectrum1 :sort t))
EXAMPLE 5: (for-example (spectrum->pitch spectrum1 :sort 'down))
EXAMPLE 6: (for-example (spectrum->pitch spectrum1 :peaks 5))
EXAMPLE 7: (print-result (peaks? spectrum1))
EXAMPLE 8: (for-example (spectrum->pitch spectrum1 :low 40 :high 60))
EXAMPLE 9: (plot (spectrum->pitch spectrum1))
EXAMPLE 10: (plot (spectrum->pitch spectrum1 :low 40 :high 60)
:replace nil)
EXAMPLE 11: (fill-template data-section spectral-melody 100 100 1
(random-choice (spectrum->pitch spectrum1))
mf 1)
(spectrum->range spectrum &key name)
A spectrum which has been read using READ-SPECTRUM-FILE is examined to return the lowest and highest note number used in the spectrum. For example 1, use the sample file 'test spear bassoon.txt' in Support/FileExamples.
If keyword NAME is bound to t, note names and fractional values are returned instead of Midi note numbers (example 2)
This tool could be useful to make informed choices regarding the modification of a spectrum with SPECTRUM->MIRROR (example 3).
It can be used in the For Example dialog, in the AC Toolbox Listener or in a Lisp edit window. More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (print-result
(spectrum->range (read-spectrum-file)))
EXAMPLE 2: (print-result
(spectrum->range (read-spectrum-file) :name t))
EXAMPLE 3: (show-help 'spectrum->mirror)
(spectrum->structure spectral-data number duration channel &key low high low-amp high-amp )
Makes a parallel note structure (a chord) based on pitch and velocity values derived from SPECTRAL-DATA. This data was returned by READ-SPECTRUM-FILE. Typically the spectral data is read into a stockpile and used by this and other tools.
Example 1 can be used to read in spectral data (e.g. from the file 'test spear bassoon.txt' found in the Support/FileExamples folder).
When the stockpile in example 1 is made, a number of peaks, starting with the peak with the highest amplitude, will be read in.
NUMBER is the chord size. DURATION is a constant, generator, list, etc. for determining the duration of each member of the chord. CHANNEL is a constant, generator, list, etc. for specifying the Midi channel for each member of the chord (examples 2-3).
Pitch can be mapped by binding values to LOW and HIGH (example 4).
Velocity can be mapped by binding values to LOW-AMP and HIGH-AMP (example 5).
The note structures returned by SPECTRUM->STRUCTURE can be joined in sequence (example 6).
SPECTRUM->STRUCTURE will use the pitches as they were rounded in READ-SPECTRUM-FILE.
More information about reading and using spectral data in the AC Toolbox can be found in Tutorial 20 of the AC Toolbox Tutorial.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (plot (spectrum->structure spectrum1
5 '(5 4 3 2 1) 1))
EXAMPLE 3: (fill-template structured-section section1 1000
(spectrum->structure spectrum1 11 1 1))
EXAMPLE 4: (fill-template structured-section section2 1000
(spectrum->structure spectrum1 11 1 1
:low 40 :high 70))
EXAMPLE 5: (fill-template structured-section section3 1000
(spectrum->structure spectrum1 11 1 1
:low-amp 60 :high-amp 100))
EXAMPLE 6: (fill-template structured-section section4 1000
(in-sequence (spectrum->structure spectrum1 11 1 1)
(spectrum->structure spectrum1 11 1 1
:low 40 :high 70)
(spectrum->structure spectrum1 11 1 1
:low 40 :high 45)))
(spectrum->window spectral-data &key low-amp high-amp peaks sort raw)
Prints information from the SPECTRAL-DATA to a window. This data was returned by READ-SPECTRUM-FILE. Typically the spectral data is stored in a stockpile and used by this and other tools.
For example, the spectral data can be read from the file 'test spear bassoon.txt' found in the Support/FileExamples folder (examples 1-2). See READ-SPECTRUM-FILE for more information about making and reading spectral files.
Velocity can be mapped with the keywords LOW-AMP and HIGH-AMP (example 3).
PEAKS can be used to further limit the number of peaks printed (example 4).
If SORT is t, the pitches are sorted in ascending order (example 5).
To sort the pitches in descending order, bind SORT to 'down (example 6).
If RAW is t, only the frequency and amplitude values are printed but not the Midi equivalents (example 7).
This tool can be evaluated in a listener (Other>Listener), in the For Example dialog, or in an editor window (File>Text>New).
If READ-SPECTRUM-FILE rounded the data and if the file which was read was produced by SPEAR or Hetro, the frequency data will reflect that rounding.
EXAMPLE 1: (fill-template construct-stockpile spectrum1
(read-spectrum-file))
EXAMPLE 2: (spectrum->window spectrum1)
EXAMPLE 3: (spectrum->window spectrum1 :low-amp 30 :high-amp 50)
EXAMPLE 4: (spectrum->window spectrum1 :peaks 5)
EXAMPLE 5: (spectrum->window spectrum1 :sort t)
EXAMPLE 6: (spectrum->window spectrum1 :sort 'down)
EXAMPLE 7: (spectrum->window spectrum1 :raw t)
(split value lower-limit probability-of-split number-of-branches &key conversion)
Returns a closure primarily intended for producing duration values. When applied, the next value from what Kevin Jones calls a space grammar will be returned. What he calls a space grammar is the hierarchical division of a value into smaller units, like a tree. If the NUMBER-OF-BRANCHES is 2, the value is either returned or split into 2. Each of those split values is again either returned or split again into 2. This process continues until either the value is returned or the lower-limit for a value is reached.
The probability that the value will be split is in the range 0.0 - 1.0.
If the value 96 is to be split, and the lower limit is 6, the following set of values could result: 48 12 24 6 6.
SPLIT differs from Jones' space grammar in several ways.
1. The generator keeps producing values. If all splits of a value have been used, the entire process starts again. Each application of the closure resulting from split returns one value (example 1).
2.The number of branches is variable (example 2).
If you need to guarantee that integer values will result from the application of this generator, supply a conversion function to the keyword :CONVERSION (example 3).
3. All input parameters can receive a constant value, a list, or a generator to produce the next split of some value. A list is cycled and a generator is applied to produce a value. All input parameters can change over time (example 4).
The Jones article can be found in Contemporary Music Review, 3(1). This concept is also discussed in his article 'Compositional Applications of Stochastic Processes' in Computer Music Journal, 5(2).
EXAMPLE 1: (for-example (split 96 6 .6 2))
EXAMPLE 2: (for-example (split 96 6 .6 3))
EXAMPLE 3: (for-example (split 96 6 .6 3 :conversion #'truncate))
EXAMPLE 4: (for-example
(split (random-choice '(48 36 55)) 6
(random-value .4 .8) (random-value 2 5))
:number 40)
(spray shape n lower upper deviation &key percent dfunction round min max conversion)
Returns a closure. When applied, a value from SHAPE is produced with a random deviation.
SHAPE may be a shape, stockpile, list, function, etc. SHAPE is converted to a list with N values. These values are mapped to be between LOWER and UPPER.
A random DEVIATION is added to the value from the shape. This deviation is the total deviation. If for example it is 10, that means that deviation is possible from 5 under the value to 5 above the value.
In example 1, line-shape is mapped to be 100 values between 40 and 80. A random-deviation in the range -5 to +5 was added to the value.
Example 2 uses a larger deviation of 20.
DEVIATION is expressed in absolute values. 10 would be 10 pitch steps, 10 rhythmic units, etc. If DEVIATION is to be interpreted as a percentage, the key word for PERCENT should be bound to t (example 3).
To quantize the result with another unit, bind ROUND to a quantization unit (example 4).
To get integer output, ROUND could be bound to 1. Alternatively, the keyword CONVERSION can be bound to a LISP conversion function such as TRUNCATE (example 5).
If both ROUND and CONVERSION are bound to values other than nil, ROUND takes precedence.
Since spray is a generator, continued use would produce different random deviations around the shape (example 6).
LOWER, UPPER, DEVIATION, MIN, and MAX may vary over time (example 7).
DFUNCTION can be used to specify a generator to determine the nature of the deviation. This generator should produce values in the range -1.0 to 1 (example 8).
MIN and MAX can be used to control the range of the values after the deviation has been added. If a value in the range specified by MIN-MAX cannot be made in 100 tries, the value is clipped according to the specification of MIN and MAX (examples 9-10). This use of a line with deviation within a specified range is similar to the approach described by James Tenney in his article Computer Music Experiences, 1961-1964.
EXAMPLE 1: (plot (spray line-shape 100 40 80 10))
EXAMPLE 2: (plot (spray line-shape 100 40 80 20))
EXAMPLE 3: (plot (spray line-shape 100 40 80 10 :percent t))
EXAMPLE 4: (for-example (spray line-shape 20 40 80 10
:round 0.5))
EXAMPLE 5: (for-example
(spray line-shape 20 40 80 10
:conversion #'truncate))
EXAMPLE 6: (plot (spray line-shape 20 40 80 20))
EXAMPLE 7: (plot
(spray line-shape 100 40 80
(line 100 0.0 30)))
EXAMPLE 8: (plot (spray line-shape 100 40 80 10
:dfunction (bv -1.0 1 .2 .2)))
EXAMPLE 9: (plot (spray sine-shape 100 40 80 10 :min 40))
EXAMPLE 10: (plot (spray sine-shape 100 40 80 10 :max 80))
(spread pitch octave)
This generator is a shortcut for PITCH-AND-OCTAVE.
It returns a closure. When applied, a pitch or chord is placed in a designated octave.
PITCH can be in any range, but it is reduced to 0 - 11 as the representation of the pitch class. 0 is C, 1 is C#, etc.
By default, middle C is octave 4. C4 is midi note number 60. This can be changed in the preferences to be octave 3. In that case, c3 is note number 60.
When middle C is octave 4, OCTAVE can have values from -1 to 9.
PITCH and OCTAVE can be constants, lists, stockpiles, or generators (example 1).
The value derived from PITCH may also be a chord (list of pitches) (example 2).
See the documentation for PITCH-AND-OCTAVE for more information and examples (example 3).
EXAMPLE 1: (for-example
(midi->notename
(spread (major 60) '(3 4 5))))
EXAMPLE 2: (for-example
(spread (make-chord (series-value 60 71) 3)
(rv 3 5)))
EXAMPLE 3: (show-help 'pitch-and-octave)
(srv low high &key step)
This is a shortcut for SERIES-VALUE. When applied, one element of the set of all values between LOW and HIGH is returned at random. No element is repeated until all elements have been used once (example 1).
STEP is the distance between values in the set (example 2). The first value is LOW, the second is LOW + STEP. The default value for STEP is 1.
SV is the shortcut for sieve and should be confused with SERIES-VALUE.
See the documentation for SERIES-VALUE for more examples (example 3).
EXAMPLE 1: (for-example (srv 1 10))
EXAMPLE 2: (for-example (srv 1 5 :step 0.5))
EXAMPLE 3: (show-help 'series-value)
(standard-map I Y K giant &key eye xy first)
Returns a closure. When applied returns the next value of a dynamical system, described by the following formula:
I(n+1)=I(n)+K*sinY(n)
Y(n+1)=Y(n)+I(n+1)
The default output variable is Y. By using the keyword EYE the variable I is returned. Both variables (Y I) will be returned in a list by using the keyword XY.
K controls the behaviour of the system and can be any number between about -60 to 60. I and Y set the initial conditions, which can vary the behaviour of the system.
The parameter GIANT determines after how many iterations the value is returned. This can be useful for filling a list with a small number of values describing the behaviour of the system over a longer period.
The system will behave chaotically for every value of K. The initial values for I and Y have an influence on the details of the behaviour (examples 1-2).
The behaviour of I and Y is independent of each other (examples 3-5).
It is not easy to predict the maximum and minimum of the output values. To map the output of this function to useful values, use CONVERT (example 6).
K may vary over time (example 7).
The initial values for I and Y are not returned. If the initial values should be returned as the first result of the generator, keyword FIRST should be bound to t (examples 8-9).
[Note: this standard-map differs from the 'real' standard-map. Its phase-space is not a two-dimensional torus]
See Bidlack,R. (1992). "Chaotic Systems as Simple (but Complex) Compositional Algorithms". Computer Music Journal, 16(3).
This generator was contributed by Gijs de Bruin.
EXAMPLE 1: (plot (standard-map 0.1 0.1 1.5 1) :plot nil)
EXAMPLE 2: (plot (standard-map 2.0 1.5 1.5 1) :plot nil)
EXAMPLE 3: (plot (standard-map 20 30 45.54 1)
:number 400 :plot nil)
EXAMPLE 4: (plot (standard-map 20 30 45.54 1 :eye t)
:number 400 :plot nil)
EXAMPLE 5: (plot (standard-map 0.1 0.1 45.54 1 :xy t)
:number 1000)
EXAMPLE 6: (for-example (convert (standard-map 20 30 45.54 10)
100 c2 c5))
EXAMPLE 7: (plot (standard-map 20 30
(group (line 10 1.0 20) 10) 1)
:plot nil)
EXAMPLE 8: (for-example (standard-map 2.0 1.5 1.5 1))
EXAMPLE 9: (for-example (standard-map 2.0 1.5 1.5 1 :first t))
stockpile
A stockpile is a collection of values. A stockpile can be used as the input parameter for generators ending with -choice, e.g. random-choice.
(stockpile->notename stockpile &key float)
Returns a list of alphanumeric representations (notenames) corresponding to Midi note numbers. STOCKPILE can be a list or stockpile (example 1).
MIDI->NOTENAME is a generator that will keep on producing values while STOCKPILE->NOTENAME will only convert the values that are in the stockpile (example 2).
When keyword FLOAT is bound to t, the fractional part of a note is printed in parentheses. This is useful if the Midi value being converted is a floating point number and insight into a possible translation to microtones is desired (example 3).
The choice for naming middle C (Midi note number 60) either c3 or c4 is made in the Preferences dialog.
EXAMPLE 1: (for-example (stockpile->notename '(60 64 67)))
EXAMPLE 2: (for-example (midi->notename '(60 64 67)))
EXAMPLE 3: (for-example
(stockpile->notename '(60.5 64.25 67) :float t))
stream
A stream is an object that produces values in realtime. You turn on the stream and notes or Midi values are produced until the stream is turned off.
(stretch factor &key round)
Returns a closure that multiplies an input value by FACTOR. The result is an integer (example 1).
FACTOR may vary over time using a generator, a list, etc. (example 2)
If ROUND is bound to a number, it will be considered the quantization unit (example 3). If ROUND is bound to t, the Lisp function ROUND will be used to round the value (example 4).
EXAMPLE 1: (show-transformation (stretch 2)
'(1 8 2 4 2))
EXAMPLE 2: (show-transformation (stretch (random-value 1 4))
'(1 1 1 1 1))
EXAMPLE 3: (show-transformation (stretch 2.0 :round .25)
(produce 10 (rv 1.0 3)))
EXAMPLE 4: (show-transformation (stretch 2.0 :round t)
(produce 10 (rv 1.0 3)))
structured section
A section where the notes have been specified with a note structure. Available note structures are A-NOTE, A-REST, A-DELAY, IN-SEQUENCE, and IN-PARALLEL.
For more information about note structures see the entries for the different note structures (a-notes, etc.) in the Index.
(stutter number thing stutter)
Returns a closure. When applied, one value is produced. The first NUMBER of applications of the closure, THING is used to produce a value. The next STUTTER number of values, the last value from THING is repeated. Then THING continues for a NUMBER of values, followed by some more stuttering, etc (examples 1-3).
NUMBER, THING, and STUTTER can vary over time.
STUTTER differs from GROUP in that GROUP repeats all values whereas STUTTER only repeats some values (example 4).
EXAMPLE 1: (for-example (stutter 5 (line 10 1 10) 5))
EXAMPLE 2: (plot (stutter (random-value 5 10)
(line 100 1 100)
(random-value 3 12)))
EXAMPLE 3: (fill-template data-section s1 100 200
(stutter (rv 5 10) (rv 1.0 3) (rv 5 10))
(rv 40 80) f 1)
EXAMPLE 4: (for-example (group (line 10 1 10) 2))
(su &rest sieves)
SU is a shortcut (abbreviation) for SIEVE-UNION (example 1).
See the help for SIEVE-UNION for more information (example 2).
EXAMPLE 1: (for-example (su '(1 3 5 7) '(1 4 7)))
EXAMPLE 2: (show-help 'sieve-union)
(sum thing &optional number)
Returns the sum of the elements of THING if it is a list or stockpile containing numbers (examples 1-3).
If THING is a generator, it is applied NUMBER of times and the sum is returned (example 4).
The default value of NUMBER is 100. To increase the number of applications of the generator, provide NUMBER with a new value (example 5).
See the help for the GENERATE-SUM for a generator than will sum values.
EXAMPLE 1: (print-result (sum '(1 2 3 4)))
EXAMPLE 2: (fill-template generate-stockpile random-stock 1000
(random-value 0.0 1))
EXAMPLE 3: (print-result (sum random-stock))
EXAMPLE 4: (print-result (sum (random-value 0.0 1)))
EXAMPLE 5: (print-result (sum (random-value 0.0 1) 1000))
supercollider
SuperCollider is a language for sound synthesis and a synthesis server application originally designed and developed by James McCartney (examples 1).
The AC Toolbox can produce binary OSC files which it will render with the SuperCollider Server if available.
EXAMPLE 1: (open-url "http://supercollider.sourceforge.net/")
supercollider server
SuperCollider is a synthesis server application and a language originally designed by James McCartney. In the language, synthesis definitions (synthdefs) can be made and stored. The synthesis server (scsynth) can be called by another application, such as the AC Toolbox, and render a binary OSC (OpenSound Control) file into an audio file.
To render OSC score files in the AC Toolbox, SuperCollider must be installed. The AC Toolbox will initially look for it in the Applications folder but it can be installed elsewhere. In that case, the AC Toolbox will probably ask where SuperCollider is.
SuperCollider can be downloaded with example 1.
Options concerning writing OSC binary files and rendering these files using the SuperCollider synthesis server can be found in the OSC File Options dialog. Synthdefs should be stored in the synthdefs folder of SuperCollider.
It is not necessary for the SuperCollider language application to be open when rendering OSC files in the AC Toolbox.
EXAMPLE 1: (open-url "http://supercollider.sourceforge.net/")
(sv mod start lower higher)
SV is a shortcut (abbreviation) for SIEVE (example 1).
See the help for SIEVE for more information (example 2).
EXAMPLE 1: (for-example (sieve 2 1 1 20))
EXAMPLE 2: (show-help 'sieve)
symbols
Many symbols have been predefined in the Toolbox. MIDI note numbers can be entered using a lettername with an octave. c4 is MIDI note number 60. c#4 is 61, Ef4 is 63, etc. Velocity symbols include ppp,pp, p, mp, mf,f, ff, fff.
(sync controller)
Returns a closure that is intended to be used as a controller. Basically it allows controllers to be synchronized, i.e. return the same value.
One reason to synchronize controllers is to relate values being generated for different parameters. An example would be if one wanted short rhythmic values to have a low velocity value and long values to have a high velocity value.
To define a data section where the velocity values can be related to the generated rhythmic values:
1. Define a controller to generate the rhythmic values (example 1).
2. Define two controllers that are sychronized with this controller (examples 2-3).
3. Construct a lookup table that can be used to map specific rhythmic values to a velocity value (example 4).
4. Make the data section in example 5.
RHYTHM1 and RHYTHM2 are both synchronized with the same controller, RHYTHM. They will produce the same values. The generator LOOKUP takes a value from RHYTHM2 and looks up the new value for velocity in VELOCITY-TABLE. This table was defined so that low values (1,2,3) map to low velocity values (40,45,50) and that a long value (10) would map to a high velocity value (127).
EXAMPLE 1: (fill-template make-controller rhythm
(random-choice '(1 2 3 10)))
EXAMPLE 2: (fill-template make-controller rhythm1 (sync rhythm))
EXAMPLE 3: (fill-template make-controller rhythm2 (sync rhythm))
EXAMPLE 4: (fill-template construct-stockpile velocity-table
(make-lookup-table 1 40 2 45 3 50 10 127))
EXAMPLE 5: (fill-template data-section test1 100 50 rhythm1
(random-value c1 g#4)
(lookup rhythm2 velocity-table) 1 0)
(take number1 value1 number2 value2 ...)
Returns a closure. When applied, one value is produced. In short, some results are returned by VALUE1, then some by VALUE2, etc.
For the first NUMBER1 applications of the closure, VALUE1 is used to produce a value. VALUE1 can be a generator, stockpile, list, constant, etc. Then for the next NUMBER2 applications of the closure, VALUE2 is used. As many numbers and values as desired may be used. After all the values have been used the desired number of times, the whole process starts again from the beginning (example 1).
The values for NUMBER1, NUMBER2 etc. can be produced by generators (example 2).
In addition to generators, values can be taken from constants (example 3), lists (example 4), stockpiles, etc.
If NUMBER1, NUMBER2, ... is a negative number, the corresponding value expression is used indefinitely (example 5). This allows some different states to be used before a final state is reached. In Example 5, three small numbers are chosen before the generator 'settles in' to pick random values between 100 and 200.
TAKE can also be useful for rhythmic groupings or articulations. For the rhythm parameter in a data section, a generator could be used to produce a number of positive values (for note durations) followed by a negative value for a rest. Since TAKE steps through its arguments and returns to the first pair of arguments after finishing the last pair, Example 6 results in a number of notes, a rest, a number of notes, a rest, etc.
EXAMPLE 1: (for-example
(take 10 (random-value 1 10)
5 (random-value 100 200)
3 (random-choice '(1 2 4 8))
2 (random-value 1000 2000)))
EXAMPLE 2: (for-example
(take (random-value 5 10) (random-value 1 10)
(series-value 1 4) (random-value 100 200)
(random-value 2 3) (random-choice '(1 2 4 8))
(series-value 1 2) (random-value 1000 2000)))
EXAMPLE 3: (for-example (take 10 0 10 34.6))
EXAMPLE 4: (for-example (take 10 '(1 2 3 4 5)
10 '(100 200 300 400 500)))
EXAMPLE 5: (for-example (take 3 (rv 1 10) -1 (rv 100 200)))
EXAMPLE 6: (fill-template data-section groupings 100 100
(take (series-choice '(3 5 8 20))
(rv 1.0 3)
1 (rv -4.0 -7))
(random-intervals c3 c5 1 3 4)
mf 1)
(take-one controller)
Returns one value from a controller, generator, or stockpile.
For a controller see examples 1-6.
For a generator, see example 7.
Note that each time the expression with the generator is evaluated, the generator is made again. This means it does not remember what it did previously (which in this case means that series-value may repeat). If series-value should retain state (remember where it is), a controller should be used.
For a stockpile, see examples 8-9.
Note that the first value is always returned from a stockpile. This could be useful for example in generating csound scores where one value could be shared among layers but a new value could be generated per section.
EXAMPLE 1: (define lower (make-controller '(40 50 40 60)))
EXAMPLE 2: (define higher (make-controller '(50 60 80 70)))
EXAMPLE 3: (for-example (random-value (take-one lower)
(take-one higher)))
EXAMPLE 4: (for-example (random-value (take-one lower)
(take-one higher)))
EXAMPLE 5: (define series (make-controller (series-value 1 3)))
EXAMPLE 6: (for-example (take-one series))
EXAMPLE 7: (for-example (take-one (series-value 1 3)))
EXAMPLE 8: (define stock1
(generate-stockpile 5 (random-value 1 10)))
EXAMPLE 9: (for-example (take-one stock1))
(tendency-choice sequence mask1 ...)
Returns a closure. When applied, one value is chosen from the sequence according to a percentage value chosen from the tendency mask. The boundaries of the tendency mask should expressed in percentages. A tendency mask is a concept developed by G.M. Koenig for producing random numbers between boundaries that change in time. One mask is described by N, A1, A2, Z1, Z2.
N is the number of values to be produced.
A1,A2 are the initial boundaries.
Z1,Z2 are the final boundaries.
There is a linear interpolation between the initial boundaries and the final boundaries (examples 1-2).
Any number of masks may be used. After all values have been produced from one mask, the next value is determined by the next mask (example 3).
EXAMPLE 1: (for-example (tendency-choice '(a b c d e f g h i)
'(20 0 20.0 90.0 100)))
EXAMPLE 2: (for-example (tendency-choice '(a b c d e f g h i)
'(20 50 60 0 100)))
EXAMPLE 3: (for-example (tendency-choice '(a b c d e f g h i)
'(10 0 10 90 100)
'(10 50 50 0 100)))
(tendency-value mask1 ...)
Returns a closure. When applied, it produces one numerical value bounded by a tendency mask. A tendency mask is a concept developed by G.M. Koenig for producing random numbers between boundaries that change in time. One mask is described by N, A1, A2, Z1, Z2.
N is the number of values to be produced.
A1,A2 are the initial boundaries.
Z1,Z2 are the final boundaries.
There is a linear interpolation between the initial boundaries and the final boundaries.
Example 1 produces 20 random values, using a mask with 1,5 as the initial boundaries and 95,100 as the final boundaries. Example 2 produces 10 values from the mask before starting again at the beginning of the mask.
An indefinite number of masks may be used. After all values have been produced from one mask, the next value is determined by the next mask (examples 3-4).
The type of the output result is determined by the mask values. If all values are integers, the output is an integer. Otherwise a real value is output.
The concept of a tendency mask can also be realized by defining a mask object and using the tool CONVERT to create a list of values that correspond to that mask.
EXAMPLE 1: (for-example (tendency-value '(20 1 5 95 100)))
EXAMPLE 2: (for-example (tendency-value '(10 1 5 95 100)))
EXAMPLE 3: (for-example (tendency-value '(10 1 5 95 100)
'(10 50 55 1 100)))
EXAMPLE 4: (plot (tendency-value '(50 1 5 95 100)
'(50 50 55 1 100)))
(test-generator n generator &key chord)
Returns a list with strings for the minimum and maximum values produced after N applications of the GENERATOR. This is useful if you are unsure about the possible range of results of a generator. In particular, chaotic generators have ranges that are often difficult to predict (example 1).
If the generator produces values that are lists (such as is the case with chords or chaotic functions, keyword CHORD can be bound to nil if the list is to be considered a multi-dimensional result. It this case, separate minimum and maximum values will be returned for each position in the list (example 2).
Knowing the expected range is important if for example you are using the generator MAP/TIME which assumes you know the possible range of the input values.
EXAMPLE 1: (for-example
(test-generator 100
(henon 0.0 0.0 1.4 0.3 1)))
EXAMPLE 2: (for-example
(test-generator 100
(henon 0.0 0.0 1.4 0.3 1 :xy t)
:chord nil))
(test-value number)
Returns a closure. When applied, a value is read from the corresponding box in the Test Value dialog (available via the 'Test Value' menu item in the 'Tools' menu).
The Test Value dialog has places for 16 entries (1-16). The values entered in the corresponding places can be accessed with the test-value generator. No scaling of the values is done. Any appropriate values may be entered.
NUMBER is the number of the place in the Test value dialog.
This generator is a simple alternative to EXTERNAL-VALUE and can be used in similar ways. It is most useful to test parameter values in a stream. While the stream is playing, new values can be sent from the Test value dialog and read by the TEST-VALUE generator.
Example 1 is a MIDI data stream using test-value.
Open the Test Value dialog via the 'Test Value' menu item. Enter numerical values for 1 and 2, e.g. 40 and 80. Send the values. If no values have been sent before test-value is applied, 0 is returned.
Generators and lists can also be entered (example 2). When playing test2, enter (random-value 40 80) for the value for place 1.
Test-value can be abbreviated to tv (example 3).
A safe practice is to enclose test-value within a clip-generator (cg) to make sure that no value below a specified minimum value is produced (example 4). Enter values for 1 and 2. 1 is the clock value which is constrained to be no less than 50 and 2 is the pitch.
EXAMPLE 1: (fill-template make-midi-data-stream test1 100 1
(random-value (test-value 1) (test-value 2))
ff 1)
EXAMPLE 2: (fill-template make-midi-data-stream test2 100 1
(test-value 1)
ff 1)
EXAMPLE 3: (fill-template make-midi-data-stream test3 100 1
(random-value (tv 1) (tv 2))
ff 1)
EXAMPLE 4: (fill-template make-midi-data-stream test2 (cg (tv 1) 50) 1
(test-value 2)
ff 1)
(thin indispensability-list level)
Returns a list containing the thinned indispensability-list. If the list is thinned to level 2, then all values < 2 are set to -1. Other values remain the same (example 1).
This tool can be used in conjunction with tool PULSE-INTERPOLATION. See tool PULSE-INTERPOLATION for an example of its use. See generator PRODUCE-PULSE for a discussion of indispensabilities.
EXAMPLE 1: (for-example (thin '(5 0 3 1 4 2) 2))
(thin-pulse indispensability-list to-thin)
Returns a closure. When applied, one thinned pulse value is returned. INDISPENSABILITY-LIST should be a list. TO-THIN may be a constant, list, or generator. A new thinning factor is calculated each time you start at the beginning of the INDISPENSABILITY-LIST (that is at the beginning of each metric unit (examples 1-2).
See the generator PRODUCE-PULSE for a more information about indispensabilities and thinning. See the generator INTERPRET-PULSE for ways that a stockpile generated with this generator can be interpreted as rhythmic or velocity values.
EXAMPLE 1: (for-example (thin-pulse '(5 0 2 4 1 3) 2)
:number 12 :number-per-line 6)
EXAMPLE 2: (for-example (thin-pulse '(5 0 2 4 1 3)
(random-value 1 5))
:number 24 :number-per-line 6)
timed section
A section made by combining sections, communities, or midi objects. A start time for each object is specified. The start times may overlap or not as desired.
tools
Tools are various functions that have been included in the Toolbox to assist in the process of the algorithmic composition. Some of the tools are useful when filling in the dialog boxes. Other tools are more appropriate when writing a Lisp program yourself. A Tool basically is any function that is not a generator. Additional information about tools can be found in the Annotated Index and in the Index.
(tracks? stockpile)
If stockpile contains analysis data returned from READ-TRACKS-FILE, this tool will indicate the number of tracks that were read (in case you do not remember). Select file 'test spear bassoon.txt' in Support/FileExamples for example 1. Example 2 will return the number of tracks.
This tool also will return the number of 'tracks' that were read with READ-SPECTRUM-FILE if a tracks files created by SPEAR or Hetro was used to make the spectrum. Select file 'test spear bassoon.txt' for example 3. Example 4 returns the number of tracks.
To recall the number of peaks in any other data returned by READ-SPECTRUM-FILE, use tool PEAKS?.
EXAMPLE 1: (fill-template construct-stockpile bassoon
(read-tracks-file))
EXAMPLE 2: (print-result (tracks? bassoon))
EXAMPLE 3: (fill-template construct-stockpile bspectrum
(read-spectrum-file))
EXAMPLE 4: (print-result (tracks? bspectrum))
(tran operator1 object1 ...)
TRAN allows you to specify your own transformer using arithmetic expressions and various combinations of constants, lists, stockpiles, and generators. TRAN returns a closure that is used for the transformation.
TRAN is similar to ON-THE-FLY except it is a transformer and expects an incoming value to change.
Infix notation is used. Expressions are evaluated left to right (as in SuperCollider) and no grouping with parentheses is allowed.
Example 1 divides the list by 2.0.
Example 2 multiplies values in the list by 2 and then adds 1 to them. Any number of operators and objects may be used.
Example 3 adds 1 first and then multiplies the result by 2. This should make clear the simple nature of the execution: left to right, no grouping or priorities.
Example 4 will add a value from the list '(1 2 4 7 8) in sequence to the incoming values. 1 is added to the first value, 2 to the second, 4 to the third, etc.
Example 5 will add a random value in the range -0.5 to 0.5 to each value. The generator is applied each time so that different random values are added.
Example 6 quantizes the result using the operator ROUNDQ. The next value is the quantization unit.
Example 7 specifies a data section that will be transformed.
Example 8 transforms the pitch in section1 by adding 0, -12, or 12 to the value. -12 and 12 will change the octave of the pitch. Subsequently, either 0, -0.5, or 0.5 is added. -0.5 and 0.5 will shift the pitch down or up a quarter tone.
Tempo in this example is transformed by multiplying the value by the grow generator. This generator produces a geometric series multiplying each previous value by 1.05 (for the first 50 values) and then multiplying the remaining 50 values by a factor 0.95.
EXAMPLE 1: (show-transformation (tran / 2.0)
'(2 2 1.5 1))
EXAMPLE 2: (show-transformation (tran * 2 + 1)
(from 1 10))
EXAMPLE 3: (show-transformation (tran + 1 * 2)
(from 1 10))
EXAMPLE 4: (print-result
(transform-stockpile (from 1 10)
(tran + '(1 2 4 7 8))))
EXAMPLE 5: (print-result
(transform-stockpile (from 1 5)
(tran + (rv -0.5 .5))))
EXAMPLE 6: (for-example
(transform-stockpile '(1 1.4 1.6 1.7 2)
(tran * 2 roundq 0.5)))
EXAMPLE 7: (fill-template data-section section1 100
100 (rv 1.0 2) (rv c5 g#5)
(line (from-number) 60 127) 1)
EXAMPLE 8: (fill-template transform section1t section1
:pitch (tran + (rc '(0 12 -12)) + (rc '(0 -0.5 0.5)))
:tempo (tran * (grow 1 '(1.05 .95) :n 50 :reset nil)))
(transform-and parameters-and-conditions tparameter transformer)
This transformer can be used with the WHATEVER parameter to transform sections. It will transform TPARAMETER with TRANSFORMER if all conditions are met.
For example, if the pitch is > g4 and the velocity is > 76, the tempo can be stretched.
PARAMETERS-AND-CONDITIONS should be a list containing one or more pairs of parameters and conditions, e.g.
(list 'pitch (anything > g4) 'velocity (anything > 76))
Parameters that can be examined in the list of PARAMETERS-AND-CONDITIONS are pitch, velocity, channel, duration, and start-time.
Parameters that can be transformed are pitch, velocity, channel, duration, tempo, and attack.
Parameters will only be transformed when all of the conditions have been met.
Example 1 will be used to demonstrate some of the possibilites.
Example 2 transpose pitches up an octave if they are > g4 and the velocity < ff.
Example 3 will stretch the durations if the channel is 2, pitch is < 60, and the velocity is not equal to ff.
When durations are stretched, as they were in example 3, this has no effect on the attack times. To change both attack times and durations of an event, transform the tempo (example 4).
Example 5 transforms the attack times without changing the durations.
Duration can also be used as one of the conditions to determine if a transformation should be made. Durations are expressed in milliseconds (the result of clock unit * rhythm value) (example 6).
If pitch is used as a parameter to be examined and it contains chords, e.g. made with MAKE-CHORD, the transformation will be applied if any pitch in the chord meets the condition (examples 7-8).
START-TIME can be used as the value for PARAMETER but not for TPARAMETER (examples 9-10). Values are expressed in milliseconds.
Related transformers are TRANSFORM-IF and TRANSFORM-OR. TRANSFORM-IF will only examine one parameter to determine if a transformation should be made. TRANSFORM-OR will examine more than one parameter and will make the transformation if one or more of the conditions has been met.
EXAMPLE 1: (fill-template data-section ds1 200 20
(rv .5 2) (rv 40 80) (rc '(p mf ff))
'(1 2))
EXAMPLE 2:
(fill-template transform ds1-trans1 ds1
:whatever (transform-and (list 'pitch (anything > g4)
'velocity (anything < ff))
'pitch (transpose 12)))
EXAMPLE 3:
(fill-template transform ds1-trans2 ds1
:whatever (transform-and (list 'channel (anything = 2)
'pitch (anything < 60)
'velocity (anything /= ff))
'duration (stretch 2)))
EXAMPLE 4:
(fill-template transform ds1-trans3 ds1
:whatever (transform-and (list 'channel (anything = 2)
'pitch (anything < 60)
'velocity (anything /= ff))
'tempo (stretch 2)))
EXAMPLE 5:
(fill-template transform ds1-trans4 ds1
:whatever (transform-and (list 'channel (anything = 2)
'pitch (anything < 60)
'velocity (anything /= ff))
'attack (stretch 2)))
EXAMPLE 6:
(fill-template transform ds1-trans5 ds1
:whatever (transform-and (list 'pitch (anything > 60)
'duration (anything > 200))
'velocity (replace-all pp)))
EXAMPLE 7: (fill-template data-section ds2 200 13
(rv .5 2) (make-chord (rv 40 80) 3)
p 1)
EXAMPLE 8:
(fill-template transform ds2-trans1 ds2
:whatever (transform-and (list 'pitch (anything <= 50)
'duration (anything > 200))
'velocity (replace-all ff)))
EXAMPLE 9:
(fill-template transform ds2-trans2 ds2
:whatever (transform-and (list 'pitch (anything <= 50)
'start-time (anything < 1000))
'velocity (replace-all ff)))
EXAMPLE 10:
(fill-template transform ds2-trans2 ds2
:whatever (transform-and (list 'pitch (anything <= 50)
'start-time (anything inside 1000 1800))
'tempo (stretch 3)))
(transform-by-index to-produce-index transformer)
Returns a closure. It will transform parameter values at indicated positions. TO-PRODUCE-INDEX can be a constant, list, stockpile, generator, etc.
TO-PRODUCE-INDEX should produce valid index numbers. The index values start from 1. At each of these index values, the content of the object will be transformed with TRANSFORMER.
Example 1 is a section to be transformed. Index values for the notes in a section can be found in the Edit window for the section (select Edit in the Objects dialog).
Example 2 transforms the pitches in notes 1, 3, and 5 of a section. When TO-PRODUCE-INDEX is a list or stockpile, the duplicate values are removed and the remaining values are sorted in ascending order.
Example 3 uses WALK to calculate index values for the transformation. Index values need to be in ascending order. If they are not in ascending order, the highest, non-descending value is the last value transformed.
Example 4 uses PRODUCE to produce a list index values. Duplicate values are ignored. This could mean that fewer values than expected are transformed. In this example, series-value was used to avoid repetitions.
Another way to avoid repeated values is to filter the output of the generator used for producing the index values. This is done in example 5.
Example 6 stretches the tempo.
TRANSFORM-BY-INDEX can be used with various objects, not just sections.
Examples 7-8 transform a stockpile.
A binary OSC file can be transformed with Methods>Transform>OSC File. Csound score files do NOT want to be transformed with TRANSFORM-BY-INDEX.
EXAMPLE 1: (fill-template data-section section1
100 48 1 (chromatic c2) mf 1)
EXAMPLE 2: (fill-template transform trans1 section1
:pitch (transform-by-index '(1 3 5)
(transpose -12)))
EXAMPLE 3: (fill-template transform trans2 section1
:pitch (transform-by-index
(walk 3 (random-value 1 7))
(transpose -12)))
EXAMPLE 4: (fill-template transform trans3 section1
:pitch (transform-by-index
(produce 10 (series-value 1 48))
(transpose -12)))
EXAMPLE 5: (fill-template transform trans4 section1
:pitch (transform-by-index
(produce 10 (without (duplicates)
(random-value 1 48)))
(transpose -12)))
EXAMPLE 6: (fill-template transform trans5 section1
:tempo (transform-by-index
(produce 10 (series-value 1 48))
(stretch 3)))
EXAMPLE 7: (fill-template construct-stockpile stock1
(from 1 20))
EXAMPLE 8: (fill-template transform trans6 stock1
:whatever (transform-by-index
(from 1 20 :step 2)
(transpose 12)))
(transform-if parameter condition tparameter transformer)
This transformer can be used with the WHATEVER parameter to transform sections. For example, it can be used to only transform the pitch parameter when the duration value is within a certain range.
When the specified PARAMETER (pitch, velocity, channel, duration, or start-time) satisfies a CONDITION, the value of the TPARAMETER (pitch, velocity, channel, duration, tempo, or attack) is transformed using TRANSFORMER.
The section made with example 1 will be used to demonstrate some transformations. Example 2 can be used to print the values for the section in a window.
Example 3 transposes the pitch for any note where the velocity is > 80. Example 4 shows the result.
Example 5 stretches the duration of any pitch outside of the range 64-69. Example 6 plots the result.
When example 5 increased the durations, the attack times were not changed. This resulted in an overlap. If both the duration and attack times should be changed, use TEMPO for the TPARAMETER (examples 7-8).
It is also possible to transform the attack times without changing the durations (examples 9-10).
Note that attack and tempo may be used for the TPARAMETER (that is transformed) but not for PARAMETER (that is examined).
If pitch is used as the parameter to be examined (PARAMETER) and it contains chords, e.g. made with MAKE-CHORD, the transformation will be applied if any pitch in the chord meets the condition (examples 11-14).
DURATION can be used as the PARAMETER being examined (examples 15-16). The values are in milliseconds.
CHANNEL can be used for either PARAMETER or TPARAMETER. In examples 17-18, the channel is changed depending on the pitch.
START-TIME can be used as the parameter for PARAMETER but not for TPARAMETER (examples 19-20). START-TIME is expressed in milliseconds.
Related transformers are TRANSFORM-AND and TRANSFORM-OR.
TRANSFORM-AND will examine more than one parameter and will make the transformation if all of the conditions has been met.
TRANSFORM-OR will examine more than one parameter and will make the transformation if one or more of the conditions has been met.
EXAMPLE 1: (fill-template data-section ds1 200 13
(rv .5 2) (from 60 72) (rc '(p mf ff)) 1)
EXAMPLE 2: (show-text ds1)
EXAMPLE 3: (fill-template transform ds1-trans1 ds1
:whatever (transform-if 'velocity (anything > 80)
'pitch (transpose -12)))
EXAMPLE 4: (show-text ds1-trans1)
EXAMPLE 5: (fill-template transform ds1-trans2 ds1
:whatever (transform-if 'pitch (anything outside 64 69)
'duration (stretch 2)))
EXAMPLE 6: (plot ds1-trans2)
EXAMPLE 7: (fill-template transform ds1-trans3 ds1
:whatever (transform-if 'pitch (anything outside 64 69)
'tempo (stretch 2)))
EXAMPLE 8: (plot ds1-trans3)
EXAMPLE 9: (fill-template transform ds1-trans4 ds1
:whatever (transform-if 'pitch (anything inside 64 69)
'attack (stretch 2)))
EXAMPLE 10: (plot ds1-trans4)
EXAMPLE 11: (fill-template data-section ds2 200 13
(rv .5 2) (make-chord (rv 60 80) 4)
(rc '(p mf ff)) 1)
EXAMPLE 12: (plot ds2)
EXAMPLE 13: (fill-template transform ds2-trans1 ds2
:whatever (transform-if 'pitch (anything < 65)
'tempo (stretch 3)))
EXAMPLE 14: (plot ds2-trans1)
EXAMPLE 15: (fill-template transform ds2-trans2 ds2
:whatever (transform-if 'duration (anything > 245)
'pitch (transpose -24)))
EXAMPLE 16: (plot ds2-trans2)
EXAMPLE 17: (fill-template transform ds2-trans3 ds2
:whatever (transform-if 'pitch (anything > 77)
'channel (replace-all 2)))
EXAMPLE 18: (show-text ds2-trans3)
EXAMPLE 19: (fill-template transform ds2-trans4 ds2
:whatever (transform-if 'start-time (anything inside 900 1500)
'tempo (stretch 3)))
EXAMPLE 20: (plot ds2-trans4)
(transform-material material produce-intervals
&key (transformer #'transpose))
Returns a closure. When applied, one value from a transformation of the list or stockpile bound to MATERIAL is returned. The amount of the transformation is determined by the list, stockpile, or generator PRODUCE-INTERVALS. The type of transformation is determined by the keyword TRANSFORMER. By default, the transformation is a transposition, i.e. the interval produced by PRODUCE-INTERVALS is added to each value in MATERIAL (examples 1-3).
Any available transformer (see the Annotated Index for a listing of transformers) can be bound to the keyword TRANSFORMER al long as it only requires one input parameter (example 4).
A possible use of this generator would be to produce motivic transformations for the pitch parameter of a data section. Another possibility would be to produced a stockpile of transposed values.
Example 5 defines a section with a motivic transformation.
Example 6 is another example of motivic transformation.
To use a transformer such as EXPAND, which requires two arguments, is a bit messier. The transformer could be included in a lambda expression that binds one of the arguments to a fixed value and takes the other one from PRODUCE-INTERVALS.
Example 7 defines a chord as a stockpile.
Example 8 uses the stockpile from example 7. It is expanded a random amount varying between 25 and 200 percent. The middle-line of the expansion is equal to the lowest note in the chord therefore only the pitches above the lowest note are transformed.
EXAMPLE 1: (for-example (transform-material '(0 1 4) '(0 1 2 5)))
EXAMPLE 2: (for-example
(transform-material '(0 1 4)
(random-value -5 5)))
EXAMPLE 3: (for-example
(transform-material '(c3 d3 f3)
'(0 1 -2 3)))
EXAMPLE 4: (for-example
(transform-material '(1 2 5)
'(1 2 4 7 10)
:transformer #'stretch)
:number 21
:number-per-line 3)
EXAMPLE 5: (fill-template data-section section1 150 45 1
(transform-material '(c3 d3 f3)
(line 15 0 14))
mf 1 0)
EXAMPLE 6: (fill-template data-section section2 150 96 1
(transform-material '(c3 d3 f3)
(random-value -12 12))
mf 1 0)
EXAMPLE 7: (fill-template generate-stockpile chord1 1
(make-chord (walk e0 (series-value 1 11)) 12))
EXAMPLE 8: (fill-template data-section section3 1000 20
(random-value 0.5 2)
(transform-material
chord1
(random-value 25 200)
:transformer #'(lambda (x)
(expand x e0)))
mf 1 0)
(transform-or parameters-and-conditions tparameter transformer)
This transformer can be used with the WHATEVER parameter to transform sections. It will transform TPARAMETER with TRANSFORMER if one or more conditions are met.
For example, if the pitch is > c5 or the velocity is = p, the tempo can be stretched.
PARAMETERS-AND-CONDITIONS should be a list containing one or more pairs of parameters and conditions, e.g.
(list 'pitch (anything > c5) 'velocity (anything = p))
Parameters that can be examined in the list of PARAMETERS-AND-CONDITIONS are pitch, velocity, channel, duration, and start-time.
Parameters that can be transformed are pitch, velocity, channel, duration, tempo, and attack.
Parameters will only be transformed when one or more of the conditions have been met. It is not necessary that all conditions are met.
Example 1 will be used to demonstrate some of the possibilites.
Example 2 transposes pitches up an octave if they are > c5 or the velocity = p.
Example 3 will stretch the durations if the channel is 2, pitch is < 50, or the velocity is equal to ff.
When durations are stretched, as they were in example 3, this has no effect on the attack times. To change both attack times and durations of an event, transform the tempo (example 4).
Example 5 transforms the attack times without changing the durations.
Duration can also be used as one of the conditions to determine if a transformation should be made. Durations are expressed in milliseconds (the result of clock unit * rhythm value) (example 6).
Start-time can be used as a condition (example 7). Start-time is expressed in milliseconds. Start-times for an object can be found by selecting the object in the Objects dialog and selecting Edit.
If pitch is used as a parameter to be examined and it contains chords, e.g. made with MAKE-CHORD, the transformation will be applied if any pitch in the chord meets the condition (examples 8-9).
Related transformers are TRANSFORM-IF and TRANSFORM-OR. TRANSFORM-IF will only examine one parameter to determine if a transformation should be made. TRANSFORM-AND will examine more than one parameter and will make the transformation if all of the conditions has been met.
EXAMPLE 1: (fill-template data-section ds1 200 20
(rv .5 2) (rv 40 80) (rc '(p mf ff))
(rc '(1 2)))
EXAMPLE 2:
(fill-template transform ds1-trans1 ds1
:whatever (transform-or (list 'pitch (anything > c5)
'velocity (anything = p))
'pitch (transpose 12)))
EXAMPLE 3:
(fill-template transform ds1-trans2 ds1
:whatever (transform-or (list 'channel (anything = 2)
'pitch (anything < 50)
'velocity (anything = ff))
'duration (stretch 2)))
EXAMPLE 4:
(fill-template transform ds1-trans3 ds1
:whatever (transform-or (list 'channel (anything = 2)
'pitch (anything < 60)
'velocity (anything = ff))
'tempo (stretch 2)))
EXAMPLE 5:
(fill-template transform ds1-trans4 ds1
:whatever (transform-or (list 'pitch (anything < 50)
'velocity (anything = ff))
'attack (stretch 2)))
EXAMPLE 6:
(fill-template transform ds1-trans5 ds1
:whatever (transform-or (list 'pitch (anything > 70)
'duration (anything < 200))
'velocity (replace-all pp)))
EXAMPLE 7:
(fill-template transform ds1-trans5 ds1
:whatever (transform-or (list 'start-time
(anything < 1000)
'start-time
(anything > 3500))
'tempo
(stretch 3))
EXAMPLE 8: (fill-template data-section ds2 200 13
(rv .5 2) (make-chord (rv 40 80) 3)
mf 1)
EXAMPLE 9:
(fill-template transform ds2-trans1 ds2
:whatever (transform-or (list 'pitch (anything < 45)
'duration (anything > 350))
'velocity (replace-all ff)))
(transform-some transformer boundaries1 argument1 ... boundaries-N argument-N)
Returns a closure that can be used as a transformer. Only some of the values will be transformed.
The TRANSFORMER is applied to values between BOUNDARIES1 using ARGUMENT1 as the argument. There can be any number of boundary and parameter pairs.
Boundaries are expressed as a list. In example 1, values between (and including) 45 and 50 are transposed by 24. Other values are not transformed. TRANSFORMER is the name of a transformer defined in the AC Toolbox.
Example 2 specifies 2 boundary/argument pairs.
Example 3 uses the transformer STRETCH. Higher values are stretched more.
Some transformers use more than one argument. TRANSLATE is an example. It maps values between A and B to between LOW and HIGH. These arguments should be in a list (example 4). Values in the range 40-50 are translated to be between 20 and 50.
FUNNEL is an example of a transformer that has a list as input. To distinguish between a list of arguments (as in example 4), a list intended as one argument should be placed inside a list (examples 5-6).
TRANSFORM-SOME does not allow for time-varying parameter values.
For other possibilities for doing conditional transformations see TRANSFORM-IF, TRANSFORM-AND, and TRANSFORM-OR.
EXAMPLE 1: (show-transformation
(transform-some transpose (45 50) 24)
(from 40 60))
EXAMPLE 2: (show-transformation
(transform-some transpose
(40 45) -12 (50 57) 12)
(from 40 60))
EXAMPLE 3: (show-transformation
(transform-some stretch (5 10) 3)
(from 1 10))
EXAMPLE 4: (show-transformation
(transform-some translate
(40 50) (40 50 20 50))
(from 40 60))
EXAMPLE 5: (show-transformation
(funnel '(1 3 5 7 9))
'(1 2 3 4 5 6 7 8 9 10))
EXAMPLE 6: (show-transformation
(transform-some funnel
(40 50) ((40 44 48)))
(from 40 60))
(transform-stockpile stockpile transformer)
Returns a list made by transforming STOCKPILE. STOCKPILE may be a list or stockpile. TRANSFORMER should be a transformer (see the Annotated Index for a list of available transformers).
Example 1 transposes each value in STOCKPILE by an octave.
Example 2 mirrors each value around a center value of 60.
TRANSFORMER could also be a Lisp expression (see Help>Lisp>Your Own for a discussion of appropriate Lisp expressions for a transformer).
Simple transformations of a stockpile such as adding a number to every value (transpose) or multiplying each value (stretch), may be easier to do with cal (examples 3-4).
EXAMPLE 1: (print-result (transform-stockpile '(60 64 67)
(transpose 12)))
EXAMPLE 2: (print-result (transform-stockpile '(60 64 67)
(mirror 60)))
EXAMPLE 3: (print-result (cal '(60 64 67) + 12))
EXAMPLE 4: (print-result (cal '(1 1.5 2) * 2))
(transform/time to-transform transformer)
Returns a closure. TO-TRANSFORM should be a list, stockpile, generator, etc. that can be used to produce a value that is subsequently transformed.
TRANSFORMER is a transformer that may vary over time. Any regular toolbox transformer such as TRANSPOSE may be used (example 1).
This generator is particularly useful when dealing with streams. To control the pitch of the Wilhelmus in a stream using the Test Value dialog, use this generator for the pitch of a data stream (example 2).Enter the amount of transposition in the first Test Value dialog box.
EXAMPLE 1: (for-example
(transform/time (from 40 60) (transpose -12)))
EXAMPLE 2: (fill-template make-midi-data-stream stream1 100 1
(transform/time (extract 'pitch wilhelmus)
(transpose (tv 1))) f 1)
transformers
Transformers are functions which are used to modify objects or part of an object. Transformers could be used to transpose pitches, stretch tempi, add random deviation to a parameter, etc.
Transformers are primarily used with the Transform method. They can also be used for example with the generators TRANSFORM-MATERIAL and TRANSFORM/TIME.
Additional information about transformers can be found in the Annotated Index and in the Index.
transforming within time limits
Most transformers are applied to all values in an object or in a file (Csound or OSC).There are some possibilities to limit the transformation to be within certain time limits.
For a section, the transformers TRANSFORM-IF, TRANSFORM-AND, and TRANSFORM-OR allow transformations to be applied to events within some time range. The parameter START-TIME is used for this (examples 1-3). Time is expressed in milliseconds.
For a Csound file, the tool AT-CSOUND-TIME can be used in the Listener or an edit window. The arguments are parameter number, transformer, and one or more sets of start and end times (example 4). The transformer is applied to events starting within the specified start and end times. Time is expressed in seconds. The original file is not changed.
A similar tool is available for OSC files: AT-OSC-TIME. The arguments are the SynthDef argument to be transformed (expressed as a string), transformer, and one or more sets of start and end times. In example 5, the transformer is applied to events starting between time 2-4 seconds and between 7-8.5 seconds. The original file is not changed.
EXAMPLE 1: (fill-template data-section ds1 200 50
(rv .5 2) (rv 60 72) mf 1)
EXAMPLE 2: (fill-template transform ds1t ds1
:whatever
(transform-if 'start-time
(anything inside 3000 5000)
'pitch (transpose 12)))
EXAMPLE 3:
(fill-template transform ds1t2 ds1
:whatever (transform-or (list 'start-time
(anything inside 2000 5000)
'start-time
(anything > 10000))
'pitch (transpose 24)))
EXAMPLE 4: (at-csound-time 5 (transpose 5000) 2 4)
EXAMPLE 5: (at-osc-time "freq" (transpose 5000) 2 4 7 8.5)
(transition table &optional previous use-previous)
Returns a closure. When applied, one value from a transition table is returned. That value can be of any type.
A transition table indicates the probability of occurence of a value. A zero-order table looks at zero previous values. Higher order tables look at one, two, etc. previous values. Optional parameter PREVIOUS can be used to present a list of the previous values. The number of previous values should be the same as the order of the transition table. By a first or higher order table, if no value is bound to PREVIOUS, an entry of the table is chosen at random to get the process started.
A zero-order table should be made with the constructor MAKE-UNCONDITIONAL-TABLE. It can have an unlimited number of entries: (make-unconditional-table number probability number probability ...)
(make-unconditional-table 'a .1 'b .3 'c .6)
Probabilities can be any positive number and will be scaled to the appropriate range. Traditionally, probabilities are in the range 0-1 (example 1).
A higher-order table should be made with the constructor MAKE-CONDITIONAL-TABLE. It should contain a list as entry and a list of a possible next values with their probabilities.
Example 2 uses a first-order table (looking at one previous value).
If the previous value is A, there is a 30% chance that the next value will be B and a 70% chance that the next value will be C.
Example 3 uses an initial value (b) for PREVIOUS.
Normally the optional previous value is not included in the output of TRANSITION. Looking at the output of the previous example, you will see that the list which was created did not begin with B, it began with the value that could come after B. If you want to include the previous value(s) as the first value(s) in the output, bind the optional parameter use-previous to t (example 4).
EXAMPLE 1: (for-example
(transition
(make-unconditional-table
'a .1 'b .3 'c .6)))
EXAMPLE 2: (for-example
(transition
(make-conditional-table
'(a) '(b .3 c .7)
'(b) '(c 1)
'(c) '(a .5 b .5))))
EXAMPLE 3: (for-example
(transition
(make-conditional-table
'(a) '(b .3 c .7)
'(b) '(c 1)
'(c) '(a .5 b .5))
'(b)))
EXAMPLE 4: (for-example
(transition
(make-conditional-table
'(a) '(b .3 c .7)
'(b) '(c 1)
'(c) '(a .5 b .5))
'(b) t))
(translate a b low high &key clip chord round)
Returns a closure that can be used as a transformer. If the value to be transformed is between A and B, it is mapped to a value between LOW and HIGH (example 1).
If the value to be transformed is not between A and B, it is clipped to be either LOW or HIGH (example 2).
If the keyword CLIP is bound to nil, then the value that is outside the range A-B is not mapped at all. This would allow part of the input to be mapped while the rest is left untouched (example 3).
To find the minimum and maximum values of the object being transformed, use FIND-RANGE (example 4).
Example 5 defines section1. Example 6 will return the minimum and maximum values for the pitch parameter of section1. To get the minimum and maximum values for other parameters, bind the PARAMETER key word of find-range to that parameter. Pitch is bound to PARAMETER by default. Other possible parameters include DURATION and VELOCITY. See the help for FIND-RANGE for more information.
TRANSLATE will return a floating point result if either LOW or HIGH is a floating point number. To quantize that value, bind ROUND to a quantization unit (or to t to use the standard Lisp function ROUND) (examples 7-9).
A, B, LOW, and HIGH can vary over time.
To map the tempo of an object, use the transformer SCALE-TEMPO.
To map a multi-dimensional list (such as produced by a chaotic function), bind the key word CHORD to nil. Each of these multi-dimensional lists in an object should have the same length. A, B, LOW, and HIGH should have lists containing values for each dimension in the list (examples 10-12).
In example 8, -0.74 is the minimum value for the X dimension and -0.22 is the minimum value for the Y dimension. The minimum value of X will be translated to 40 and the minimum value of Y to 1.
EXAMPLE 1: (show-transformation (translate 60 72 40 80)
(from 60 72))
EXAMPLE 2: (show-transformation (translate 60 64 40 80)
(from 58 66))
EXAMPLE 3: (show-transformation (translate 60 64 40 80 :clip nil)
(from 58 66))
EXAMPLE 4: (print-result (find-range '(40 30 50 60 32)))
EXAMPLE 5: (fill-template data-section section1 100 50
1
(rv (make (rv 40 60)) 80)
mf 1)
EXAMPLE 6: (for-example (find-range section1))
EXAMPLE 7: (fill-template generate-stockpile random-pitch
40 (random-value 40.0 80))
EXAMPLE 8: (for-example (transform-stockpile random-pitch
(translate 40 80 70 90)))
EXAMPLE 9: (for-example (transform-stockpile random-pitch
(translate 40 80 70.0 90 :round .5)))
EXAMPLE 10: (fill-template generate-stockpile stockpile1 5
(henon 0.0 0.0 1.4 .3 1 :xy 1))
EXAMPLE 11: (for-example (find-range stockpile1 :chord nil))
EXAMPLE 12: (show-transformation
(translate '(-0.74 -0.22) '(1.08 0.32)
'(40 1) '(80 10) :chord nil)
stockpile1)
(transpose interval)
Returns a closure that adds a numerical INTERVAL to the value being transformed (example 1).
INTERVAL may vary over time using a generator, a list, a stockpile, etc. (example 2).
EXAMPLE 1: (show-transformation (transpose 12)
'(60 62 64 65))
EXAMPLE 2: (show-transformation (transpose (random-value -5 5))
'(60 60 60 60 60))
(triangle-choice stockpile)
Returns a closure. When applied, one value from STOCKPILE is chosen using a triangular distribution. A triangular distribution primarily returns values in the middle. It is used to produce index values for reading STOCKPILE. (examples 1-3).
STOCKPILE may be a list, stockpile, etc.
EXAMPLE 1: (for-example (triangle-choice '(a b c d e f g h i j)))
EXAMPLE 2: (plot (triangle-choice (from 1 100 :step 4)))
EXAMPLE 3: (make-histogram (triangle-choice (from 1 100)) :number 1000)
(triangle-value low high &key round)
Returns closure. When applied, one random value with a triangular distribution is returned (examples 1-2). The most likely result is in the middle of LOW and HIGH. The probability density is therefore triangular (example 3).
LOW and HIGH can change over time (examples 4-5).
To quantize the result with another unit, bind ROUND to a quantization unit (example 6).
TRV is the shortcut for TRIANGLE-VALUE (example 7).
EXAMPLE 1: (for-example (triangle-value 40 60))
EXAMPLE 2: (plot (triangle-value 1 100))
EXAMPLE 3: (make-histogram (triangle-value 1 100) :number 1000)
EXAMPLE 4: (plot (triangle-value (line 100 1 100) 100))
EXAMPLE 5: (plot (triangle-value 1 (line 100 100 20)))
EXAMPLE 6: (for-example (triangle-value 40.0 60 :round 0.5))
EXAMPLE 7: (plot (trv 1 100))
(trv low high &key round)
This is an abbreviation for TRIANGLE-VALUE. When applied, one random value with a triangular distribution is returned. The most likely result is in the middle between LOW and HIGH. The probability density is therefore triangular (example 1).
See the documentation for TRIANGLE-VALUE for more examples and information (example 2).
EXAMPLE 1: (make-histogram (trv 1 100) :number 1000)
EXAMPLE 2: (show-help 'triangle-value)
(tv number)
TV is a shortcut (abbreviation) for TEST-VALUE (example 1).
See the help for TEST-VALUE for more information (example 2).
EXAMPLE 1: (fill-template make-midi-data-stream test1 100 1
(random-value (tv 1) (tv 2))
ff 1)
EXAMPLE 2: (show-help 'test-value)
(unix command-string &optional print)
The COMMAND-STRING can contain a Unix command (examples 1-2).
By default, PRINT is true, causing the result of the Unix command to be printed to a window.
UNIX was originally implemented to allow the AC Toolbox to render binary osc files using SuperCollider (actually scsynth). Users familiar with Unix might find other uses for this tool.
Paths which include spaces should be enclosed in \" (example 3).
EXAMPLE 1: (unix "cal")
EXAMPLE 2: (unix "cd /Applications ; ls")
EXAMPLE 3: (unix "open \"/Applications/QuickTime Player.app\"")
(until-time seconds)
This tool can be used for the number specification of a data section, a note section, a controller data object, and a program data object.
It can also be used for the number specification when generating a Csound or OSC file.
UNTIL-TIME indicates that notes or events should be generated until a certain length of time in seconds has been reached (examples 1-2).
The resulting section always allows the last note to sound for its full duration. This could mean that the total length of the section is longer than SECONDS.
The number of notes produced in an section can be obtained with (from-number) (example 3).
UNTIL-TIME can be used with a note section (example 4).
When UNTIL-TIME is used for the number specification in Csound or with an OSC score, the START parameter must be a constant (example 5). Also the expression used to calculate durations should not use (FROM-NUMBER).
The resulting Csound score could be rendered with test csound.orc in Support/FileExamples.
UNTIL-TIME can be used in for an OSC score object (example 6).
The source code for the synthdef sine1 can be found in Support/FileExamples (test osc synthdefs.rtf or test osc synthdefs.scd).
SECONDS may be a number, generator, stockpile, or controller.
As a general rule of thumb, when UNTIL-TIME is used for number in an object specification, rhythm or duration values should not be calculated using FROM-NUMBER. This is because the only way to know if the time limit has been reached is to calculate durations or rhythms until the time is up.
UNTIL-TIME can be abbreviated as UT (example 7).
EXAMPLE 1: (fill-template data-section data-section1 200
(until-time 10) '(2 1)
(random-value c3 g#5)
(random-choice '(pp mf ff)) 1 0)
EXAMPLE 2: (show-info data-section1)
EXAMPLE 3: (fill-template data-section data-section2 200
(until-time 10) '(2 1)
(random-value c3 g#6)
(convert line-shape (from-number) pp ff) 1 0)
EXAMPLE 4: (fill-template note-section note-section1 200
(until-time 30) wilhelmus 0)
EXAMPLE 5: (fill-template csound-score-object score4
"f1 0 8193 10 1
f2 0 8193 20 2 1"
nil nil 1
(until-time 10) 1 0
(random-value .5 1)
(convert line-shape
(from-number) 0.01 0.3)
(random-value 220 880))
EXAMPLE 6: (fill-template osc-score-object osc-score1 (until-time 10)
"sine1" nil nil nil 1 0
"dur" (random-value 0.1 0.2)
"amp" 0.3
"freq" (series-value 415 466))
EXAMPLE 7: (fill-template data-section data-section3 200
(ut 10) (rv 1 3)
(rv c3 g#5)
(rc '(pp mf ff)) 1 0)
(ut seconds)
This tool is a shortcut for UNTIL-TIME.
It can be used in the number specification of a data section, note section, controller data object, program data object, csound score object, and an osc score object.
UT indicates that notes or events should be generated until a certain length of time in seconds has been reached (examples 1-2). Notes or events are allowed to finish to the total length of a section, etc. may be longer than the specified time. All attacks will occur within the specified time.
See the documentation for UNTIL-TIME for more examples (example 2).
EXAMPLE 1: (fill-template data-section data-section1 200
(ut 10) (rv 1 3)
(rv c3 g#5)
(rc '(pp mf ff)) 1 0)
EXAMPLE 2: (show-help 'until-time)
(value-pass value)
This tool is intended to be used as a filter for FILTER-AND, FILTER-IF, FILTER-OR, FILTER-STOCKPILE, etc.
It allows values which are = VALUE (examples 1-4).
Example 1 makes a section with values in 2 Midi channels. Example 2 will filter values in channel 1 and pass events in all other channels. Events in channel 1 with pitches between 65 and 75 will be passed. All other events in channel 1 are rejected.
VALUE can change over time.
EXAMPLE 1: (fill-template data-section test1 100 20
(rv 1 2) (rv 60 80) mf '(1 2))
EXAMPLE 2: (fill-template filter test1f test1
(other (filter-if 'channel (value-pass 1)
'pitch (band-pass 65 75)))
'whatever t)
EXAMPLE 3: (show-text test1)
EXAMPLE 4: (show-text test1f)
(value-reject value)
This tool is intended to be used as a filter for FILTER-AND, FILTER-IF, FILTER-OR, FILTER-STOCKPILE, etc.
It rejects values which are = to VALUE (examples 1-4).
Example 1 makes a section with values in 2 Midi channels. Example 2 will filter values in channel 1 and pass events in all other channels. Events in channel 1 with the pitch g4 will be rejected. All other events in channel 1 are passed.
VALUE can change over time.
EXAMPLE 1: (fill-template data-section test1 100 20
(rv 1 2) (rc '(c4 e4 g4 b4)) mf '(1 2))
EXAMPLE 2: (fill-template filter test1f test1
(other (filter-if 'channel (value-pass 1)
'pitch (value-reject g4)))
'whatever t)
EXAMPLE 3: (show-text test1)
EXAMPLE 4: (show-text test1f)
variant
A variant is a new object of the same type as some existing object. The same data specifications (input) used to create the original object are used to create the new object.
(vary object)
Returns a closure which, when applied, produces a variant of the object. A variant is an object made with the same input description as the object being varied.
It is particularly useful to generate communities by varying sections with this generator. Note that sections can also be varied without using this generator via the dialog for GENERATE SEQUENTIAL SECTION.
(walk starting-point next-step &optional lower upper)
Returns a closure that 'walks' around starting at number STARTING-POINT. NEXT-STEP determines the interval to be added. NEXT-STEP can be a number (example 1), sequence (example 2), stockpile, or function (example 3) that should provide a number. Each time a step is to be taken, a new value is produced from NEXT-STEP and added to the previous value.
Optional LOWER and UPPER boundaries can be provided (examples 4-8). If the result would be outside of the boundary, the sign of the value(s) to be added is reversed and the next result is the amount that would have been outside the boundary but placed inside. Two outside of the boundary would be 2 inside the boundary.
NEXT-STEP, LOWER, and UPPER may change over time. STARTING-POINT may use a generator to calculate its value.
EXAMPLE 1: (for-example (walk 48 2))
EXAMPLE 2: (for-example (walk 48 '(2 2 1 2 2 1)))
EXAMPLE 3: (for-example (walk 10 (random-value -5 5)))
EXAMPLE 4: (for-example (walk 1 1 1 5))
EXAMPLE 5: (for-example (walk 1 '(1 2) 1 5))
EXAMPLE 6: (for-example (walk 10 (random-value -5 5) 0 20))
EXAMPLE 7: (for-example
(walk (random-value 1 15) (random-value -5 5) 0 20))
EXAMPLE 8: (plot (walk 50 (random-value -5 5) 0 100))
(weibull-choice sequence s-parameter t-parameter)
Returns a closure. When applied, one element from the sequence is returned. The index for the returned element is chosen with a Weibull distribution (examples 1-2). See the help window for WEIBULL-VALUE for the characteristics of that distribution.
The S-PARAMETER controls the horizontal spread of the distribution. An appropriate value should be less than the length of the sequence.
The T-PARAMETER controls the type of distribution.
If 1, the distribution is exponential.
If 3.2, it is nearly Gaussian.
S-PARAMETER and T-PARAMETER may vary over time.
EXAMPLE 1: (for-example (weibull-choice '(a b c d e f g h i) 4 1))
EXAMPLE 2: (for-example (weibull-choice '(a b c d e f g h i) 4 3.2))
(weibull-value threshold s-parameter t-parameter
&optional upper-boundary round)
Returns a closure. When applied, one number from a Weibull distribution is returned. This number is >= THRESHOLD. If the optional UPPER-BOUNDARY is provided,the number is <= to it. The type of the THRESHOLD determines the type of the result. The S-PARAMETER scales the horizontal spread of the distribution. The T-PARAMETER influences the shape of the distribution (examples 1-5).
If T-PARAMETER = 1, the distribution is exponential.
if T-PARAMETER = 3.2, the distribution is nearly Gaussian.
THRESHOLD, S-PARAMETER, T-PARAMETER, and UPPER-BOUNDARY may vary over time.
To quantize the result with another unit, bind ROUND to a quantization unit (example 6). Note that ROUND is an optional parameter (not a key word) and therefore there must be a value specified for UPPER-BOUNDARY. If no UPPER-BOUNDARY is desired, nil can be entered for it.
EXAMPLE 1: (for-example (weibull-value 40 5 1))
EXAMPLE 2: (for-example (weibull-value 40.0 5 3.2))
EXAMPLE 3: (make-histogram (weibull-value 0 5 1)
:title "Weibull, T = 1")
EXAMPLE 4: (make-histogram (weibull-value 0 5 3.2)
:title "Weibull, T = 3.2")
EXAMPLE 5: (plot (weibull-value c3 5 3.2))
EXAMPLE 6: (for-example (weibull-value 50.0 5 1 nil 0.25))
(whole-tone start)
Returns a closure. When applied, a note number corresponding to the next value in a whole-tone scale is generated. The first value in the series is START. The series could continue indefinitely (examples 1-2).
EXAMPLE 1: (for-example (whole-tone 60) :number 8)
EXAMPLE 2: (for-example (whole-tone 55) :number 8)
(with constraint generator-or-stockpile &key stop)
Returns a closure. When applied, CONSTRAINT is used as a filter to see which values produced by GENERATOR-OR-STOCKPILE will be included. For example if CONTRAINT is a list, only values included in that list are allowed.
CONSTRAINT should be a list, stockpile, function, or constant. GENERATOR-OR-STOCKPILE should be a generator, stockpile, or list.
CONSTRAINT can be a list of values to be included (example 1).
GENERATOR-OR-STOCKPILE can be a generator, stockpile, or list. The next value will be returned (example 2).
CONSTRAINT can be a stockpile (examples 3-4).
CONSTRAINT can be a list or stockpile made with a tool. Example 5 includes integers in the range 60-72.
CONSTRAINT can be a function describing a condition for including results from the generator. The tool ANYTHING can be used to make such a function.
ANYTHING produces a function appropriate for use with WITH. The first argument should be a function. One or two additional arguments are accepted (example 6).
Example 7 allows values outside the range 60-70. Examples 8-9 demonstrate filtering a chaotic function to include values in the range 0-1.
Lisp programmers could also insert a lambda expression for CONSTRAINT. Example 10 specifies that values less than 60 should be accepted.
If the GENERATOR cannot produce allowed output after STOP number of attempts, an error message occurs and the process is cancelled. The default value for STOP is 100. If more attempts are desired, another value can be bound to STOP (examples 11-12).
If GENERATOR produces a list of values (such as in a chord), each member of the list will be examined. If any pass the test, the entire list (chord) is accepted.
In example 13 all chords include 60. In example 14, all chords will have a 60, 64, or 67. In example 15, all chords will have at least one value < 60.
The tool PITCH-CLASS returns a function which when used together with WITH, will only allow values from the specified pitch classes (example 16).
The tool PROBABILITY-FILTER allows values below various limits to pass based on a separate probability factor for each pair of limits (example 17).
Several tools used for the filter method are also available for use with WITH (examples 18-19):
(low-pass threshold)
(high-pass threshold)
(band-pass low high)
(band-reject low high)
(bank low1 high1 low2 high2 ...)
Filters can be manipulated with the logical tools CONSTRAINT-AND, CONSTRAINT-OR, and CONSTRAINT-NOT. CONSTRAINT-AND is true if the item passes all of the constraints. Example 20 allows values which are < 70 and belong to the pitch-class 0 (C). CONSTRAINT-OR is true if the item passes one or more of the constraints. CONSTRAINT-NOT negates the result of the filter function.
WITH is intended as a quick and easy way to impose limits on what is chosen. More complicated ways of filtering output can be achieving by using a filter method on an object.
See WITHOUT for a quick and easy way to exclude values (example 21).
To allow or block intervals see ALLOW-INTERVAL (example 22) or BLOCK-INTERVAL (example 23).
EXAMPLE 1: (for-example (with '(60 67) (random-value 60 72)))
EXAMPLE 2: (for-example (with '(60 64 67) '(60 61 62 63 64 65 65 67)))
EXAMPLE 3: (define stock1 (specify-stockpile 60 62 64 65 67 69 71 72))
EXAMPLE 4: (for-example (with stock1 (random-value 60 72)))
EXAMPLE 5: (for-example
(with (from 60 70)
(1/f-value 100 40 80)))
EXAMPLE 6: (for-example
(with (anything < 60)
(1/f-value 100 40 80)))
EXAMPLE 7: (plot
(with (anything outside 60 70)
(random-value 40 80)))
EXAMPLE 8: (plot (henon 0.0 0.0 1.4 .3 1)
:plot nil)
EXAMPLE 9: (plot (with (anything inside 0 1)
(henon 0.0 0.0 1.4 .3 1))
:plot nil)
EXAMPLE 10: (for-example
(with #'(lambda (x) (< x 60))
(1/f-value 100 40 80)))
EXAMPLE 11: (for-example (with '(1 2) (random-value 5 10)))
EXAMPLE 12: (for-example
(with '(1 2) (random-value 5 10) :stop 1000))
EXAMPLE 13: (for-example
(with 60 (make-chord (random-value 40 80) 4)))
EXAMPLE 14: (for-example
(with '(60 64 67) (make-chord (random-value 40 80) 4)))
EXAMPLE 15: (for-example
(with (anything < 60) (make-chord (random-value 40 80) 4)))
EXAMPLE 16: (for-example
(midi->notename
(with (pitch-class 0 1)
'(c2 c3 d3 f3 g#4 d#3 c#3))))
EXAMPLE 17: (make-histogram
(with (probability-filter 1 10 .8 11 50 .2 70 100 .5)
(random-value 1 100)))
EXAMPLE 18: (for-example
(with (low-pass 60)
(1/f-value 100 40 80)))
EXAMPLE 19: (plot (with (bank 1 10 40 50 90 100)
(random-value 1 100)))
EXAMPLE 20: (for-example
(with (constraint-and (anything < 70) (pitch-class 0))
'(40 48 60 64 72 80)))
EXAMPLE 21: (show-help 'without)
EXAMPLE 22: (show-help 'allow-interval)
EXAMPLE 23: (show-help 'block-interval)
(with-probability probability transformer)
This transformer limits the application of TRANSFORMER to a certain percentage of the events.
TRANSFORMER can be any available transformer. PROBABILITY is in the range 0-1. 0 is never, 1 is always.
Example 1 defines a section.
Example 2 transforms 30% of the pitches of that section.
WITH-PROBABILITY can also be used with TRANSFORM-IF, TRANSFORM-AND, and TRANSFORM-OR. In example 3, if pitch is < 67, velocity will be transformed 50% of the time.
The value for PROBABILITY can change over time (example 4).
With a small number of values, the percentages will probably not be too accurate.
EXAMPLE 1: (fill-template data-section ds1 200 13
1 (from 60 72) mf 1)
EXAMPLE 2: (fill-template transform ds1-trans1 ds1
:pitch (with-probability .3 (transpose 24)))
EXAMPLE 3: (fill-template transform ds1-trans2 ds1
:whatever
(transform-if 'pitch (anything < 67)
'velocity (with-probability .5 (tran + 30))))
EXAMPLE 4: (fill-template transform ds1-trans3 ds1
:pitch (with-probability (line 13 .2 .8) (transpose 24)))
(without value generator-or-stockpile &key stop)
Returns a closure. When applied, GENERATOR-OR-STOCKPILE is used to return an output without using certain values specified with VALUE.
VALUE should be a constant, list, stockpile, note-structure, or function. GENERATOR-OR-STOCKPILE should be a generator, stockpile, or list.
If GENERATOR-OR-STOCKPILE is a stockpile or list, it will return the next element from the stockpile or list each time a value is needed. If GENERATOR-OR-STOCKPILE is a generator, it is applied to produce an output.
If the output produced by generator-or-stockpile is equal to VALUE (if value is a constant or note-structure) or one of the elements within VALUE (if VALUE is a list or stockpile), then GENERATOR-OR-STOCKPILE keeps on producing output until an output is produced that is not equal to those excluded values.
VALUE can be a constant (example 1).
VALUE can be a list of values to be excluded (example 2).
GENERATOR-OR-STOCKPILE can be a list or stockpile in addition to a generator (example 3).
VALUE can be a stockpile (examples 4-5).
VALUE can be a note-structure (example 6).
VALUE can be a list or stockpile made with a tool (example 7).
VALUE can be a function describing a condition for excluding results from the generator. The tool ANYTHING can be used to make such a function.
ANYTHING produces a function appropriate for use with WITHOUT. The first argument should be a function. One or two additional arguments are accepted. If one additional argument is used, the generated value is compared to it (examples 8-9).
Example 10 does not allow values between (and including) 60 and 70.
Example 11 does not allow values outside the range 60-70.
Lisp programmers could also insert a lambda expression for VALUE. Example 12 specifies that no values less than 60 should be accepted.
The tool DUPLICATES will return a function that will disallow any value that has already occurred (example 13).
A problem will arise with the use of DUPLICATES if the generator is not able to produce a value that has not already occurred (example 14).
This could be addressed by binding a value to the keyword DIVERSITY. This value defines how many new values have to be chosen before all values are again available to be chosen (example 15).
Example 16 chooses groups of three unique values from all available values.
In example 17, DUPLICATES uses the key word PITCH-CLASS. Values in the same pitch-class will be considered duplicates. Three-note groups containing values that are not members of the same pitch-class will be made.
If the GENERATOR cannot produce output without using VALUE after STOP number of attempts, an error message occurs and the process is cancelled. The default value for STOP is 100. If more attempts are desired, another value can be bound to STOP (examples 18-19).
If GENERATOR produces a list of values (such as in a chord), each member of the list will be examined. If any fail the test, the entire list (chord) is rejected and a new one is generated (example 20).
The tool MORE-THAN will return a function that limits the number of times that certain values can be used.
The constraints are the number of times a value can be used, followed by the value that should be constrained. When that number of a certain value has been chosen, WITHOUT will not allow any more of that value to pass.
In example 21, no more than one 3 and two 1s will be allowed.
In example 22, the keyword :pitch-class is used at the end of the constraints, followed by a non-nil value. It that case, the pitch class of values will be compared to the pitch class of the constrained values. In example 19, no more than two Cs will be allowed. Note that c2 is 36, c3 is 48 and c4 is 60.
The tool PITCH-CLASS will return a function that will reject certain pitch-classes when used with WITHOUT (example 23).
Filters can be manipulated with the logical tools CONSTRAINT-AND, CONSTRAINT-OR, and CONSTRAINT-NOT. CONSTRAINT-AND is true if the item passes all of the constraints. Example 24 excludes values which are < 70 and belong to the pitch-class 0 (C). CONSTRAINT-OR is true if the item passes one or more of the constraints. CONSTRAINT-NOT negates the result of the filter function.
WITHOUT is intended as a quick and easy way to exclude one or more values from being chosen. More complicated ways of filtering output can be achieving by using a filter method on an object.
See WITH (example 25) for a quick and easy way to include values.
To allow or block intervals see ALLOW-INTERVAL (example 26) or BLOCK-INTERVAL (example 27).
EXAMPLE 1: (for-example (without 0 (random-value -3 3)))
EXAMPLE 2: (for-example (without '(66 68) (random-value 60 72)))
EXAMPLE 3: (for-example (without 64 (from 60 72)))
EXAMPLE 4: (define stock1 (specify-stockpile 66 68))
EXAMPLE 5: (for-example (without stock1 (random-value 60 72)))
EXAMPLE 6: (fill-template note-section test1 100 50
(without (a-note 2 67 64 1)
(random-choice wilhelmus)) 0)
EXAMPLE 7: (for-example
(without (from 60 70)
(random-value 40 80)))
EXAMPLE 8: (for-example
(without (anything < 60)
(random-value 40 80)))
EXAMPLE 9: (for-example
(without (anything > 60)
(random-value 40 80)))
EXAMPLE 10: (plot
(without (anything inside 60.0 70)
(random-value 40 80)))
EXAMPLE 11: (for-example
(without (anything outside 60.0 70)
(random-value 40 80)))
EXAMPLE 12: (for-example
(without #'(lambda (x) (< x 60))
(random-value 40 80)))
EXAMPLE 13: (for-example
(without (duplicates)
(random-value 1 20)))
EXAMPLE 14: (for-example
(without (duplicates)
(random-value 1 10)))
EXAMPLE 15: (for-example
(without (duplicates :diversity 10)
(random-value 1 10)))
EXAMPLE 16: (for-example
(without (duplicates :diversity 3)
(random-value 1 10))
:number 21 :number-per-line 3)
EXAMPLE 17: (for-example
(midi->notename
(without (duplicates :diversity 3 :pitch-class t)
(rc '(c3 c4 c5 d3 d4 d5 g3 g4 g5 a3 a4 b3 b4))))
:number 21 :number-per-line 3)
EXAMPLE 18: (for-example (without '(1 2) (random-value 1 2)))
EXAMPLE 19: (for-example
(without '(1 2) (random-value 1 2)
:stop 1000))
EXAMPLE 20: (for-example
(without 60 (make-chord (random-value 40 80) 4)))
EXAMPLE 21: (for-example
(without (more-than 1 3 2 1)
(random-value 1 3)))
EXAMPLE 22: (for-example
(without (more-than 2 c4 :pitch-class t)
(random-choice '(c2 c3 c4 g4 a4 b4))))
EXAMPLE 23: (for-example
(midi->notename
(without (pitch-class 0 1)
'(c2 c3 d3 f3 g#4 d#3 c#3))))
EXAMPLE 24: (for-example
(without (constraint-and (anything < 70) (pitch-class 0))
'(40 48 60 64 72 80)))
EXAMPLE 25: (show-help 'with)
EXAMPLE 26: (show-help 'allow-interval)
EXAMPLE 27: (show-help 'block-interval)
writing fomus files
FOMUS is a music notation formatting tool. It can convert data entered in its input format to data suitable for use by various music notation programs. In particular, data can be written to LilyPond format or to MusicXML which can be read by programs such as Sibelius and Finale.
The aim of FOMUS is to provide a more rational interpretation of pitch and rhythm data than may be obtained by importing a Midi file in a notation program. The result can nonetheless be considered a sketch.
The dialog 'Write Fomus File' (File>Write FOMUS File) converts the data from one section in the AC Toolbox to a file which can be processed by FOMUS. The output type (LilyPond or MusicXML) can be chosen. Various other options can be specified.
FOMUS needs to be installed separately. Any desired notation program (such as LilyPond) should also be installed.
RHYTHM
SPECIFY TEMPO
Tempo can be specified as beats per minute or milliseconds per beat. Using BPM is particularly useful if the clock time in a section is expressed using the BPM tool, e.g. (bpm 120).
'MS per beat' is the number of milliseconds in the AC Toolbox object which should be considered to be a beat. A beat is the denominator in the time signature. This should probably be related to the clock time specified for a section.
In most cases, it is probably useful to use the same tempo specification as in the section.
TIME SIGNATURE
The numerator and denominator for the time signature are entered in separate edit boxes. The AC Toolbox sets the rhythmic value which is equivalent to 1 beat to be 1/denominator. If the denominator is 4, a beat is notated as a quarter note (1/4). If the denominator is 8, a beat will be notated as an eighth note (1/8). This is can be changed in the FMS Settings by assigning a value to beat, e.g.:
beat = 1/8
MIN TUPLET DUR
The minimum duration (in beats) for a tuplet.
MAX TUPLET DUR
The maximum duration (in beats) for a tuplet.
MAXIMUM TUPLETS
The maximum number of notes that can be grouped as a tuplet. Higher or lower values may make more sense with particular rhythmic values. If the Quantization option is chosen, this value should be 2,3,5, or 7. If Quantization is not chosen, any value is possible.
MAX BEAT DIVISION
The maximum number of divisions of a beat. If the denominator of the time signature is 4, a maximum beat division of 4 would allow 16th notes. A maximum beat division of 8 allows 32nd notes, etc.
OPTIONS
ENABLE
The data entry panes for 'Instruments', 'Title', 'Author', and 'Settings' can individually be enabled for editing by checking the corresponding box. If the box is not checked, that information will not be used in the FOMUS file.
INSTRUMENTS
If no instruments are specified (which is the case when the Instruments box is not checked), FOMUS does what it thinks is appropriate which is two staves.
To enter data, the 'Instruments' check box should be checked.
Each Midi channel in a section can be mapped to a separate instrument in FOMUS. FOMUS has a number of predefined instruments such as piano, flute, cello, and tenor-trombone. More names and information can be found in the FOMUS documentation and code. In the FOMUS source code (which can downloaded separately), the file src/data/fomus.conf contains several instrument definitions. Instrument definitions can be discovered in the text printed by typing the following command line in the Terminal application:
fomus -S -fuselevel=3
Instrument prototypes are given specific names which are printed in the score. The specific names should be a string.
To enter an instrument for Midi channel 1 based on the FOMUS piano prototype, you could enter:
1 piano "Fender".
Additional instruments for other channels could follow:
1 flute "Recorder 1" 2 cello "Gamba"
TITLE
This is printed at the top of the score. The 'Title' check box must be checked for this value to be used.
AUTHOR
This is printed at the right-hand side of the top of the score. The 'Author' check box must be checked for this value to be used.
FMS SETTINGS
FOMUS allows other global settings than the ones available in this dialog. If additional global settings (which are written at the top of the file before the part data) are desired, they could be entered here. They should be entered just as you would if you were typing the FOMUS data in a text editor. Available settings may be discovered when perusing the documentation for FOMUS.
A more complete source of settings for FOMUS can be found be typing the following in the Terminal application:
fomus -S -fuselevel=3
This will list all possible settings, their default values, and a short description. To return less information, replace 3 in the above command line with a value from 0-2. 0 is for beginners. 2 for dedicated users. 3 is described as being for gurus.
One example of a FOMUS setting is:
acc-rule = measure
By default, the use of FOMUS in the AC Toolbox will print accidentals per note. The above setting would change this to print accidentals per measure.
Another FOMUS setting is to overrule the beat assignment. The AC Toolbox assigns one beat to be 1/denominator of the time signature. If the denominator is 4, this can be set to be an eighth note with:
beat = 1/8
Several different settings can be included in FMS Settings.
ALLOW
If 'QUARTERTONES' is checked, FOMUS will round floating-point pitch data to quartertone values. This is supported in both LilyPond and MusicXML though some MusicXML implementations may ignore this data.
If 'DYNAMICS' is checked, velocity values from the section are converted to dynamic markings. Dynamics are limited to the range ppp to fff. FOMUS will present the dynamic markings as it sees fit.
If 'SEPARATE VOICES' is checked, FOMUS may notate pitch values as two voices instead of one. The result of using this option may be surprising or not evident.
If 'QUANTIZATION' is checked, the section is quantized using the Pre-FOMUS Rhythm Quantizer of Luc Döbereiner. The original section is not modified. The quantized copy of the section is formatted.
The Pre-FOMUS Rhythm Quantizer aligns the events of a given structure on fractions of beats before it is written out and processed by FOMUS. For complex rhythmical sections, this will likely result in a more easily readable score. The possible fractions are determined by the setting MAXIMUM TUPLETS. The quantizer searches for the best fitting division for each beat. A beat can be divided into 2, 3, 4, 5, 6, 7 and 8 onsets. Faster passages will be grouped in chords. In case of a structure containing several channels, the events of each channel will be quantized independently.
When the quantizer is used, the setting for MAXIMUM TUPLETS should be 2, 3, 5, or 7. Any other value will cause an error message.
The Quantization option is separate from the quantization that FOMUS might do. The Quantization option indicates if the Pre-FOMUS Rhythmic Quantizer should be used or not. It has no influence on the quantization that may be performed by FOMUS.
If a stack overflow occurs during the quantization, the stack size can be increased using the tool ALLOW-LARGER-QUANTIZATION-STACK which can be evaluated in the Listener. If the stack size has been increased, the current size is printed in the Text Output window the next time that a FOMUS file is written. If no new stack size is printed, then it was not possible to allocate more memory for the stack.
When a large section is quantized, the calculations make take some time.
If events in the same channel have the same start time and were not made with generator make-chord, the Pre-FOMUS Rhythm Quantizer may not return accurate start times for those events. In that case, events may be returned in sequence rather than in parallel. Turn off the quantization option to deal with this issue.
UTILITIES
OPEN
To call FOMUS to process the fms file written by the AC Toolbox, 'FOMUS after Writing File' should be chosen.
If a XML file is produced, it can be opened in a specified program by checking 'XML File created by FOMUS'. If the output for FOMUS is LilyPond, this setting has no effect.
The application to open the xml file (if one is made) can be specified with 'Open XML File with'.
FOMUS OUTPUT FORMAT
The output format is either 'LilyPond' or'MusicXML'. FOMUS will produce a file with the extension .ly for LilyPond output or .xml for MusicXML output.
While the MusicXML format has been defined, various programs may not interpret this data in the same way. They may ignore certain parts of the specification.
The AC Toolbox converts section data to the FOMUS input format. The quality of the notation produced is the responsibility of FOMUS, LilyPond, and whatever other notation program is used. Adjusting the FOMUS parameters and turning the Quantizer on/off can result in significant differences in output.
UTILITIES
The most recent fms file in the current session can be edited by clicking on the 'Edit' button. If no file has been made or the file is no longer available, a file name can be chosen. Editing a fms file allows the user to insert additional, obscure FOMUS commands.
A FMS file that has already been produced or edited, can be rendered by clicking the 'Render' button. The fms file must be chosen.
AUTOMATICALLY GENERATE FILE NAMES
Instead of prompting the user for a file name each time a FOMUS file is written, a file name is generated using the section name, the date, and current time. The first time, the user will be asked which folder should be used to write the files.
RESET
Reset the choices for this dialog to their default values. These are the original values specified in the AC Toolbox, not the values that the user may have specified previously.
writing sound files
Some objects and expressions can be written to a sound file. The menu item 'Write Sound File' produces a dialog to facilitate this. The file can use either the AIFF or WAVE file format.
The output files are limited to 16-bit integers. The toolbox is not a particularly efficient way to create large sound files. It may be useful in making waveforms or control signals for other programs. It also provides an easy way to hear what some algorithms may sound like in the audio domain.
Shapes or masks will be converted to a number of values and scaled to be between a minimum and maximum value. The desired number of values, the minimum value, the maximum value, and the sampling rate for the file can be specified using a dialog produced by the options button. The minimum and maximum values can be in the range of -32768 to 32767 for a 16-bit file (examples 1-2).
Stockpiles, lists, and generators can also be written to a sound file. The values taken from these things are kept 'as is' therefore the user should ensure that the values are in the appropriate range (integers between -32768 and 32767) (example 3). The number of values and the sampling rate can be indicated in the options dialog. The values in the options dialog for minimum and maximum are used for shapes and masks, not for stockpiles, lists, or generators.
To slow down the rate of change for the sample values, GROUP can be used (examples 4-5).
Some generators, such as the chaotic ones, need to be scaled before being written to a sound file. TEST-GENERATOR can be used to discover possible minimum and maximum values. MAP/TIME can be used to scale the values (examples 6-7).
To choose from a stockpile of possible lists to write to the file, a stockpile of with lists can be made using MAKE-CHORD (example 8). A chord is a list of values. Note the specification of value for STOP in MAKE-CHORD. This value should be at least as large as the longest list.
SELECT-PATTERNS is a generator that will select a list and return all values in the list before selecting a new list. In example 9, one of the lists in MANY-LISTS is selected. Group indicates that entire selected list will be repeated a number of times before a new list is chosen.
To mix several processes together, ON-THE-FLY or its shortcut (OTF) can be used. In example 10, two processes are added together and then multiplied by .5.
EXAMPLE 1: (fill-template write-sf line-shape 4096)
EXAMPLE 2: (plot (load-sound-file :size 1))
EXAMPLE 3: (fill-template write-sf (rv -10000 10000)
(seconds->samples 2))
EXAMPLE 4: (fill-template write-sf
(group (rv -10000 10000) 100)
(seconds->samples 10))
EXAMPLE 5: (fill-template write-sf
(group (rv -10000 10000) (rv 100 1000))
(seconds->samples 10))
EXAMPLE 6: (print-result
(test-generator 100000
(henon 0.0 0.0 1.4 .3 10)))
EXAMPLE 7: (fill-template write-sf
(map/time (henon 0.0 0.0 1.4 .3 10)
-1.28 1.27 -30000 30000)
(seconds->samples 10))
EXAMPLE 8: (fill-template generate-stockpile many-lists 10
(make-chord (rv -10000 10000) (rv 100 1000)
:stop 1000))
EXAMPLE 9: (fill-template write-sf
(select-patterns
(group (rc many-lists) (rv 5 100)))
(seconds->samples 20))
EXAMPLE 10: (fill-template write-sf
(otf (select-patterns
(group (rc many-lists) (rv 5 100)))
+ (select-patterns
(group (rc many-lists) (rv 5 100)))
* .5)
(seconds->samples 20))
(xcv low high &key (curve 2) round)
This generator is a shortcut for EXPCURVE-VALUE.
When applied, it produces an exponentially-distributed value that is always in the range LOW to HIGH (examples 1-2).
CURVE controls the spread. When it is > 1, more lower values are produced (example 3).
When CURVE is in the range 0-1, more higher values are produced (examples 4-5).
See the documentation for EXPCURVE-VALUE for more examples and information (example 6).
EXAMPLE 1: (make-histogram (xcv 1 100))
EXAMPLE 2: (plot (xcv 40 80))
EXAMPLE 3: (make-histogram (xcv 1 100 :curve 10))
EXAMPLE 4: (make-histogram (xcv 1 100 :curve .5))
EXAMPLE 5: (make-histogram (xcv 1 100 :curve .1))
EXAMPLE 6: (show-help 'expcurve-value)
(xrv low high &key ratio round)
This generator is a shortcut for EXPRAND-VALUE.
When applied, it produces an exponentially-distributed value that is always in the range LOW to HIGH (examples 1-2).
RATIO controls the spread. Lower values increase the spread.
ROUND can be bound to a quantization unit.
See the documentation for EXPRAND-VALUE for more examples and information (example 3).
EXAMPLE 1: (make-histogram (xrv 1 100))
EXAMPLE 2: (plot (xrv 40 80))
EXAMPLE 3: (show-help 'exprand-value)