Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
205 lines (146 sloc) 6.7 KB

Custom temperament

The temperament in music is the set of exact values in Hz that we assign to notes. In modern western music tradition the main temperament is equal temperament.

Equal temperament divides octave on 12 equal parts (in logarithmic scale) so that each interval with the same number of notes in between is should sound the same no matter from where you place the root of the interval. For instance a C major triad should sound the same as F# major triad. The sound is different in pitch but not in quality or relationships of the notes. It gives a huge advantage for transposition. If you want to sing along with the song but the scale is not good for your voice you can easily transpose the scale and it should sound the same.

But it brings some disadvantages too. The main strength of the equal temperament can become it's main weakness. All major thirds are the same and all minor seconds are the same. In fact all same intervals produce the same sound in all scales. It can wipe away all the colors from the music. The Bach, Chopin, Beethoven and all composers from the Romanticism era used different temperaments. So when we listen Chopin on the modern piano we listen to the music that is not quite the same as Chopin intended it to be.

They used temperaments that have many slightly different triads. It gives the specific colors to the scales and it makes the scale divergence within the composition more profound. Change in scale is not just a trasnposition it can affect the mood of the piece.

Ethnic music enjoys the variety of temperaments. In the Indian classical music octave is divided in 22 notes (or shruties). The musician picks up 5 to 9 notes from the raw material of 22 shruties and each combination can create different mood. For Indian music different scales have not only different sharps and flats but the quality of the note's flatness can be different from scale to scale. For example there can be three different F#.

By default all midi playing utilities use equal temperament. But we can alter this behavior.


The most common way to play patches is to use the function atMidi. It plays the patch with equal temperament. If you have a real midi device you can use the dac in place of vdac:

> ghci
> :m +Csound.Base Csound.Patch
> vdac $ atMidi vibraphone1

To change the temperament we can use the function atMidiTemp that accepts the temperament as the first argument:

> vdac $ atMidiTemp young1 vibraphone1

We can try out an ancient Pythagorean tuning:

> vdac $ atMidiTemp pythagor1 vibraphone1

We have several predefined temperaments to try out: equal1, pythagor, meantone, just1, werckmeister, young1, young2, young3.


Temperament is defined with the base note and the set of relationships for the notes of the scale. The temperament (Temp) can be created with function genTemp:

genTemp :: Double -> Double -> Double -> [Double] -> Temp
genTemp mainInterval baseHz baseMidiKey cents

Let's look at the arguments:

  • mainInterval - The frequency range covered before repeating the grade ratios, for example 2 for one octave, 1.5 for a fifth etcetera.

  • baseHz - The base frequency of the scale in cycles per second.

  • baseMidiKey - The integer index of the scale to which to assign baseHz unmodified.

  • cents - the list of ratios for each note of the temperament in cents.

So here is the definition for equal temperament:

equal1  = genTemp 2 261.63 60 equalCents1
equalCents1 = [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200]

The list should include the first note from the next octave (scale's main interval).

There are utility functions that simplify the definition of the temperament:

baseC :: [Double] -> Temp
baseC cents 

The baseC creates a temperament with octave interval and modern C as the base note of the temperament. We can rewrite the previous definition as:

equal1 = baseC equalCents1

There are other useful functions

stdTemp, barTemp :: [Double] -> Temp

The function stdTemp creates a scale so that 9nth note is modern concert A (440 Hz). The barTemp creates a temperament with baroque concert A (415 Hz). There are predefined lists of cents for several western temperaments: equalCents1, pythagorCents1, meantoneCents, werckmeisterCents, youngCents1, youngCents2, youngCents3. We can use them as an example to define our own temperaments.

Midi instruments

Let's invoke a simple virtual midi instrument:

> vdac $ midi $ onMsg $ \cps -> 0.5 * fades 0.01 0.1 * tri cps

The onMsg function takes in a function of type Sig -> Sig and converts it to midi function of the type Msg -> SE Sig We can change the temperament with function onMsg'

> vdac $ midi $ onMsg' just1 $ \cps -> 0.4 * fades 0.01 0.1 * tri cps

The onMsg takes in a temperament as the first argument. Behind the scenes the function onMsg invokes the function ampCps. it extracts the amplitude and frequency from the midi message. To change the temperament we can use the the function ampCps'. it accepts the temperament as the first argument:

ampCps' :: Temp -> Msg -> (D, D)
ampCps temp msg = (amplitude, frequency)

The ampCps' uses the function cpsmidi' to extract frequency with custom temperament:

cpsmidi' :: Temp -> Msg -> D


With patches we can use the functions atMidiTemp (for polyphonic synths) and atMonoTemp (for monophonic synths). Let's lookt at a couple of examples:

> vdac $ atMidiTemp young1 dreamPad
> vdac $ atMonoTemp just1 nightPadm

Sound fonts

Also we can use custom temperaments with sound fonts.

> vdac $ sfTemp meantone (Sf "/path/to/soundfont/jRhodes3.sf2" 0 0) 0.2

Temperament as a note's parameter

It's worth to note that we can pass the temperament as the instrument's argument. It can be used inside the scores or with event streams. The Temp type is an instance of the typeclass Arg.

More information on the datatype Temp and it's functions you can find in the module Csound.Tuning.