NAME
Music::Canon - routines for musical canon construction
SYNOPSIS
use Music::Canon ();
my $mc = Music::Canon->new;
# options affecting all the *_map routines
$mc->set_contrary(1);
$mc->set_retrograde(1);
$mc->set_transpose(12); # by semitones
$mc->set_transpose(q{c'}); # or "to" a lilypond note
# 1:1 semitone mapping
my @new_phrase = $mc->exact_map(qw/0 7 4 0 -1 0/);
$mc->exact_map_reset;
# trickier is the so-called modal mapping;
# default is Major to Major
@new_phrase = $mc->modal_map(qw/0 7 4 0 -1 0/);
$mc->modal_map_reset;
# or instead modal mapping by scale name (via Music::Scales)
$mc->set_scale_intervals( 'input', 'minor' );
$mc->set_scale_intervals( 'output', 'dorian' );
@new_phrase = $mc->modal_map(qw/0 7 4 0 -1 0/);
See also canonical
of the App::MusicTools module for a command line tool interface to this code, and the eg/
and t/
directories of this distribution for more example code.
DESCRIPTION
Musical canons involve horizontal lines of music (often called voices) that are combined with other canon or free counterpoint voices to produce harmony. This module assists with the creation of new voices via *_map
methods that transform pitches according to various rules. Chords could also be transformed via the *_map
functions by passing the pitches of the chord to the *_map
method, then forming a new chord from the results.
Whether the output is usable is left to the composer. Harmony can be created by careful selection of the input material and the mapping settings, or perhaps by adding a free counterpoint voice to support the canon voices. Analyzing the results with Music::Tension may help search for suitable material.
The methods of this module at present suit crab canon, as those lines are relatively easy to calculate. Other forms of canon would ideally require a counterpoint module, which has not yet been written. The modal_map method also suits the calculation of new voices of a fugue, for example converting the subject to the dominant.
Knowledge of canon will doubtless help any user of this module; the "SEE ALSO" section lists resources for learning these.
METHODS
Methods may die or croak under various conditions. new would be a good one to start with, then one of the *_map
functions to transform the list of pitches into new material.
Most methods, notably the *_map
methods, operate only on pitch numbers. Some methods also accept lilypond note names (via Music::LilyPondUtil). Use notes2pitches of Music::LilyPondUtil to convert notes to pitches suitable for passing to a *_map
function. Otherwise, MIDI pitch numbers could easily be fed to the mapping methods, or objects that have a pitch method.
- exact_map phrase
-
One-to-one semitone mapping from the input phrase to the returned list. phrase may be a list or an array reference, and may contain raw pitch numbers, objects that support a pitch method, or other data that will be passed through unchanged.
Affected by various settings, notably set_contrary, set_retrograde, and set_transpose.
Be sure to call exact_map_reset when done converting a phrase, or disable the keep_state option of new and then pass the phrase in a single call to exact_map.
- exact_map_reset
-
Resets current state of the exact_map method. Not necessary if keep_state option of new disabled, and entire phrases passed in one go to exact_map.
Returns the Music::Canon object, so can be chained with other method calls.
- get_contrary
-
Returns the current contrary setting (boolean).
- get_modal_chrome
-
Returns current modal_map chrome weighting (troolean).
- get_modal_pitches
-
Returns the current modal input and output layer starting pitches used by modal_map. These will be undefined if unset, or might have values leftover from some previous conversion, unless reset via reset_modal_pitches.
- get_retrograde
-
Returns the current retrograde setting (boolean). Retrograde is a fancy way to indicate that the output list be reversed.
- get_scale_intervals layer
-
Returns the scale intervals for the indicated layer (
input
oroutput
), or throws an exception if these are unset. The intervals are returned as a list of two array references, the first for the scale ascending, the second for the scale descending.Note that descending scale intervals are noted from the highest note down.
- get_transpose
-
Returns the current transpose setting (integer of semitones or lilypond note name, depending on what was previously set).
- modal_map phrase
-
Modal mapping of the pitches in phrase from an arbitrary input mode to an arbitrary output mode, as set by set_scale_intervals, or the Major to Major scales by default. Returns a list, or throws an exception if a pitch cannot be converted. phrase may be a list or an array reference, and may contain raw pitch numbers, objects that support a pitch method, or other data that will be passed through unchanged.
Configuring the starting pitches via set_modal_pitches is a necessity if the phrase starts on a scale degree that is not the root or tonic of the mode involved. That is, a phrase that begins on the note E will create a mapping around E-major by default; if a mapping around C- Major (at MIDI pitch 60) is intended, this must be set in advance:
# by pitch number $mc->set_modal_pitches( 60, 60 ); $mc->modal_map(qw/64 .../); # or the equivalent via lilypond note names $mc->set_modal_pitches(qw/c' c'/); $mc->modal_map(qw/e' .../);
NOTE modal_map is somewhat experimental, so likely has edge cases or bugs unknown to me, or may change without notice as I puzzle through the mapping logic. Consult the tests under the module distribution
t/
directory for what cases are covered. It is also relatively unexplored, for example mapping between exotic scales or Forte Numbers.The algorithm operates by converting the intervals between the notes into diatonic steps via the input mode, then replicates that many steps in the output mode, followed by any necessary chromatic adjustments. The initial starting pitches (derived from the input phrase and transpose setting, or via pitches set via the set_modal_pitches method) form the point of linkage between the two scales or really any arbitrary interval sequences.
Transposition (via set_transpose) will influence the output linking pitch, unless that value was already set via a prior conversion or set_modal_pitches call.
An example may help illustrate this function. Assuming Major to Major conversion, contrary motion, and a transposition by an octave (12 semitones), the software will convert pitches as shown in this chart (the "linking point" is from 0 in the input scale to 12 in the output scale):
0 1 2 3 4 5 6 7 8 9 10 11 12 In | C | c# | D | d# | E | F | f# | G | g# | A | a# | B | C' | Out | C' | x | B | a# | A | G | f# | F | x | E | d# | D | C | 12 11 10 9 7 6 5 4 3 2 0
Assuming an input phrase of
C G c#
, the output phrase would beC' F
and then an exception would be thrown, as there is no way to convertc#
using this modal mapping and transposition. Other mappings and transpositions will have between zero to several notes that cannot be converted. Theeg/conversion-charts
file of this module's distribution contains more such charts, as also can be generated by theeg/brutecanon
utility.How to map non-diatonic notes is another concern; the above chart shows two
x
for notes that cannot be converted. Depending on the mapping, there might be zero, one, or several possible choices for a given chromatic. Considerc#
of C Major to various entry points of the sakura scaleG# A# B D# E
:C Major | C | c# | D | ------------------------------------------------------------ Sakura @ G# | G# | a | A# | - one choice Sakura @ A# | A# | x | B | - throw exception Sakura @ B | B | ? | D# | - (c, c#, d)
The chrome_weight parameter to new controls the multiple choice situation. The default setting of
0
results inc#
, as that value is halfway betweenB
andD
, just as the input scale chromatic is halfway betweenC
andD
. Otherwise, with a negative chrome_weight,c
is favored, or for a positive chrome_weight,d
. Test cases are advised to confirm that the resulting chromatics are appropriate, though this should only be necessary if the output scale has intervals greater than two (e.g. hungarian minor, or any of the pentatonic scales, etc).modal_map is affected by various settings, notably set_contrary, set_modal_pitches, set_retrograde, set_scale_intervals, and set_transpose.
Be sure to call modal_map_reset when done converting a phrase. reset_modal_pitches may also be necessary to clear prior scale linking points.
- modal_map_reset
-
Resets the state variables associated with modal_map, with the exception of the pitches set by the set_modal_pitches call (or automatically from the input phrase), which are not reset by this method (use the reset_modal_pitches method to accomplish that).
Returns the Music::Canon object, so can be chained with other method calls.
- new
-
Constructor. Accepts a number of options, the useful or safe of which are listed here.
chrome_weight - sets the chrome_weight troolean. Zero by default.
chrome_weight controls how chromatics between output intervals greater than two semitones are handled in modal_map; if this parameter is negative, the literal chromatic step from the input scale will be used from the previous pitch (bottom up), if positive the literal chromatic step will be applied in the other direction (top down), and if zero (the default) a value proportionally closest to where the chromatic is in the input interval will be calculated. See documentation for modal_map for a longer example.
contrary - sets the contrary boolean. On by default.
input - scale or Forte Number or interval set for the modal_map input mode. Defaults to the Major scale if unset. See set_scale_intervals and modal_map for details.
keep_state - configures whether state is maintained through different calls to the various
*_map
methods. On by default, which requires the use of the corresponding*_map_reset
method when a phrase is complete. There are two possible workflows; with state enabled, multiple calls can be made to the mapping function, which suits modal_map:my $mc_state = Music::Canon->new; for my $e (@input) { my $result; eval { $result = $mc_state->modal_map($e) }; if ($@ and $@ =~ m/undefined chromatic conversion/) { $result = 'r'; # make it a lilypond rest } push @output, $result; } @output = reverse @output if $mc->get_retrograde; $mc_state->modal_map_reset;
The other workflow is to disable state, and pass entire phrases for conversion in one call. This better suits exact_map, which unlike the modal transformation will not have pitches it cannot convert, and thus will not need to handle individual note exceptions:
my $mc_no_state = Music::Canon->new(keep_state => 0); my @output = $mc_no_state->exact_map(\@input);
non_octave_scales - configures whether scales should be bounded at an octave (12 semitones) or not. The default is to pad interval sets that sum up to less than 12 to include an additional element such that the sum of the intervals is 12. Interval sets greater than 12 will cause an exception to be thrown.
Enable this option only if dealing with a maqam or similar scale that is not bounded by the Western notion of octave. For example, the whole tone scale (which is really just an expensive way to do an exact_map):
my $mc = Music::Canon->new( non_octave_scales => 1 ); # or Forte Number '6-35' $mc->set_scale_intervals('input', [2,2,2,2,2] ); $mc->set_scale_intervals('output', [2,2,2,2,2] );
output - scale or Forte Number or interval set for the modal_map output mode. Defaults to the Major scale if unset. See set_scale_intervals and modal_map for details.
retrograde - sets whether phrases are reversed. On by default.
transpose - value to transpose by, in semitones, or "to" a lilypond note name.
- reset_modal_pitches
-
Routine to nullify the modal_map pitches that are either set by the first note of the input phrase, or via the set_modal_pitches method. These values otherwise persist across calls to modal_map.
- set_contrary boolean
-
Sets the contrary boolean (on by default). With this set, phrases from the
*_map
routines will be set in contrary motion to the input phrase.Returns the Music::Canon object, so can be chained with other method calls.
- set_modal_chrome weight
-
Sets the modal_map chrome weighting. Troolean: 0 (proportional), negative (literal from previous note up), or positive (literal from current note down).
- set_modal_pitches input_tonic, [ output_tonic ]
-
Sets the tonic note or pitch of the input and output interval sets used by modal_map. If the input_tonic is set, but not the optional output_tonic, the cached output_tonic value, if any, will be wiped out.
$mc->set_modal_pitches(60, 62); $mc->set_modal_pitches(undef, 64); # just output start pitch $mc->set_modal_pitches(q{c'}); # by lilypond note
Using this method is a necessity if the phrase passed to modal_map begins on a non-tonic scale degree, as otherwise that non- tonic scale degree will become the tonic for whatever interval set is involved. That is, if the notes
e e f g g
are passed to modal_map, by default modal_map will assumee
Major as the input scale, ande
Major as the output scale (though that may vary depending on the transpose setting).Returns the Music::Canon object, so can be chained with other method calls.
- set_retrograde boolean
-
Sets the retrograde boolean (on by default). If set, phrases from the
*_map
routines will be reversed. Meaningless if*_map
calls are being made note-by-note (see the keep_state documentation).Returns the Music::Canon object, so can be chained with other method calls.
- set_scale_intervals layer, asc, [dsc]
-
Sets the scale intervals for the indicated layer (
input
oroutput
). The asc (and optional dsc) can be one of several different things:$mc->set_scale_intervals('input', 'minor'); # Music::Scales $mc->set_scale_intervals('input', '7-23'); # Forte Number # arbitrary interval sequence $mc->set_scale_intervals('input', [qw/2 1 3 2 1 3 1/]);
If the dsc is undefined, the corresponding asc intervals will be used, except for Music::Scales, for which the descending intervals associated with the ascending scale will be used. If asc is undefined, dsc must then be set to something. This allows the descending intervals alone to be adjusted.
$mc->set_scale_intervals('output', undef, 'aeolian');
Note that the descending intervals must be ordered from the highest pitch down. That is, melodic minor can be stated manually via:
$mc->set_scale_intervals( 'output', [2,1,2,2,2,2], # ascending - c d ees f g a b [2,2,1,2,2,1] # descending - c bes aes g f ees d );
Though this particular case would be much more easily stated via Music::Scales via:
$mc->set_scale_intervals('output', 'mm');
set_scale_intervals returns the Music::Canon object, so can be chained with other method calls.
- set_transpose integer or lilypond note
-
Sets the value to transpose to or by in
*_map
methods, either in semitones, or to a particular lilypond note:$mc->set_transpose(-12) # down by an octave $mc->set_transpose(q{c'}) # to the lilypond note
Returns the Music::Canon object, so can be chained with other method calls.
SEE ALSO
"Counterpoint in Composition" by Felix Salzer and Carl Schachter.
"The Technique of Canon" by Hugo Norden
"Counterpointer" by Ars Nova (counterpoint instruction software).
http://en.wikipedia.org/wiki/Forte_number
Music::AtonalUtil, Music::LilyPondUtil, Music::Scales, Music::Tension
The canonical
and scalemogrifier
utilities of App::MusicTools may also be of interest.
AUTHOR
Jeremy Mates, <jmates@cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2013 by Jeremy Mates
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.16 or, at your option, any later version of Perl 5 you may have available.