# NAME

Music::AtonalUtil - atonal music analysis and composition

# SYNOPSIS

```
use Music::AtonalUtil ();
my $atu = Music::AtonalUtil->new;
my $nf = $atu->normal_form([0,3,7]);
my $pf = $atu->prime_form(0, 4, 7);
...
```

Though see below for the (many) other methods.

# DESCRIPTION

This module contains a variety of routines for atonal music composition and analysis (plus a bunch of somewhat related routines). See the methods below, the test suite, and the `atonal-util`

command line interface in App::MusicTools for pointers on usage.

This module follows the Rahn method of prime form calculation (as opposed to the Forte method). The prime numbers have been audited against Rahn's "Basic Atonal Theory".

# CONSTRUCTOR

By default, a 12-tone system is assumed. Input values are mapped to reside inside this space where necessary. Most methods accept a pitch set (an array reference consisting of a list of pitch numbers, or just a list of such numbers), and most return an array reference containing the results. Some sanity checking is done on the input, which may cause the code to **croak** if something is awry.

**new** *parameter_pairs ...*

The degrees in the scale can be adjusted via:

`Music::AtonalUtil->new(DEG_IN_SCALE => 17);`

or some other positive integer greater than one, to use a non-12-tone basis for subsequent method calls. This value can be set or inspected via the **scale_degrees** method. **Note that while non-12-tone systems are in theory supported, they have not much been tested.** Rhythmic analysis overlaps with various routines available; this is a practical use for a different number of "scale" degrees.

# METHODS

**adjacent_interval_content** *pitch_set*

A modified form of **interval_class_content** that only calculates adjacent interval counts for the given pitch set. Return values same as for **interval_class_content** method.

This method suits rhythmic analysis, see "RHYTHM".

**bark_scale** *frequency* ..

Calculate the bark scale number for the given frequencies, using one of the several formula available to do that.

**bits2pcs** *number*

Converts a number into a *pitch_set*, and returns said set as an array reference. Performs opposite role of the **pcs2bits** method. Will not consider bits beyond **scale_degrees** in the input number.

**check_melody** *params ref*, *pitch_set*

Given a set of parameters and a melody (an array reference of pitch numbers), returns false if the melody fails any of the rules present in the parameters, or true otherwise. See **gen_melody** for one method of melody generation. The return value in scalar context will be a boolean; in list context, the boolean will be followed by a rule name and then depending on the rule possible a third return value, an hash reference containing details of what failed where.

Parameters (at least one must be specified, doubtless more):

*dup_interval_limit*=>*count*-
Rejects the melody if there are a number of intervals equal to or greater than the specified

*count*. *exclude_interval*=> [*list of hashes*... ]-
Rejects the melody should it contain specified patterns of intervals. Only the magnitude of the interval is considered, and not the direction. An example, whose ending in rising fourths would be unacceptable in a strict atonal context:

`$atu->check_melody( [qw/60 64 57 59 60 57 65 64 62 67 72/], exclude_interval => [ { iset => [ 5, 5 ], }, # adjacent fourths ("cadential basses") ], );`

In addition to the

*iset*interval array reference, an*in*value can specify in how many intervals (above that of the*iset*) to search for the specified intervals. The following would look for two perfect fourths, optionally with some other interval between them:`{ iset => [ 5, 5 ], in => 3 },`

Intervals in any order may be considered by adding the

*sort*flag, and then numbering the intervals to match from low to high:`{ iset => [ 1, 2, 3 ], sort => 1 },`

*exclude_half_prime*=> [*list of hashes*... ]-
Rejects the melody should it contain notes comprising the specified so- called "half prime" form. The

*ps*value pitch set must be in**half_prime_form**. Otherwise identical to*exclude_prime*. *exclude_prime*=> [*list of hashes*... ]-
Rejects the melody should it contain notes comprising the specified prime forms. The

*ps*value pitch set must be in**prime_form**.`exclude_prime => [ { ps => [ 0, 3, 7 ], in => 4 }, # major or minor triad, any guise { ps => [ 0, 2, 5, 8 ], }, # 7th, any guise, exact { ps => [ 0, 2, 4, 6 ], in => 5 }, # whole tone formation ],`

Additionally, a

*subsets*key can be used to apply the rule to any subset prime form pitch set of the input pitch set. For example, to exclude 5 or 6 note subsets of the 7-35 pitch set:`exclude_prime => [ { in => 8, # in 8 (or 7 or 6) note groups subsets => [ 5, 6 ], ps => [ 0, 1, 3, 5, 6, 8, 10 ], # 7-35 (major/minor scale) }, ],`

This method probably should not be used for smaller subsets than five, as sets like 7-35 or larger have many subsets in the 4-x (13 prime form subsets, to be exact) or smaller range, and with the prime form conflation of multiple other "half prime" sets, well more pitches than one might expect can match the rule.

**circular_permute** *pitch_set*

Takes a pitch set (array reference to list of pitches or just a list of such), and returns an array reference of pitch set references as follows:

`$atu->circular_permute([1,2,3]); # [[1,2,3],[2,3,1],[3,1,2]]`

This is used by the **normal_form** method, internally. This permutation is identical to inversions in tonal theory, but is different from the **invert** method offered by this module. See also **rotate** to rotate a pitch set by a particular amount, or **rotateto** to search for something to rotate to.

**complement** *pitch_set*

Returns the pitches of the scale degrees not set in the passed pitch set (an array reference to list of pitches or just a list of such).

`$atu->complement([1,2,3]); # [0,4,5,6,7,8,9,10,11]`

Calling **prime_form** on the result will find the abstract complement of the original set, whatever that means.

**fnums**

Returns hash reference of which keys are Forte Numbers and values are array references to the corresponding pitch sets. This reference should perhaps not be fiddled with, unless the fiddler desires different results from the **forte2pcs** and **pcs2forte** calls.

**forte_number_re**

Returns a regular expression capable of matching a Forte Number.

**forte2pcs** *forte_number*

Given a Forte Number (such as `6-z44`

or `6-Z44`

), returns the corresponding pitch set as an array reference, or `undef`

if an unknown Forte Number is supplied.

**gen_melody** *params* ...

Generates a random 12-tone series, feeds that to **check_melody**, tries for a number of times until a suitable melody can be returned as an array reference. May throw an exception if something goes awry or the rules did not permit a melody. The 12-tone series will remain within a single register, so the generation of melodies with 9ths or 10ths is not possible via this method.

See **check_melody** for documentation on the parameters; setting these is mandatory. **gen_melody** offers one additional parameter to set the tessitura of the melody (in semitones; default is a 10th):

`$atu->gen_melody( melody_max_interval => 11, ... );`

The Music::VoiceGen module offers an alternate means of generating melodies.

**half_prime_form** *pitch_set*

Returns what I call the "half prime" form of a pitch set; in scalar context returns an array reference to the resulting pitch set, while in list context returns an array reference and a subsequent hash reference containing a mapping of pitch set numbers to the original pitches (as also done by **normal_form**).

An example with the Major and minor triads should illustrate the differences between **half_prime_form**, **normal_form**, and **prime_form**, using `lilypond`

note names for the input and pitch numbers for the resulting output:

```
normal form <d f a> = 2,5,9 # D minor
normal form <d fis a> = 2,6,9 # D Major
normal form <e g b> = 4,7,11 # E minor
normal form <e gis b> = 4,8,11 # E Major
halfp form <d f a> = 0,3,7
halfp form <d fis a> = 0,4,7
halfp form <e g b> = 0,3,7
halfp form <e gis b> = 0,4,7
prime form <d f a> = 0,3,7
prime form <d fis a> = 0,3,7
prime form <e g b> = 0,3,7
prime form <e gis b> = 0,3,7
```

Note that some pitch sets have no "half prime form" distinct from the prime form; this distinction influences what the Music::NeoRiemannianTonnetz module can do with the pitch set, for example (see `eg/nrt-study-setclass`

of that module).

The "half prime form" name is my invention; I have no idea if there is another term for this calculation in music theory literature. The wikipedia "list of pitch class sets" as of 2015 distinguishes `3-5A`

from `3-5B`

, which would correspond to the half prime form this module will calculate, while **prime_form** would only find `3-5`

for any member of that set.

**interval_class_content** *pitch_set*

Given a pitch set with at least two elements, returns an array reference (and in list context also a hash reference) representing the interval-class vector information. Pitch sets with similar ic content tend to sound the same (see also **zrelation**).

This vector is also known as a pitch-class interval (PIC) vector or absolute pitch-class interval (APIC) vector:

https://en.wikipedia.org/wiki/Interval_vector

Uses include an indication of invariance under transposition; see also the **invariants** mode of `atonal-util`

of App::MusicTools for the display of invariant pitches. It also has uses in rhythmic analysis (see works by e.g. Godfried T. Toussaint).

**intervals2pcs** *start_pitch*, *interval_set*

Given a starting pitch (set to `0`

if unsure) and an interval set (a list of intervals or array reference of such), converts those intervals into a pitch set, returned as an array reference.

**invariance_matrix** *pitch_set*

Returns reference to an array of references that comprise the invariance under Transpose(N)Inversion operations on the given pitch set. Probably easier to use the **invariants** mode of `atonal-util`

of App::MusicTools, unless you know what you are doing.

**invert** *axis*, *pitch_set*

Inverts the given pitch set, within the degrees in scale. Set the *axis* to `0`

if unsure. Returns resulting pitch set as an array reference. Some examples or styles assume rotation with an axis of `6`

, for example:

https://en.wikipedia.org/wiki/Set_%28music%29#Serial

Has the "retrograde-inverse transposition" of `0 11 3`

becoming `4 8 7`

. This can be reproduced via:

```
my $p = $atu->retrograde(0,11,3);
$p = $atu->invert(6, $p);
$p = $atu->transpose(1, $p);
```

**lastn** *array_ref*, *n*

Utility method. Returns the last N elements of the supplied array reference, or the entire list if N exceeds the number of elements available. Returns nothing if the array reference is empty, but otherwise will throw an exception if something is awry.

**mininterval** *from*, *to*

Returns the minimum interval including sign between the given pitch numbers within the confines of the **scale_degrees**; that is, C to F would be five, F to C negative five, B to C one, and C to B negative one.

**multiply** *factor*, *pitch_set*

Multiplies the supplied pitch set by the given factor, modulates the results by the **scale_degrees** setting, and returns the results as an array reference.

**nexti** *array ref*

Utility method. Returns the next item from the supplied array reference. Loops around to the beginning of the list if the bounds of the array are exceeded. Caches the index for subsequent lookups. Part of the **geti**, **nexti**, **reseti**, **seti**, and **whati** set of routines, which are documented here:

**geti***array ref*-
Returns current position in array (which may be larger than the number of elements in the list, as the routines modulate the iterator down as necessary to fit the reference).

**grabi***count**array ref*-
Returns a list of

*count*elements from the array reference, looping back over the reference when*count*is greater than the number of elements, or the current pointer requires doing so. **reseti***array ref*-
Sets the iterator to zero for the given array reference.

**seti***array ref*,*index*-
Sets the iterator to the given value.

**whati***array ref*-
Returns the value of what is currently pointed at in the array reference. Does not advance the index.

**normal_form** *pitch_set*

Returns two values in list context; first, the normal form of the passed pitch set as an array reference, and secondly, a hash reference linking the normal form values to array references containing the input pitch numbers those normal form values represent. An example may clarify:

`my ($ps, $lookup) = $atu->normal_form(60, 64, 67, 72); # c' e' g' c''`

`$ps`

is`[0,4,7]`

, as`60`

and`72`

are equivalent pitches, so both get mapped to`0`

.`$lookup`

contains hash keys`0`

,`4`

, and`7`

, where`4`

points to an array reference containing`64`

,`7`

to an array reference containing`67`

, and`0`

an array reference containing both`60`

and`72`

. This allows software to answer "what original pitches of the input are X" type questions.

Use `scalar`

context or the following to select just the normal form array reference:

`my $just_the_nf_thanks = ($atu->normal_form(...))[0];`

The "packed from the right" method outlined in the www.mta.ca link ("SEE ALSO") is employed, so may return different normal forms than the Allen Forte method. There is stub code for the Allen Forte method in this module, though I lack enough information to verify if that code is correct. The Forte Numbers on Wikipedia match that of the www.mta.ca link method.

See also **half_prime_form** and **prime_form**.

**pcs2bits** *pitch_set*

Converts a *pitch_set* into a **scale_degrees**-bit number.

```
7 3 0
[0,3,7] -> 000010001001 -> 137
```

These can be inspected via `printf`

, and the usual bit operations applied as desired.

```
my $mask = $atu->pcs2bits(0,3,7);
sprintf '%012b', $mask; # 000010001001
if ( $mask == ( $atu->pcs2bits($other_pset) & $mask ) ) {
# $other_pset has all the same bits on as $mask does
...
}
```

**pcs2forte** *pitch_set*

Given a pitch set, returns the Forte Number of that set. The Forte Numbers use uppercase `Z`

, for example `6-Z44`

. `undef`

will be returned if no Forte Number exists for the pitch set.

**pcs2intervals** *pitch_set*

Given a pitch set of at least two elements, returns the list of intervals between those pitch elements. This list is returned as an array reference.

**pcs2str** *pitch_set*

Given a pitch set (or string with commas in it) returns the pitch set as a string in `[0,1,2]`

form.

```
$atu->pcs2str([0,3,7]) # "[0,3,7]"
$atu->pcs2str(0,3,7) # "[0,3,7]"
$atu->pcs2str("0,3,7") # "[0,3,7]"
```

**pitch2intervalclass** *pitch*

Returns the interval class a given pitch belongs to (0 is 0, 11 maps down to 1, 10 down to 2, ... and 6 is 6 for the standard 12 tone system). Used internally by the **interval_class_content** method.

**prime_form** *pitch_set*

Returns the prime form of a given pitch set (via **normal_form** and various other operations on the passed pitch set) as an array reference.

See also **half_prime_form** and **normal_form**.

**reflect_pitch** *pitch*, *min*, *max*

Utility method. Constrains the supplied pitch to reside within the supplied minimum and maximum limits, by "reflecting" the pitch back off the limits. For example, given the min and max limits of 6 and 12:

```
pitch ... 10 11 12 13 14 15 16 17 18 19 20 21 ...
result ... 10 11 12 11 10 9 8 7 6 7 8 9 ...
```

This may be of use in a Music::LilyPondUtil `*_pitch_hook`

function to keep the notes within a certain range (modulus math, by contrast, produces a sawtooth pattern with occasional leaps).

**retrograde** *pitch_set*

Fancy term for the `reverse`

of a list. Returns reference to array of said reversed list.

**rotate** *rotate_by*, *pitch_set*

Rotates the pitch set by the integer supplied as the first argument. Returns an array reference of the resulting pitch set. (**circular_permute** performs all the possible rotations for a pitch set.)

**rotateto** *what*, *dir*, *pitch_set*

Utility method. Rotates (via **rotate**) a given array reference to the desired element *what* (using string comparisons). Returns an array reference of the thus rotated set. Throws an exception if anything goes wrong with the input or search.

*what* is searched for from the first element and subsequent elements, assuming a positive *dir* value. Set a negative *dir* to invert the direction of the search.

**scale_degrees** *optional_integer*

Without arguments, returns the number of scale degrees (12 by default). If passed a positive integer greater than two, sets the scale degrees to that. Note that changing this will change the results from almost all the methods this module offers, and has not (much) been tested.

**set_complex** *pitch_set*

Computes the set complex, or a 2D array with the pitch set as the column headers, pitch set inversion as the row headers, and the combination of those two for the intersection of the row and column headers. Returns reference to the resulting array of arrays.

Ideally the first pitch of the input pitch set should be 0 (so the input may need reduction to **prime_form** first).

**subsets** *length*, *pitch_set*

Returns the subsets of a given pitch set as an array of array refs. *length* should be `-1`

to select for pitch sets of one element less, or a positive value of a magnitude less than the pitch set to return the subsets of a specific magnitude.

```
$atu->subsets(-1, [0,3,7]) # different ways to say same thing
$atu->subsets( 2, [0,3,7])
```

The input set will be modulated to the **scale_degrees** limit, and any duplicate pitches excluded before the subsets are generated. The return sets might be further reduced by the caller via **half_prime_form** or **prime_form** or some other method to (sometimes) effect an even greater reduction in the number of subsets. However, by default, no such reduction is done by this method, beyond initial input set sanitization.

**tcs** *pitch_set*

Returns array reference consisting of the transposition common-tone structure (TCS) for the given pitch set, that is, for each of the possible transposition operations under the **scale_degrees** in question, how many common tones there are with the original set.

**tcis** *pitch_set*

Like **tcs**, except uses **transpose_invert** instead of just **transpose**.

**transpose** *transpose_by*, *pitch_set*

Transposes the given pitch set by the given integer value in *transpose_by*. Returns the result as an array reference.

**transpose_invert** *transpose_by*, *axis*, *pitch_set*

Performs **invert** on given pitch set (set *axis* to `0`

if unsure), then transposition as per **transpose**. Returns the result as an array reference.

**variances** *pitch_set1*, *pitch_set2*

Given two pitch sets, in scalar context returns the shared notes of those two pitch sets as an array reference. In list context, returns the shared notes (intersection), difference, and union as array references.

**zrelation** *pitch_set1*, *pitch_set2*

Given two pitch sets, returns true if the two sets share the same **interval_class_content**, false if not.

# RHYTHM

Rhythmic analysis might begin with:

`Music::AtonalUtil->new(DEG_IN_SCALE => 16);`

Assuming 16 beats in a measure, as per the Godfried Toussaint article ("SEE ALSO"), the "clave Son" rhythm that in lilypond might run something like `c8. c16 r8 c8 r8 c8 c4`

could be represented using the "onset-coordinate vector" notation of `(0,3,6,10,12)`

and perhaps passed to such routines as **interval_class_content** for subsequent analysis. For example, a measure of evenness (the sum of the interval arc-lengths) can be obtained via:

```
use Music::AtonalUtil ();
my $atu = Music::AtonalUtil->new( DEG_IN_SCALE => 16 );
my $ics = ( $atu->interval_class_content( 0, 3, 6, 10, 12 ) )[1];
my $sum = 0;
for my $k ( keys %$ics ) {
$sum += $k * $ics->{$k};
}
```

See `atonal-util`

of App::MusicTools for **beats2set** and **set2beats**, for beat pattern to "pitch" set conversions.

# CHANGES

Version 1.0 reordered and otherwise mucked around with calling conventions (mostly to allow either an array reference or a list of values for pitch sets), but not the return values. Except for **normal_form**, which obtained additional return values, so you can figure out which of the input pitches map to what (a feature handy for Music::NeoRiemannianTonnetz related operations, or so I hope).

Otherwise I generally try not to break the interface. Except when I do.

# BUGS

## Reporting Bugs

If the bug is in the latest version, send a report to the author. Patches that fix problems or add new features are welcome.

http://github.com/thrig/Music-AtonalUtil

## Known Issues

Poor naming conventions, vague and conflicting standards of music theory, plus any mistakes in understanding of music theory or coding by the author.

# SEE ALSO

"Basic Atonal Theory" by John Rahn.

`@book{rahn1980, title={Basic Atonal Theory}, author={John Rahn}, year=1980, publisher={Longman}, ISBN="0-582-28117-2", }`

"Computational geometric aspects of rhythm, melody, and voice-leading" by Godfried Toussaint (and other rhythm articles by the same).

"The Geometry of Musical Rhythm" by Godfried T. Toussaint.

Musimathics, Vol. 1, p.311-317 by Gareth Loy.

http://www.mta.ca/faculty/arts-letters/music/pc-set_project/pc-set_new/

"Review of Basic Atonal Theory", David H. Smyth. Perspectives of New Music, Vol. 22, No. 1/2 (Autumn, 1983 - Summer, 1984). pp. 549-555. http://www.jstor.org/stable/832965

"Serial Composition" by Smith-Brindle Reginald.

"The Structure of Atonal Music" by Allen Forte.

`@book{forte1973, title={The Structure of Atonal Music}, author={Allen Forte}, year=1973, publisher={Yale University Press}, ISBN="978-0-300-02120-2", }`

# AUTHOR

thrig - Jeremy Mates (cpan:JMATES) `<jmates at cpan.org>`

# COPYRIGHT AND LICENSE

Copyright (C) 2012-2016 by Jeremy Mates

This module is free software; you can redistribute it and/or modify it under the Artistic License (2.0).