Index
HarmonisedScore
DB
HS_Score
Rules
DBs
HS_Distro
HS_Out
HS
Schoenberg
Default
Jazz
Partch
Johnston
Harrison
Chalmers
Catler
ArithmeticalSeriesChords
Functor defines data abstraction for a user-defined database of settings like chord and scale structures which are used by the contribution HarmonisedScore. See SetDB of further details.

Functor

Import

Export

Define

proc{SetDB NewDB}
Sets the database which is used by the HarmonisedScore contribution (e.g., its music representation and rules).
The syntax of the database is
<DB> ==:: unit([chordDB:<PCGroupDB>]
[scaleDB:<PCGroupDB>]
[intervalDB:<IntervalDB>]
[pitchesPerOctave:<PitchesPerOctave>]
[accidentalOffset:<AccidentalOffset>]
[octaveDomain:<OctaveDomain>]
[generators:<Generators>]
[generatorFactors:<generatorFactors>]
[generatorFactorsOffset:<GeneratorFactorsOffset>]
[temperament:<Temperament>])
<PCGroupDB> ==:: unit(<PCGroupEntry>+)
<PCGroupEntry> ==:: unit(pitchClasses:<IntList>
roots:<IntList>
[<FeatureValuePair>*]
[comment:<Value>])
<IntervalDB> ==:: unit([<FeatureValuePair>+]
[comment:<Value>])
<PitchesPerOctave> ==:: <Int>
<AccidentalOffset> ==:: <Int>
<OctaveDomain> ==:: <Int>#<Int>

All features of the DB and also of some sub-DBs (e.g. of the chordDB and scaleDB) are optional (as marked by square brackets). Missing features are set to the features of the default database (HS.dbs.default). However, in case PitchesPerOctave \= 12, then the following features are mandatory: chordDB, scaleDB and intervalDB.
Note the above doc is unfinished: for further details read the doc of the aux accessors (available in the source file contributions/anders/HarmonisedScore/source/Database.oz).

'comment' feature of database entries: is either a single value (usually an atom) or a record.
Naming database entries: either by an atom given to the 'comment' feature of a database, or an atom given to the 'name' feature of the record at the 'comment' feature, or -- for multiple alternative names -- a list of atoms given to the 'name' feature of the record at the 'comment' feature.

The optional settings 'generators', 'generatorFactors', 'generatorFactorsOffset' and 'temperament' are for bookkeeping when using regular temperaments.

TODO: write a better doc..


fun{GetEditChordDB }
fun{GetInternalChordDB }
fun{GetEditScaleDB }
fun{GetInternalScaleDB }
fun{GetEditIntervalDB }
fun{GetInternalIntervalDB }
fun{GetPitchesPerOctave }
fun{GetPitchUnit }
fun{GetAccidentalOffset }
fun{GetOctaveDomain }
fun{GetGenerators }
fun{GetGeneratorFactors }
fun{GetGeneratorFactorsOffset }
fun{GetTemperament }
fun{MakePitchClassFDInt }
Return a FD integer representing a pitch class (range defined by PitchesPerOctave).


fun{MakeOctaveFDInt }
Return a FD integer representing an octave (range OctaveDomain).


fun{MakeAccidentalFDInt }
Return a FD integer representing an accidental (range 0#AccidentalOffset*2).


fun{MakeScaleDegreeFDInt }
Returns a FD integer representing a scale degree (range 1#MaxScaleLength).


fun{MakeChordDegreeFDInt }
Returns a FD integer representing a chord degree (range 1#MaxChordLength).


fun{MakeFullDB Args}
Returns a full database specification that can be given as argument to HS.db.setDB.

Args:

'chords'/'scales'/'intervals' (each tuple of records, default of each is unit): chord/scale/interval database entries that are appended before the entries defined internally in this functor. There features pitchClasses, essentialPitchClasses and roots can be declared as integers (depends on pitchesPerOctave), ratios (pairs of ints) or symbolic note names (as supported by arg symbolToPc, see below) .

'chordFeatures'/'scaleFeatures'/'intervalFeatures' (each list of atoms, default of each is nil): additional features required in database entries (example: essentialPitchClasses). Database entries that do not contain all the required features are removed from the output (reported at standard out).

'symbolToPc' (default HS.pc): function that expects an atom (a symbolic pitch name) and returns the corresponding pitch class.

'pitchesPerOctave' (default 12)
'accidentalOffset' (default 2)
'octaveDomain' (default 0#9)



proc{RatiosInDBEntryToPCs MyDBEntry KeysPerOctave Result}
Processes an entry for a HS database (e.g. for a chord database). HS depends on pitches as keynumbers and pitch classes (all represented by integers or FD ints), both depending on KeysPerOctave. RatiosInDBEntryToPCs2, on the other hand, permits also ratios (floats or fractions specs) which are transformed and rounded to the nearest pitch class (a ratio representing an interval exceeding an octave is transformed into an interval within an octave).
MyDBEntry is a record with arbitrary features. Each feature value is either an interger, a list of integers, a ratio spec (either a float or a fraction spec in the form <Int>#<Int>), or a list of ratio specs. The output contains each integer/lists of integers unchanged but substitutes each ratio/list of ratios by the nearest pitch class interval (an integer), depending on KeysPerOctave (an integer).
Additionally, a comment feature in MyDBEntry with arbitrary value is permitted. The returned record has always a comment feature with a record as value. The explanation of the comment in the return value is a bit complicated and depends on MyDBEntry. For features in MyDBEntry with a ratio, collect in comment the ratio, its pitch class plus the ji_error (i.e. the difference between the JI ratio and the pitch class it is mapped to), for other features in Test keep the orig value. In case MyDBEntry contains a feature comment as well, this value is preserved: in case MyDBEntry.comment is a record as well, its features are added to the comment record of the result. However, in case MyDBEntry.comment contains a feature 'comment' with the same feature as a feature in MyDBEntry itself, then the feature of MyDBEntry.comment is preferred. See the test file for examples.
Because the comment feature of the returned DB entry is changed, the function WasRatiosDBEntry recognises a DB entry processed by RatiosInDBEntryToPCs2.

NB: in HS.db, an OctaveDomain is also specified as <Int>#<Int>, but must not be mixed up with a fraction spec.


BUG: reported error signs not correct -- check JI signs (you know what to expect..)


proc{RatiosInDBEntryToPCs2 MyDBEntry KeysPerOctave Temperament Args Result}
RatiosInDBEntryToPCs2 is a generalised version of RatiosInDBEntryToPCs that additionally expects Temperament, a sorted tuple of integers expressing a regular temperament (as explected by RatioToRegularTemperamentPC). If Temperament is unit (i.e. an empty tuple), then it defaults to an equal temperament depending on KeysPerOctave (which is the behaviour of RatiosInDBEntryToPCs).

Args:
'minOccurrences': the minimum number an interval needs to occur in order to be taken into account.


fun{WasRatiosDBEntry MyDBEntry}
Returns true if MyDBEntry was processed by RatiosInDBEntryToPCs2.


fun{Pc2Ratios PC IntervalDB}
Returns a list of all ratios which match PC (an int) in IntervalDB (given in its edit form) which was defined using ratios (e.g. {HS.dbs.partch.getIntervals {HS.db.getPitchesPerOctave}}).
A ratio consists in two integers and has the form Nom#Denom. If no entry in the database matches PC or non matching is defined as ratio, then nil is returned.

Two examples:
{Pc2Ratios 9 {HS.dbs.partch.getIntervals 12}}
{Pc2Ratios 53 {HS.dbs.partch.getIntervals 72}}

NB: Pc2Ratios is a deterministic function and no constraint.


fun{GetChordIndex MyName}
Convenience functions. ChordIndex expects a name (atom) for a chord and returns the corresponding index. This name is either the value stored under the edit database feature 'comment', or the value of a feature 'name' of a record stored under the edit database feature 'comment'. If no database entry with this name is defined, then nil is returned.
ScaleIndex and IntervalIndex do the same for scales and intervals.


fun{GetScaleIndex MyName}
fun{GetIntervalIndex MyName}
fun{GetComment X}
Expects a chord, scale or interval object and returns the comment value in its internal database format.
Blocks until the index parameter is determined.


fun{GetName X}
Returns the name of a chord, scale or interval specified in its database entry (a VS, usually an atom). The name is a list of atoms (its a list because there are sometimes multiple name alternatives). Returns nil if no name was found.
Blocks until the index parameter is determined.

The name is often specified as an atom at the 'comment' feature of a database entry. Alternatively, the entry defines a record at the 'comment' feature, and then the name is and atom at the feature 'name' in this subrecord, or a list of atoms at the feature 'name' (for specifying multiple alternative names).


fun{GetAllNames DB}
Returns a list of list of all the names (usually atoms) of the entries in the database DB (a database in the format of edit DBs, e.g., {HS.db.getEditScaleDB}). A list of lists is returned because some database entries have multiple names. Note that some entries have no names at all.

Example: how to return a list of all scale names of the named scales in the current database (only their first name).
{LUtils.mappend {HS.db.getAllNames {HS.db.getEditScaleDB}}
fun {$ Ns}
case Ns of nil then nil
else [Ns.1]
end
end}


fun{GetUntransposedRatios X}
Returns the ratios specs by which X (chord or scale object) is declared in the database. If X was declared by pitch classes instead and thus no ratios are available then nil is returned.


fun{GetUntransposedRootRatio X}
Returns the ratio specs by which the roots of X (chord or scale object) are declared in the database. If the root was declared by a pitch class instead and thus no ratio is available then nil is returned.


fun{GetUntransposedRootRatio_Float X}
Returns the frequency ratio of the [first] root of X (chord or scale object) as a float. For example, if the ratio 1#1 or the pitch class 0 is declared as root, then 1.0 is returned; it it is 3#2 then 1.5 is returned.

NB: blocks until root and transposition of X are determined.


fun{MakeRegularTemperament Generators GeneratorFactors Args}
Returns sorted list of pitch classes (ints) that constitute a regular temperament, i.e. a temperament whose pitches are generated by a repeated transposition with the same interval(s) (http://en.wikipedia.org/wiki/Regular_temperament). Generators (list of integers) is the list of transposition intervals, the unit of measurement depends on the Arg pitchesPerOctave (e.g., if pitchesPerOctave is 1200, then the Generators and all temperament pitches are measured in cent). GeneratorFactors is a specification that denotes the generator transpositions. For each element in Generator, GeneratorFactors contains a pair of integers MinTranposition#MaxTransposition. For example, the generator factor ~1#2 indicates that the corresponding generator is transposed 1 time downwards and 2 times upwards (i.e. together with the start pitch 4 pitches are generated).
The octave interval is always implicitly added as generator to a regular temperament: the result of MakeRegularTemperament is a list of pitch classes (i.e. generated pitches that "fell outside" the octave are automatically "folded back" into the octave).

Args:
'pitchesPerOctave' (default {HS.db.getPitchesPerOctave}): denotes the unit of measurement for Generators and the resulting pitch classes of the temperament.
'generatorFactorsOffset' (default 0): this argument is intended to avoid negative generator factors, in case generator factors are variables (e.g., if using the class HS.score.regularTemperamentMixinForNote). For example, if generatorFactorsOffset is 100, then the generator factors spec 99#102 indicates that the corresponding generator is transposed 1 time downwards and 2 times upwards.
'transposition' (default 0): pitch class interval for transposing the whole temperament. With the default value 0, the temperament's "origin" is the pitch class 0 (always C).

See examples/RegularTemperaments.oz for usage examples.


fun{AllTemperamentIntervals Temperament Args}
Expects a regular temperament spec Temperament (tuple of ints) and returns a tuple that contains all intervals contained in this temperament (remember that Temperament contains all intervals available from PC 0, but in addition some intervals may only be available between other pitches).

Args:
'minOccurrences' (default 1): the minimum number an interval needs to occur in order to be included.
'pitchesPerOctave' (default {HS.db.getPitchesPerOctave}): the pitches per octave (i.e., pitch unit).
'reportOccurrences' (default false): if true, AllTemperamentIntervals returns a completely different format that also reports the number of occurances of each interval in the temperament. AllTemperamentIntervals returns a record where the features are the intervals and the values are the number of occurrences.


fun{RatioToRegularTemperamentPC Ratio Args}
Expects a Ratio (float or pair of ints) and returns the corresponding tempered pitch class (an int), i.e. the pitch class that approximates the ratio closest in the temperament. Ratio is either pair of integers Nominator#Denomitator or a float that corresponds to the value of the ratio.

Args:
'temperament' (default {HS.db.getTemperament}): a tuplet of pitch classes (ints), sorted in ascending order, which constitute the temperament.
'pitchesPerOctave' (default {HS.db.getPitchesPerOctave}): denotes the unit of measurement for the pitch classes of the temperament.
'showError' (Boolean, default false): if true, RatioToRegularTemperamentPC returns tuple PC#Error, where Error is the difference between the JI interval and the returned tempered interval (unit of measurement depends on Arg pitchesPerOctave).
'minOccurrences': the minimum number an interval needs to occur in order to be taken into account.

See examples/RegularTemperaments.oz for usage examples.


End