This functor defines re-usable musical segments. These segments are defined as sub-CSPs (extended scripts). They implement relatively specific musical ideas (e.g., a contrapuntual line, a specific motif, or a homophonic chord progression), but they support a number of arguments in order to make them flexible enough that they are interesting for re-use.
In addition, this functor defines constraints (and expressive constraint applicators) that shape musical segments, such as constraints on the texture.
Unfortunately, the documentation for many of the definitions here are not automatically extracted in the the HTML reference. Please check the source at ../Segments.oz for the documentation of these definitions.
Functor
Import
- FD
- FS
- Browser(browse:Browse)
- GUtils at "x-ozlib://anders/strasheela/source/GeneralUtils.ozf"
- LUtils at "x-ozlib://anders/strasheela/source/ListUtils.ozf"
- MUtils at "x-ozlib://anders/strasheela/source/MusicUtils.ozf"
- Score at "x-ozlib://anders/strasheela/source/ScoreCore.ozf"
- SMapping at "x-ozlib://anders/strasheela/source/ScoreMapping.ozf"
- Init at "x-ozlib://anders/strasheela/source/Init.ozf"
- Pattern at "x-ozlib://anders/strasheela/Pattern/Pattern.ozf"
- HS at "x-ozlib://anders/strasheela/HarmonisedScore/HarmonisedScore.ozf"
- Fenv at "x-ozlib://anders/strasheela/Fenv/Fenv.ozf"
- H at "x-ozlib://anders/strasheela/Heuristics/Heuristics.ozf"
- HCP at "source/HomophonicChordProgression.ozf"
- TSC at "source/TransformableSubscript.ozf"
- SegsOut at "source/Output.ozf"
Export
Define
fun{MakeParametersAccessor Accessor}
MakeMotifIndexNote is a constructor for HS.score.note which implicitly creates an index parameter.
*/
MakeMotifIndexNote = {Pattern.makeIndexConstructor HS.score.note [MotifIndexName]}
/** %% Expects a note that is part of a pattern motif (i.e. a note with a motif index parameter), and returns the motif number of this note (i.e. the index variable value). For example, all notes that are part of an instance of the motif which has been declared first have the motif index value 1 and so forth.
*/
fun {GetMotifIndexOfNote N} {Pattern.getMotifIndex N MotifIndexName} end
end
/** %% Returns accessor function expecting a list of items (notes) and returning list of variables returned by Accessor (unary function or method). Example
{MakeParametersAccessor getPitch}
fun{PitchContourAccessor Ns}
The function PitchContourAccessor is intended as a value for the argument motifAccessors of MakeCounterpoint_PatternMotifs and friends. Note that for this def of PitchContourAccessor the last direction in a motif spec is the direction from the last motif note to the note following the motif.
fun{PitchContourAccessor2 Ns}
Variant of PitchContourAccessor, where the first direction in a motif spec is the direction from the note preceeding a motif to the first motif note.
fun{MakeAkkords_Seq Args}
Same as MakeAkkords, but returns sequential container of akkords.
proc{MakeChordSlicesForm Args MyScore}
Returns extended script for musical section where each segment in the section expresses a single chord.
Args:
'segments' (required): list of textual score specs: each spec which "express" one chord.
'chords' (required): function returning list of chord objects (wrapped in function to protect variables).
'constructors' (required): constructors as expected by Score.make.
further args: handed to top-level sequential.
NB: Each segment must be sim, and sim items are specified at feat 1.
NB: List of segments and list of chords must be of the same length (shorter list of chords causes fail).
Note: this def is rather restricted in generality.. Alternatives are, e.g., HS.score.harmoniseScore.
fun{PatternedPhrase Args}
Generates extended script for creating a phrase consisting of multiple segments, and for applying pattern constraints on these segments. The resulting score topology is as follows, where the segmenents are form segments created by other extended scripts.
seq(segment+)
Args:
'constructors': constructor spec for the top-level sims and seq, format as expected by Score.make. Features should be 'sim' and 'seq'.
'pAccessor' (default GUtils.identity): unary function applied to each segment, returning a value for the argument pattern, e.g, a parameter value (FD int) or a score object (see below).
'pattern' (default proc {$ Xs} skip end): unary procedure expecting/constraining the list of values returned by 'pAccessor' for all segments.
All other top-level arguments are given to the top-level seq.
Args.segments:
tuple of segment specifications, where each segment specifications is a record of the following arguments. (In principle Args.segments can be a record, but then the temporal order of segments depends on the order of features in the record.)
'constructor': extended script (binary procedure) for creating the layer, commonly created with Score.defSubscript. Should return a score object (not a list of score objects).
All other arguments in Args.segments are given to this constructor.
The arguments of the returned extended script correspond to Args.
proc{PatternedSlices Args MyScore}
Extended script for creating a sequence of polyphonic form segments, resulting score topology, where the segmenents are form segments created by other extended scripts.
seq(sim(segment+)+)
The simultaneous containers can be though of as formal "slices", consisting of layers (the segmenents). Note that all slices are uniform in the sense that each slices consists of the same layers (i.e. the layers of each slices are created with the same constructors). However, depending on the flexibility of these layer constructors (e.g., their set of arguments) corresponding layers can also considerably differ across slices. Also, pattern constraints can be applied conveniently to lists of corresponding layers accross slices.
PatternedSlices can be used, for example, to create the score with the actual notes for a harmonic CSP. For example, each slices could express its own harmony (e.g., sim chord object).
Args:
'n': number of sims in the top-level seq (number of slices).
'constructors': constructor spec for the top-level sims and seq, format as expected by Score.make. Features should be 'sim' and 'seq'.
Args.layer:
record/tuple of layer specifications, where each layer specifications is a record of the following arguments. Each layer specification is used for creating all instances of this layer accross the slices.
iargs.constructor: extended script (binary procedure) for creating the layer, commonly created with Score.defSubscript. Should return a score object (not a list of score objects).
'pAccessor' (default GUtils.identity): unary function applied to each layer instance, returning a value for the argument pattern, e.g, a parameter value (FD int) or a score object (see below).
'pattern' (default proc {$ Xs} skip end): unary procedure expecting/constraining the list of values returned by 'pAccessor' for all instances of the present layer across slices.
In addition, (almost) all other constructor arguments are supported. These constructor arguments are supported in all formats introduced by Score.makeItems, such as each-args. However, it may be necessary to specify composite argument as each-args. For example, in order to specify an "rargs argument", the whole rargs record must be specified as each-args such as
unit(rargs: each # [unit() unit() ...] ...)
NB: arguments expected by Score.makeItems (n, constructor, handle, rule) *cannot* be handed to the layer constructors!
proc{Texture Dependency LeadingPart DependantParts Args}
Texture constraints restrict the independence between parts/voices. Dependence examples are homorhythm (simultaneous notes have the same start time and duration), heterorhythm (simultaneous notes have similar start times and durations), contrarhythm (simultaneous notes have different same start times or durations), homodirectional texture, various degrees of imitation (dependencies like, e.g., homorhythmic and homodirectional texture with a time offset) and many more possibilities. Texture constraints are inspired by Berry, Wallace (1987). Structural functions in music. Courier Dover Publications.
A texture constraint applies a Dependency (a constraint, see below) between certain notes in a LeadingPart (a container) and certain notes in a DependantParts (a container). DependantParts can be either a single container or a list of container; in the latter case a dependency is applied to multiple parts (e.g., for a fully homophonic texture apply the dependency Homophonic to one voice as LeadingPart and a list with the remaining voices as DependantParts).
A Dependency is a procedure with the following interface.
{MyDependency Note1 Note2 Args}
A Dependency defines a constraint between Note1, a note from the LeadingPart, and Note2, a note from the DependantPart. By default, Note1 and Note2 are simultaneous notes (see the argument offsetTime below for other cases). For example, homophony can be defined by constraining that the start times and durations of Note1 and Note2 are equal. Constraints that require more complex score contexts (e.g., the note succeeding Note1 in LeadingPart) are defined by accessing such contexts from the given notes (e.g., using methods like getTemporalSuccessor). The Dependency argument Args contains values for optional arguments in the Args argument of a texture constraint (see below). Various dependencies are predefined (e.g., Homophonic, and HomoDirectional), and users can freely define their own.
The argument Args of Texture supports the following optional arguments.
offsetTime (default 0): Using this argument, various forms of imitation can be defined. The dependency constraint is applied to a note in DependantPart that starts the specified amount of offset later than the respective note in LeadingPart.
Remember that negative offset times are not allowed (if you would need them, simply swap the arguments LeadingPart and DependantPart).
In case DependantParts is a list of containers, then a list of individual offset times can be given.
timeRange (default nil): Specifies the time frames of the affected notes in LeadingPart. For example, the time frame [0#4 8#12] affects the notes that are in the time frames 0-4 and 8-12 in LeadingPart and their simultaneous notes in DependantPart (if offsetTime is the default). timeRange is based on SMapping.forTimeRange, and supports all its time frame notations. The arguments timeRange and indexRange exclude each other (only one must be given).
indexRange (default nil): Specifies the positions of the affected notes in LeadingPart. For example, the numeric range [1#3 5#6] affects the notes at position 1-3 and 5-6 in LeadingPart and their simultaneous notes in DependantPart (if offsetTime is the default). indexRange is based on SMapping.forNumericRange, and supports all its index integers notations. The arguments timeRange and indexRange exclude each other (only one must be given).
Note that further arguments can be provided, which are then forwarded to the dependency constraints. For example, a transposition dependency may use a transposition argument which would then be included in the Args record for Texture.
In case DependantParts is a list of containers, then a list of individual values can be given to any argument.
proc{TextureProgression_Index Specs}
Multiple applications of Texture can be programmed slightly more concisely and better readable with TextureProgression. The following two code examples are equivalent (first a version using Texture then using TextureProgression).
Imitation at the beginning (e.g., Voice2 at time 2 imitates 1st 5 notes of Voice1)
{Texture MyDependency Voice1 [Voice2 Voice3 Voice1]
unit(indexRange: 1#5
offsetTime: [2 4 6])}
Homophonic section
{Texture Homophonic Voice1 [Voice2 Voice3]
unit(indexRange: 9#12)}
{TextureProgression_Index
[%% Imitation at the beginning (e.g., Voice2 at time 2 imitates 1st 5 notes of Voice1)
(1#5) # unit(MyDependency Voice1 [Voice2 Voice3 Voice1]
offsetTime: [2 4 6])
Homophonic section
(8#12) # unit(Homophonic Voice1 [Voice2 Voice3])
]}
proc{TextureProgression_Time Specs}
Same as TextureProgression_Index, but with leading time values instead of indices.
proc{Homophonic N1 N2 Args}
[Dependency for Texture] Results in a homophonic texture.
Note that a truely homophonic texture only results for the default offset time 0, otherwise a time-shifted "homophonic" imitation results.
proc{HeuristicHomophonic N1 N2 Args}
proc{HierarchicHomophonic N1 N2 Args}
[Dependency for Texture] Generalised (?) version of "Orjan Sandred's notion of hierarchic rhythm.
If the start time of N1 occurs between start and end of N2 including, then the start time of these notes are equal. In other words, the notes of N2's voice may be shorter than those of N1's voice, but whenever a longer note starts in the latter voice there also starts a note in the former.
proc{HomoDirectional N1A N2A Args}
[Dependency for Texture] Results in a homo-directional texture (i.e. parallel pitch contours).
End