Scala and Custom Tuning
Reference for Scala support in RNBO. Working with custom scales and keyboard mappings.
Scala and Custom Tuning Reference
RNBO supports several ways to define a custom tuning for MIDI/Frequency conversion using the specification used in the Scala system for musical tunings. This document is meant to be a quick reference; for a full introduction to how Scala's tunings and keyboard mappings can be used in RNBO, check out our article Working with Scala and Custom Tuning.
RNBO's mtof and ftom objects support Scala's system for describing musical tunings in two ways: by allowing the user to call a tuning by name from the Scala archive, or by defining a tuning using a list of values. Tunings described with the syntax used in the
.scl file format should first be converted into a list, either manually, as we'll discuss in this section, or automatically using the scala.scl object.
The mtof and ftom objects can be given an argument, the filename of a tuning from the Scala archive (omitting the file extension
.scl). The object will then use that tuning when performing the MIDI/frequency conversion. You should be able to use any named tuning that you find on the Scala archive, though please note that RNBO may be using an older version of the archive that might not include recently-added tunings.
In the above image, you can see the result from sending the same MIDI note
60 to two mtof objects, one using twelve-tone equal temperament and one using the
iter4 tuning from the Scala archive.
@scale attribute with a properly formatted list will cause mtof to calculate the MIDI to frequency conversion based on a tuning specified by that list. The syntax for this list is specific to RNBO. To convert a Scala formatted file into a list for RNBO:
- Ignore any comment lines (prefixed with
- Skip the descriptive text line.
- Begin the list with the length value.
- Then for each line that follows, if the value is an absolute value in cents, add the cents value to the list, followed by a zero. If the value is a ratio, add the numerator and then the denominator to the list.
In this example, the cents value of
128.298 would be noted as
128.298 0. The ratio
2/1 would become
4 (with no period) is actually an implied ratio of
4/1 and would thus become
4 1 .
The following scala file for the pelog_me3 scale
! pelog_me3.scl ! Gamelan Kyahi Pangasih (kraton Solo). 1/1=286 Hz 7 ! 128.298 276.357 545.806 669.366 784.692 967.096 2/1
7 128.298 0 276.357 0 545.806 0 669.366 0 784.692 0 967.096 0 2 1
where the leading
7 indicates that there are 7 notes in the scale,
128.298 0 indicates 128.298 cents, and
2 1 indicates a ratio of 2/1 (octave).
In the image above, we can see the
iter4 tuning we used before has been applied to mtof by setting the
While the examples in this section have used pre-existing tunings by converting them into RNBO's list format, it's of course quite possible to create your own tuning by assembling a list of values.
By adapting the rules for the scl file format, you can create your own tuning in list format like so:
The first integer in the list contains the number of notes. This number indicates a number of pairs of numbers that describe pitch values.
After that comes the pitch values, each a pair of values. If the second number in the pair is
0, the pair represents a cents value, otherwise, the pair describes a ratio.
You may want to define a custom mapping for your MIDI keyboard or MIDI input stream such that your MIDI input more appropriately maps to the tuning you've defined. The mtof and ftom objects support Scala's
.kbm syntax for defining keyboard mappings, converted into a list format.
@map attribute with a properly formatted list will set a keyboard mapping for mtof which describes how a tuning with an arbitrary number of steps maps onto the piano keyboard.
RNBO's keyboard mapping format is the same as Scala's except there are no comments, and the maps are flattened into a list instead of having an entry per line. Additionally, we use -1 instead of 'x' to indicate unmapped entries. If the unmapped keys are at the end of the mapping, you can also simply leave them off.
In the KBM format, a mapping is described as follows:
! Template for a keyboard mapping ! ! Size of map. The pattern repeats every so many keys: 12 ! First MIDI note number to retune: 0 ! Last MIDI note number to retune: 127 ! Middle note where the first entry of the mapping is mapped to: 60 ! Reference note for which frequency is given: 69 ! Frequency to tune the above note to (floating point e.g. 440.0): 440.0 ! Scale degree to consider as formal octave (determines difference in pitch ! between adjacent mapping patterns): 12 ! Mapping. ! The numbers represent scale degrees mapped to keys. The first entry is for ! the given middle note, the next for subsequent higher keys. ! For an unmapped key, put in an "x". At the end, unmapped keys may be left out. 0 1 2 3 4 5 6 7 8 9 10 11
In RNBO, we'd define this same mapping as:
12 0 127 60 69 440 12 0 1 2 3 4 5 6 7 8 9 10 11
In the following map for the
pelog_me3 scale, the pattern repeats every 12 keys of the piano keyboard. MIDI notes between 0 and 127 will be tuned. The first entry of the mapping will be MIDI note 60, the reference note for the scale's tuning is MIDI note 62, which is tuned to 286 Hz.
The scale's "formal octave" is 7, meaning there are 7 notes described in this scale.
Those 7 notes are mapped onto the "white keys" of the piano keyboard. All other keys are skipped, indicated with the -1 .
12 0 127 60 62 286 7 0 -1 1 -1 2 3 -1 4 -1 5 -1 6
Please note: while you can also use the "x" character to indicate an unmapped key in Max, this is not possible in RNBO's list format — you must use the "-1" to indicate an unmapped key.
You can send a
set map to reset the map back to its default: "linear 440," meaning each successive MIDI note is mapped to a successive pitch value, with a reference note of MIDI note 69 tuned to 440 Hz.
The signal-rate mtof~ and ftom~ objects will accept
set scale and
set map just like their event-rate counterparts. However, you'll want to be aware that MIDI notes that are unmapped in an active keyboard mapping will be output from mtof~ as 0 Hz, and that ftom~ will output a MIDI note 0 when it receives an input of 0 Hz.
The scala.list object can store multiple tunings from the Scala archive as an indexed array and then output them in RNBO's list format when given an integer or a bang as input.
You can also let scala.list choose a tuning at random from the Scala archive at codegen time, using the word
random instead of a scale name. The name of the selected tuning and some information about the tuning from the Scala archive will print in the console.
If you don't want to manually convert your
.kbm file into a RNBO-style list, RNBO has objects that will do that for you—the scala.scl and scala.kbm codebox editors.
In the image above, the
meanquar tuning from the previous image is defined in Scala's
.scl file format, and output as a RNBO-formatted list with a bang.