atonal-util - routines for atonal composition and analysis


Prime form and APIC vector for a pitch set:

  $ atonal-util basic --ly f fis c

Apply a series of transformations to a pitch set:

  $ cat rules
  invert 6
  transpose 1
  $ atonal-util recipe --file=rules 0 11 3

Among many other options.


Routines for atonal music composition and analysis, plus other music theory or composition related tasks. Global options and a mode must be supplied, followed by any mode specific arguments. Most modes accept pitch sets, though some perform other tasks and thus expect various input formats. Pitch sets can be read as arguments or from standard input; some modes require two pitch sets that must be supplied one per line on standard input.

The output will vary depending on the mode, and may include Cope tension numbers (average, min, max tension for the pitch set). Other programs should not be written to use this program, as the output may change. Use the underlying code or modules called by this program, as this program is intended for interactive use.


This program currently supports the following global command line switches:

--flats | --noflats

Uses flats instead of sharps in output (but only with --ly). Specify --noflats to disable flats, in the event you have an alias that sets --flats by default. There is currently no --sharps option, sorry.

Doubleflats or doublesharps are not supported in the output, as they will be rendered to the underlying note (e.g. for Fx the output would be G). Doubleflats or doublesharps can be specified in the input, though.


Displays help and exits the program.


Displays supported operation modes and exits the program.


Show lilypond note names instead of raw pitch numbers. This feature may be disabled if the scale degrees is altered from 12.


Adjust the number of scale degrees (default: 12). May cause strange, untested results from various calculations, use with caution. Rhythm work might benefit from setting this to 16, depending.


Most modes accept a pitch set. These comprise raw pitch numbers (integers), or lilypond note names (bis, c, des, etc.), or a Forte Number, specified either on the command line or via standard input, though some modes have other conventions or input they accept.

  atonal-util basic 0 4 7 10
  atonal-util basic c e g bes
  atonal-util basic 4-27

Various global flags (listed above) can be specified as options to modes where they make sense.

bark pitches...

Coverts the given pitches or note names into Bark scale numbers, by way of pitch2freq. Supports the same arguments as pitch2freq.

See "Voice Leading" by David Huron for practical uses of critical bands.

basic pitch_set

Shows the prime_form and interval_class_content and perhaps other details.

beats2set beats

Converts rhythmic beats to a "pitch" set, where x represents an onset, and . a rest. An example may help:

  $ atonal-util beats2set --scaledegrees=16 x..x ..x. ..x. x...

set2beats performs the reverse operation of this.

circular_permute pitch_set

All permutations by rotation of the input pitch set. See Music::AtonalUtil for details.

combos freq1 freq2 [freq3 ...]

Shows the combination tones of the input frequencies (or with the optional --pitches flag, MIDI pitch numbers or lilypond note names) relative to the first listed frequency. The delta of equal temperament tuning from the actual combination tone is also shown.

  $ atonal-util --ly combos 220 440
  $ atonal-util --ly combos --pitches "c' g'"

This mode also accepts the --concertfreq or --cf argument to specify a different reference pitch than 440 Hz. This will affect both notes input (different frequencies) and output (how error amounts for how far the resulting combination tone is from the nearest pitch).

complement pitch_set

Emits those pitches not listed in the input. See Music::AtonalUtil.

equivs pitch_set

Lists equivalents of the input pitch set under various transposition and inverse transposition operations.

findall --exclude=p1[,p2] --fn=nums --root=pitch pitch_set

Find all Forte pitch sets in which the given pitches exist. Like findin, except iterates over all Forte pitch sets instead of just a named pitch set.

With --exclude, omits results containing the listed pitches. With --fn, limits the search to the mentioned forte number prefixes (the number of pitches in the set). With --root, limits matches to those with the named root pitch.

  $ atonal-util findall --root=c --fn=4-5 c e g bes

findin --exclude=p1[,p2] --root=pitch --pitchset=base_set pitch_set

Answers questions such as, given a base pitch set of [0,3,7], and the notes D and Bb, what pitch sets (via any transpose or transpose_invert operation) complete the base pitch set. With --exclude, omits results containing the listed pitches. With --root, limits matches to those with the named root pitch.

  $ atonal-util findin --exclude=c,ees --pitchset=5-25 d fis a

Another use is for what some call "concatenated chords"; one might have an exercise to write a melody where the previous note or two is used to form a new triad (major/minor, or also diminished and augmented) so may want to know what other chords are usable given a note or two:

  $ atonal-util findin -P 3-11 c
  $ atonal-util findin -P 3-10 -P 3-11 -P 3-12 des f

Atonality, however, may not exactly match harmonic requirements.

fnums [ --tension=cope ]

Returns a list of all Forte Numbers and corresponding pitch sets (and their interval_class_content). With the --tension flag, also shows Cope tension values for the pitch sets.

forte2pcs forte_number

Given a Forte Number, returns the corresponding pitch set.

freq2pitch frequencies...

Converts the listed frequencies (in Hz) into the closest MIDI note numbers. Reads frequencies line-per-line from standard input if the only frequency given is a -. With --ly also converts the MIDI note number to a lilypond note name.

This mode also accepts the --concertfreq or --cf argument to specify a different reference pitch than 440 Hz.


Generates a random melody perhaps suitable for subsequent atonal use. See code and documentation over in Music::AtonalUtil for details.

half_prime_form pitch_set

Shows the "more normal" or "half prime" form of a pitch set, which may or may not differ from the prime_form of the pitch set. This output, if relevant, is also emitted in the basic mode.

interval_class_content pitch_set

See Music::AtonalUtil, or

intervals2pcs --pitch=startpitch pitch_set

Converts a list of intervals to a pitch set. The default starting pitch is 0.

invariance_matrix pitch_set

Invariance under Transpose(N)Inversion operation matrix. See Music::AtonalUtil.

invariants pitch_set

Returns list of transpose or transpose_invert operations that have invariant pitches with the supplied pitch set, along with which pitches have not varied.

invert --axis=inversion_axis pitch_set

See Music::AtonalUtil. Default axis is around pitch 0.

ly2pitch --relative=note notes...

Converts lilypond note names to pitch numbers, via absolute mode by default. The input unlike in other modes may be quoted to protect the lilypond ' register change from shell quoting rules. Example usages:

  $ echo c e g | atonal-util ly2pitch -
  $ atonal-util ly2pitch "c d' e f, g"
  $ atonal-util ly2pitch --relative=a\' a c d b

ly2struct --relative=note --tempo=t notes...

Converts lilypond note names and durations to C struct members comprised of the frequency in Hz and duration in milliseconds of the note. Handy for feeding data to an Arduino tone() call:

  atonal-util ly2struct --relative=c\' --tempo=116 \
    "c8 d e f8. g32 f e8 a d, g8. a16 g f ..."

And then:

  struct voice {
      unsigned int freq;
      unsigned long dur;
  struct voice melody[] = {
      { 262, 259 },     /* c8 */
      { 294, 259 },     /* d */
      { 330, 259 },     /* e */
      { 349, 388 },     /* f8. */
      { 392, 65 },      /* g32 */
      { 349, 65 },      /* f */
  for (i = 0; i < sizeof(melody) / sizeof(voice); i++){
      if (melody[i].freq != 0)
          tone(BUZZER_PIN, melody[i].freq);

Other (less tested) options include --beats (quarter note by default), --concertfrequency and --concertpitch, and a --scala file to use.

multiply --factor=N pitch_set

Multiplies specified pitches by specified factor (1 by default).

normal_form pitch_set

Returns the normal form (via the "packed from the right" method) of the given pitch set.

notes2time --ms --tempo=bpm --beats=b notedurs...

Converts note durations (for example 4 for a quarter note or 4. for a dotted quarter note, or 8..*2/3 for a double-dotted eighth note of a triplet) to time, which is shown in a condensed form, unless -- ms is supplied, in which case the duration is shown in milliseconds. The --fraction=x/y option provides another means to set fractional durations, and is applied to all durations provided.

See also time2notes, which reverses millisecond values.

pcs2forte pitch_set

Given a pitch set, returns the corresponding Forte Number, if any.

pcs2intervals pitch_set

Given a pitch set of at least two elements, returns the list of intervals between the pitches.

pitch2freq pitches...

Converts pitches to frequencies (in Hz) using the standard MIDI note number conversion equation. Reads pitches (or lilypond notes) line-by-line from standard input if the only pitch given is -.

This mode also accepts the --concertfreq or --cf argument to specify a different reference pitch than 440 Hz.

pitch2intervalclass pitch

Return the interval class a given pitch belongs to.

pitch2ly --mode=relative|absolute pitches...

Converts pitches (integers) to lilypond note names. Reads pitches line-by- line from standard input if only pitch given is -. Use the --mode option to specify relative or absolute conversion.

prime_form pitch_set

Returns the prime form of the given pitch set.

recipe --file=recipefile

Apply a series of named operations from a batch file to a given pitch set. One possibility for recipefile contents might be:

  invert 6
  transpose 1

retrograde pitch_set

Reverses the given list of pitches.

rotate --rotate=integer pitch_set

Rotates the pitch set by the given integer (by default 0 or no rotation). Music::AtonalUtil also has a rotateby method to rotate to a particular element that may be of use in composition.

set2beats pitch_set

Converts a set class into a list of rhythmic beats. Reverse of what beats2set does.

  $ atonal-util set2beats 4-27 

Far more interesting might be to listen to the set:

  $ atonal-util set2beats 5-z38 | \
    perl -pe 'tr/x./cr/; s/(.)/${1}16 /g' | \
    ly-fu --tempo=168 --repeats=16 -

set_complex pitch_set

Computes the set complex of a pitch set (a table of the pitch set, pitch set inversion, and their combination).

subsets [ --length=integer ] pitch_set

See Music::AtonalUtil. The length, if supplied, must be a magnitude equal to or less than the number of pitches supplied, and probably also two or higher.

tcs pitch_set

Transposition common-tone structure. See Music::AtonalUtil. Probably easier to use the invariants mode to list the full results.

tcis pitch_set

As above method except with transpose_invert instead of transpose. Probably easier to use the invariants mode to list the full results.

tension pitch_set

Returns the average, min, max, and tension values for all the tensions in the passed pitch set, from the first notes in the set up to the last. Tensions calculated via Music::Tension::Cope.

time2notes --tempo=bpm --beats=b milliseconds...

Converts millisecond values to note durations. Reverse of notes2time with the --ms flag. These two can be used to convert notes between different tempos, for example to effect a fermata delay where tempo changes in the MIDI are not possible:

  atonal-util time2notes --tempo=$OUT_T \
    $(atonal-util notes2time --ms --tempo=$IN_T c4)

This would convert a quarter note at a tempo of 39 to the equivalent under the tempo of 60. The output value presently uses the lilypond multiplier format to represent the new duration.

transpose --transpose=integer_or_note pitch_set

Transposes the supplied pitches by the specified integer (by default 0, or a no-op), or to the specified note.

  $ atonal-util transpose --transpose=4 --ly c e g
  e gis b
  $ atonal-util transpose --transpose=e --ly c e g
  e gis b

Register aware transpositions are possible with the canonical tool of the App::MusicTools module, among many other nifty features (modal transpositions, etc).

transpose_invert --transpose=integer_or_note [ --axis=integer_or_note ] pitch_set

Inverts and then transposes the supplied pitch set by the specified integer, or to the specified note. Default axis for inversion is 0 (c).


Accepts two pitch sets, one per line, via standard input. Returns three lines consisting of the intersection, difference, and union of the given sets.

whatscalesfit pitch_set

Given a list of pitches or notes, shows what scales, if any, fit those notes. Only diatonics of the scale are considered; there is no support at present for also matching on bVI or other common chromatic alterations.


Accepts two pitch sets, one per line, via standard input. Emits 1 if the two sets share the same interval_class_content, 0 if they do not.


A ZSH completion script is available in the zsh-compdef/ directory of the App::MusicTools distribution. Install this to a $fpath directory.


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.

Known Issues

Poor naming conventions and standards of underlying music theory and any associated mistakes in understanding thereof by the author. (The Forte numbers are the Rahn Forte numbers, not the Forte Forte numbers.)


Music::AtonalUtil, Music::LilyPondUtil, Music::Tension::Cope


Copyright 2012 Jeremy Mates

This program is distributed under the (Revised) BSD License: