To reduce typing!
We should use one of the subclasses of the collection class to handle note name, i.e. step in muscXML, and its accidental, i.e. alter in sclang:
~thisPitchClass = [\c, \n] // step, alter
~thisPitchClass = (step: \c, alter: \n)
In real use we also need octave:
~thisPitch = [\c, \n, 4] // step, alter, octave
~thisPitch = (step: \c, alter: \n, octave: 4)
If we use this as a symbol, we can easily combine ‘step’, ‘alter’ and ‘octave’ and parse the symbol via asString into each of them:
~pitchCombiner = { |step, alter, octave| (step ++ alter ++ octave).asSymbol }
(
~pitchParser = { |aPitch|
var string, size, step, alt, octave;
string = aPitch.asString;
size = aPitch.asString.size;
step = string[0];
alt = string[1 .. size - 2];
alt = if (alt[0] == $n || (alt[0] == $s) || (alt[0] == $f) || (alt[0] == $q) || (alt[0] == $t)) {
alt
} {
alt.asFloat
};
octave = string[size-1];
(step: step, alt: alt, octave: octave)
}
)
~pitch1 = ~pitchCombiner.(\a, \qs, 4)
~parsedPitch1 = ~pitchParser.(~pitch1)
[~parsedPitch1[\step], ~parsedPitch1[\step].class]
[~parsedPitch1[\alt], ~parsedPitch1[\alt].class]
[~parsedPitch1[\octave], ~parsedPitch1[\octave].class]
~pitch2 = ~pitchCombiner.(\a, 0.5, 4)
~parsedPitch2 = ~pitchParser.(~pitch2)
[~parsedPitch2[\step], ~parsedPitch2[\step].class]
[~parsedPitch2[\alt], ~parsedPitch2[\alt].class]
[~parsedPitch2[\octave], ~parsedPitch2[\octave].class]
I’m not sure I understood your question correctly…
In my system, the output of a pitch or pitchclass query is an array. For example, midinote 60 or \c4 will return:
69.midispn // -> [ a4, gx4, bff4 ]
69.midispn(\mus) // -> [ a♮4, g𝄪4, b𝄫4 ]
440.cpsspn // -> [ a4, gx4, bff4 ]
440.cpsspn(\mus) // -> [ a♮4, g𝄪4, b𝄫4 ]
69.5.midispn // -> [ aqs4, btqf4, gxqs4, bffqs4, cffqf5 ]
69.5.midispn(\mus) // -> -> [ a ¼↑ 4, b♭ ¼↓ 4, a♯ ¼↓ 4, g𝄪 ¼↑ 4, b𝄫 ¼↑ 4, c𝄫 ¼↓5 ]
452.89298412314.cpsspn // -> [ aqs4, btqf4, gxqs4, bffqs4, cffqf5 ]
452.89298412314.cpsspn(\mus) // -> -> [ a ¼↑ 4, b♭ ¼↓ 4, a♯ ¼↓ 4, g𝄪 ¼↑ 4, b𝄫 ¼↑ 4, c𝄫 ¼↓5 ]
0.pitchClass // -> [ c, bs, dff, c♮, b♯, d𝄫, cn, c, bs, dF ]
and each element in a pitch or a pitch class returns the same frequency or MIDI pitch number:
\a4.midi // -> 69.0
\a4.cps // -> 440.0
\gx4.midi // -> 69.0
\gx4.cps // -> 440.0
\bff4.midi // -> 69.0
\bff4.cps // -> 440.0
\a.pitchClass // -> 9.0
\gss.pitchClass // -> 9.0
\bff.pitchClass // -> 9.0
\gx.pitchClass // error.... I should correct it.
So in my system there is no need to calculate enharmonic pitches when converting. However, there should be a calculation if your question is from a different perspective. Please let me know if my answer is based on a misunderstanding of your question.
It is not in my system, but sclang provides differentiate
and -
. So I could use them:
[\a4.midi, \a5.midi].differentiate[1..]
\a5.midi - \a4.midi
This only returns semitones. So I need to build a dictionary of intervals. Here I need to consider enharmonic intervals, so I should build the output as an array again.
I have not implemented the interval, but I could implement it.
Thank you for your question. Answering your question makes me very happy and has given me a wider perspective!