Music::NeoRiemannianTonnetz - performs Neo-Riemann operations on set classes


  use Music::NeoRiemannianTonnetz ();
  my $nrt = Music::NeoRiemannianTonnetz->new;

  # "parallel" changes Major to minor
  $nrt->transform( 'P', [60, 64, 67] );   # [60, 63, 67]
  $nrt->transform( 'P', [60, 63, 67] );   # [60, 64, 67]

  # or multiple operations (LPR)
  my $tasks = $nrt->taskify_tokens('LPR');
  my $new_pitch_set = $nrt->transform($tasks, 0, 3, 7);

  # Sevenths (4-27 only), e.g. F+ to C-
  $nrt->transform( 'S34', [65,69,72,75] ); # [66,70,72,75]

The Music::LilyPondUtil module will assist with converting between lilypond note names and raw pitch numbers; this module deals with only the raw pitch numbers (integers).


Performs Neo-Riemannian operations on major and minor triads (set class 3-11), and sevenths (set class 4-27).

This is a very new module, use with caution, things may change, etc.


Available operations (called "tokens" in this module) for the transform method on members of set class 3-11:

  P  Parallel
  R  Relative
  L  Leittonwechsel
  N  Nebenverwandt (RLP)
  S  Slide (LPR)
  H  "hexatonic pole exchange" (LPL)


These are derived from [Childs 1998] and operate only on members of set class 4-27. For example, the S23 will convert a F+ chord F A C Eb into F- F# A C E, or a F- chord into a F+, and so forth:

       F+   F-
  S23  F-   F+
  S32  F#-  E+
  S34  C-   Bb+
  S43  B-   B+
  S56  D-   Ab+
  S65  D#-  G+
  C32  D+   G#-
  C34  Ab+  D-
  C65  B+   B-

These always change two notes while holding the other two invariant; there is also a 10th (here unnamed) operation that holds three pitches invariant e.g. F+ [0,3,5,9] to A- [0,3,7,9]. But there is no network of changes while holding three invariant, only toggling between one or the other of two chords.


Token names are at present defined to be upper case ASCII letters (A-Z), followed by zero to many lower case ASCII letters or numbers (a-z0-9). Tokens will not perform any changes to a pitch set unless suitable code is added to the transformation table (a hash of token names to CODE references).


Most operations on most set classes are undefined. Use the eg/nrt-study-setclass program under the distribution of this module to graph arbitrary set classes. Otherwise, software exploiting links between related forms of a set class would not need to know the name of the link being followed (but humans might to help analyze what is going on).


The code may croak if something goes awry; catch these errors with e.g. Try::Tiny. The new method is doubtless a good one to begin with, and then transform to just experiment around with the transformations.

new parameter_pairs ...


DEG_IN_SCALE => positiveinteger

A 12-tone system is assumed, though may be changed, though I have no idea what that would do.

  Music::NeoRiemannianTonnetz->new(DEG_IN_SCALE => 17);
normalize pitch_set

Normalizes the given pitch set (a list or array reference of pitch numbers, which in turn should be integers) via code that is something like normal_form of Music::AtonalUtil but slightly different. Returns in list context a string of the normalized pitch set (such as 0,4,7 for a Major triad), and a hash reference that maps the normalized pitch set pitch numbers to the original pitches of the input pitch_set. In scalar context, just the string of the normalized pitch set is returned:

  use Music::LilyPondUtil         ();
  use Music::NeoRiemannianTonnetz ();
  my $lyu = Music::LilyPondUtil->new;
  my $nrt = Music::NeoRiemannianTonnetz->new;

  scalar $nrt->normalize( $lyu->notes2pitches(qw/c e g/) ) # 0,4,7

This method is used internally by the transform method, or can be used to explore the 3-11, 4-27, or other arbitrary set classes:

  chord        normalized  set class
  <c e g>      [0,4,7]     3-11
  <c ees g>    [0,3,7]     3-11
  <f a c ees>  [0,3,6,8]   4-27
  <fis a c e>  [0,2,5,8]   4-27

Neo-Riemannian operations need this unique normalized form as the set class conflates these different forms into the same Forte Number (3-11) or prime form pitch set ([0,3,7]), and Neo-Riemannian operations must do different things depending on whether the triad is major or minor, or is [0,3,6,8] or [0,2,5,8].

There are scripts under the eg/ directory of the distribution of this module that explore the normalize/atonal prime form set space.

taskify_tokens tokens, [ tasks ]

Converts tokens (a string such as RLP (three tokens, R, L, and P), or an array reference of such) to a list of tasks (CODE references) returned as an array reference, assuming all went well with the taskification.

techno [ measurecount ]

Generates techno beats (returned as a list). The optional measurecount should be a positive integer, and doubtless a power of two.

transform tokens, pitch_set

Transforms the given pitch_set (a list or array reference of pitch numbers, ideally integers) via the given tokens. If tokens is not an array reference, it is fed through the taskify_tokens method first. Returns the new pitch set (as an array reference) if all goes well.

The resulting pitch set will be ordered from lowest pitch to highest; Neo-Riemannian theory cares little about chord inversions, and will convert root position chords to and from various inversions:

  # C-major to F-minor (2nd inversion)
  $nrt->transform('N', 60, 64, 67); # [60, 65, 68]


Newer versions of this module may be available from CPAN. If the bug is in the latest version, check:

techno is not a bug, though may bug some.


[WP] as an introduction. for a description of the 3-11 and other set class names used in this documentation.

[Cohn 1998] "Introduction to Neo-Riemannian Theory: A Survey and a Historical Perspective" by Richard Cohn. Journal of Music Theory, Vol. 42, No. 2, Neo-Riemannian Theory (Autumn, 1998), pp. 167-180.

[Childs 1998] "Moving beyond Neo-Riemannian Triads: Exploring a Transformational Model for Seventh Chords" by Adrian P. Childs. Journal of Music Theory, Vol. 42, No. 2, Neo-Riemannian Theory (Autumn, 1998), pp. 181-193.

And also the rest of the Journal of Music Theory Vol. 42, No. 2, Autumn, 1998 publication:

Various other music modules by the author, for different views on music theory: Music::AtonalUtil, Music::Canon, Music::Chord::Positions, Music::LilyPondUtil, etc.


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


Copyright (C) 2013-2015 by Jeremy Mates

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