CompositeTuning
CompositeTuning uses the fractional part of the note index to choose from an array of tuning objects. The main intended usage is just intonation, since you may need to adjust in the interval ratios to suit different harmonic contexts.
*new(tunings)
Initializes the composite tuning object with the array of tuning objects supplied as the argument.
cps(noteindex)
value(noteindex)
For each note index (which may be a single value or an array), choose the correct tuning object from the array and ask it for the frequency value in Hz. The hundredths place determines which tuning will be used: 1.0 uses tunings[0], 1.01 uses tunings[1] and so on. Indexing is wrapped (wrapAt); if the index goes beyond the size of the array, one of the array elements will be used regardless.
The tuning object is addressed with the "value" message, so if needed, you can place a function in the array of along with tuning objects. Of course, you will not be able to calibrate the function, but that may be okay in some circumstances.
See the example below.
calibrate(freq = 440, noteindex = 69)
Delegates the calibrate message to all the tuning objects in the array, so that they will all be in tune at the reference pitch. If any of the array elements do not respond to "calibrate," they will be ignored.
Array methods for easier access:
size == how many tunings in the array
at(i) == tunings[i]
wrapAt(i) == tunings.wrapAt(i)
clipAt(i) == tunings.clipAt(i)
foldAt(i) == tunings.foldAt(i)
put(i, tuning) --> tunings[i] = tuning
wrapPut(i, tuning) == tunings.wrapPut(i, tuning)
clipPut(i, tuning) == tunings.clipPut(i, tuning)
foldPut(i, tuning) == tunings.foldPut(i, tuning)
do(func) --> tunings.do(func)
collect(func) --> tunings.collect(func)
Example forthcoming. This class is still experimental.