Jeremy Mates > Music-Tension > Music::Tension::Cope



Annotate this POD


View/Report Bugs
Module Version: 0.68   Source  


Music::Tension::Cope - tension analysis for equal temperament music


Beta interface! Has and will change without notice!

  use Music::Tension::Cope;
  my $tension = Music::Tension::Cope->new;

  my $value = $tension->pitches(4, 17);

  my $sum                     = $tension->vertical([qw/0 4 7/]);
  my ($sum, $min, $max, $ref) = $tension->vertical([qw/0 4 7/]);

  $tension->duration( $sum,        1/4 );
  $tension->duration( [qw/0 4 7/], 1/8 );

  $tension->metric(1, 2);  # beat 1, with custom value 2

  $tension->approach(7);   # motion by perfect fifth from prev.


This module offers tension analysis of equal temperament 12-pitch music, using the method outlined by David Cope in the text "Computer Models of Musical Creativity". The various methods will calculate the tension of verticals (simultaneous pitches), tension over a given duration, and so forth. Larger numbers indicate greater tension (dissonance) and smaller numbers consonance.

Cope uses the sum of the methods approach, duration, metric, and vertical to calculate the overall tension for each beat in an example Chorale. approach and metric will be the trickiest to implement, as they rely on knowing the interval of the harmonic change between the beats or having a lookup table available to calculate tension for random beats in random time signatures.

Various details are not captured by the tension analysis, notably if a particular pitch is chromatic (implying an underlying key that is being diverged from), musical style, dynamics, the sonic envelope, and so forth. If these are important, they should be included in the tension analysis.

Tension results may change between releases due to code changes. Be sure to update all old tension values before starting any new analysis or composition. This may require storing the original intervals or pitch sets along with the tension numbers.

Parsing music into a form suitable for use by this module and practical uses of the results are left as an exercise to the reader.


See (doi: 10.1073/pnas.1207989109) - "The basis of musical consonance as revealed by congenital amusia" for more thoughts on consonance. This article in particular shows a control group (presumably Western) rating an augmented triad as less pleasant than a diminished triad, while the numbers in this module will rate an augmented triad as only slightly more tense than the major and minor triads, and well less tense than a diminished triad (due to the tritone present in that).


Any method may croak if something is awry with the input. Methods are inherited from the parent class, Music::Tension.

new optional params

Constructor. Accepts optional parameters that specify alternate values instead of using the Cope-derived defaults.

  my $tension = Music::Tension::Cope->new(
    duration_weight => 0.42,
    metric_weight   => 0.42,
    octave_adjust   => 0.42,
    tensions        => { 0 => 0.42, 1 => 0.42, ... },
  • duration_weight adjusts the weighting given to duration tensions.
  • metric_weight adjusts the weighting given to metric tensions.
  • octave_adjust is a number to adjust intervals greater than an octave by. Intervals a single or multiple registers above the root will receive the same adjustment.
  • tensions must be a hash reference that must contain all intervals from (unison) to 11 (major seventh) inclusive. The default values are a distillation of an involved consideration of the overtone series by Cope; see the references below for the gory details.
approach pitch1

Presently a thin wrapper around pitches, where pitch1 is relative to unison (0), and will be mapped to that register, regardless of sign or direction of the music. Used for horizontal tensions. Cope indicates this is for "root motions" which from the example provided appears to be the harmonic changes, not specific interval leaps, so tension of unison for a tonic extension, tension of fifth for I-V6-I stasis or trips up or down the circle of fifths, and so forth:

  $tension->approach( 0 );    # stasis (tonic -> tonic)
  $tension->approach( 5 );    # perfect fourth (tonic -> pre-dominant)
  $tension->approach( 7 );    # fifth (tonic -> dominant)

Something else may be necessary to account for other root motions; Schoenberg (in "Theory of Harmony") favors rising fourths and falling thirds over the weaker falling fourth and rising thirds, and points out the weaker motions can be rectified over a longer phrase. Also relevant is whether the music is melodically rising or falling, and harmonically rising or falling (these can go in parallel or opposite directions, depending).

duration pitch_set_or_tension, duration

Calculates and returns the duration tension of a given pitch set reference or prior tension value for a given duration. The duration tension increases in proportion to the input tension and magnitude of the duration.

The exact value of the duration parameter is largely irrelevant as long as shorter durations use smaller values, and that the durations used are consistent over an analysis or composition. It could be a value in seconds, or a fraction 1/16 for a 16th note and then 1 for a whole note, or whatever. If using notes, be sure to factor in tempo if there are significant alterations to that over the course of a work.

The duration tension may also need adjustment depending on how well the instrument involved sustains; consider a xylophone vs. a piano vs. a piano with the sustain pedal down vs. a church organ.

frequencies f1, f2

Calculates tension between two given frequencies (Hz), via crude conversion of the frequencies to whatever-are-the-closest MIDI pitch numbers, and then calling pitches on those pitches. Mostly for interface compatibility with Music::Tension::PlompLevelt; presumably could be replaced with mathematical expression Cope uses to avoid the kluge-to-MIDI-pitch-numbers?

metric beat_number, beat_value

Tension calculation based on the position in a measure. The beat number should be an positive integer (1 for first beat of measure, 2 for second, etc) and the value a non-zero number used to adjust the results.

Cope indicates the use of a lookup table to provide the value, due to the complexity of where the weightings occur depending on the meter (e.g. 3/4 stresses the first (and perhaps second) beats, while 6/8 has stress on first and fourth). Lilypond auto-beaming should show one opinion on how notes are grouped and therefore where the stresses are, among other sources. Cope's tension values are lower on the beat, and higher towards the end of the measure:

            4/4 time
  beat     | 1     2     3     4
  value    | 2     2     6     2
  tension  | 0.05  0.10  0.05  0.20
vertical pitch_set_reference

vertical accepts an array reference of pitches (integers), and tallies tensions between the initial pitch to each subsequent. vertical will move subsequent pitches up a register if they are below the first pitch:

  <10 0 4 7> is considered as <10 12 16 19>

Unisons with the initial pitch will not be adjusted upwards. Octaves below the initial pitch will be adjusted to unison. If the adjustments are a problem, ensure that the first pitch is the lowest of the pitch set.

vertical returns the tension, minimum tension, maximum tension, and a reference to a list of tensions for each interval. Except in scalar context, where just the tension value is returned.

An alternative method would be to perform tension checks on each pitch to any higher pitches, such that 0 3 4 5 would also count the intervals present above the root (3 to 4, 3 to 5, and 4 to 5), instead of just the minor 3rd, major 3rd, and perfect fourth up from the root. An earlier version of this module did so, but the current code is trying to follow what Cope does as closely as possible.

pitches pitch1, pitch2

Accepts two pitches (integers) and returns the tension of the interval formed between those two pitches.



Jeremy Mates, <>


Copyright (C) 2012 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.

syntax highlighting: