Hi there,
Is there a way to convert integer and float to scientific pitch notation?
I have coded a function to do a similar thing as follows, but I would like to know if there is another way supported by sclang primitives or other quarks.
(
~midispn = { |aNumber|
var midispn = ();
(0, 0.5 .. 127).do { |quarterStep|
var quarterToneStep, octave;
quarterToneStep = [
\c, 'a quarter-tone raised c', 'c#', 'a quarter-tone raised c#',
\d, 'a quarter-tone raised d', 'd#', 'a quarter-tone raised d#',
\e, 'a quarter-tone raised e',
\f, 'a quarter-tone raised f', 'f#', 'a quarter-tone raised f#',
\g, 'a quarter-tone raised g', 'g#', 'a quarter-tone raised g#',
\a, 'a quarter-tone raised a', 'a#', 'a quarter-tone raised a#',
\b, 'a quarter-tone raised b'
][quarterStep * 2 % 24];
octave = (quarterStep / 12).floor - 1;
midispn.put(quarterStep.asSymbol, quarterToneStep ++ octave.asInteger)
};
midispn[aNumber.asFloat.asSymbol]
}
)
~midispn.(60)
~midispn.(69)
~midispn.(60.5)
~midispn.(61.5)
I’m not aware of anything that supports microtones. To be honest, I’m not aware of the existence of a scientific pitch notation to describe microtones and microtonal accidentals. Given the vast range of tuning systems (not all of which repeat at the octave), it seems like a daunting task.
Just freewheeling a bit here (and I 'd be surprised if nothing like this actually existed, somewhere, but I’m not aware of it):
A pragmatic approach might be to use an integer “scale degree” which is mapped to an actual frequency using a scala definition ( Scala scale file (.scl) format ). Accidentals then can be some fractional modifier which modifies the scale degree, and which logarithmically interpolate between the frequencies specified in the scala file.
E.g. consider this scala definition which defines a scale of 5 degrees, which repeat at the octave.
! 05-24.scl
!
5 out of 24-tET, symmetrical
5
!
100.00000
550.00000
650.00000
1100.00000
2/1
Each of the numbers above represent pitch modifiers (to be applied to a root frequency which, sadly, is not specified in scala) in cents (100 cents corresponds to a semi-tone in conventional 12 EDO tuning). This would give rise to a system of 5 “pitches”: “0”, “1”, “2”, “3”, “4”. (pitch 0 corresponds to a modifier of 0 cents, which is not explicitly listed in the scala definition)
The scala format does not define how the pitches relate to octave number but as a convention one might assign octave 0 to whatever is used as “root frequency”.
To denote a pitch 2 in the third octave, one could e.g. imagine writing “2(3)”. To denote a pitch halfway pitch 2 and 3 in the third octave, one could e.g. modify this into “2(3)(+0.5)”. Such notation can only be translated into frequencies in combination with a scala definition that describes what “2” means. The +0.5 fraction interpolates “logarithmically” (i.e. halfway in pitch space, not in frequency space) between the frequencies represented by “2(3)” and “3(3)”. Similarly, 2(3)(-0.75) would result in a pitches 3-quarters between pitches represented by 2(3) and 1(3). To avoid floating point accuracy issues, perhaps similar to scala, the fractional part could also be represented as a rational number: 2(3)(-3/4).
In case of scales that do not repeat at the octave (e.g. Bohlen-Pierce tuning divides a ratio 3:1 into equal parts instead of the normal 2:1), the name “octave number” is not accurate, but a number similar in spirit could be used, maybe one could call it the “interval number” instead of “octave number”.
If this seems like a reasonable approach, I think it should be possible to write a quark that, given a scala definition and a root frequency, can convert both ways between “scientific notation” and “frequency”.
Naming pitches and associating (or mapping) those pitches to specific frequencies are two different things, I think.
You mentioned scales spanning an octave. This is theoretically possible, but human pitch recognition is based on ‘octave equivalence’, regardless of culture, as far as I know. (I think ‘octave equivalence’ applies to all species of animals that can hear sound, but let’s stick with humans). The all-pitch naming system I know of is based on octave equivalence, and I think this approach is practically reasonable.
My question was simply how to translate integer and float for music notation. I limited the range to quarter notes because musicxml only allows 24 EDO notation. I would use 1/16, but this does not seem to work with the current version of musicxml.
And thanks for mentioning the Scala language. I will look into it when I can.
There’s a potential for misunderstanding here: I’m not referring to the Scala programming language, I’m referring to the scala program for microtonal music. See: https://www.huygens-fokker.org/scala/
Actually, in the world of microtonal music it is quite common to define scales that do not repeat at the octave. Perhaps the most widely used tuning to do so is the Bohlen-Pierce tuning (you can find a significant amount of Bohlen-Pierce music on youtube… here’s one I made a few years ago) which is based on a “tritave” (“3:1” ratio) as opposed to the octave (“2:1”).
I would actually like to make something like what I’ve described above (or perhaps something like a “microtonal version of Panola”), so I can play a bit with it, even if only as a proof of concept.
Yes, your suggestion is simpler and even better. I thought it should react to the number from 0 to 127, but with your logic it could go beyond that range. Great!
I think it is not good enough to make a PR because there are duplicate variable definitions in the different methods in a class such as pitchClasses as well as in the different classes such as quarterToneStep.
If this is just for you then ignore this, but since you mentioned a PR…
Have you considered using Lilypond’s format for pitch names to avoid reinventing the wheel
as - a sharp
af - a flat
bff - b double flat
bss - b double sharp
fqs - f quarter sharp
gtqf - g three quarter flat
When you convert from a number, the result shows a# which might be a little confusing as previously we have been writing it as as.
There is nothing ‘scientific’ about the naming here. Its just note names.
What does .cpsspn mean? Why not, .cpsname as wslib does? Speaking of, have you looked at the stuff from wslib, like Note and the .cpsname method? It doesn’t quite do what you want but you could easily alter it.
it just means the combination of note names with numbers as opposed to using tick marks - so a6 as opposed to a’’
I personally find blocks of note names not so readable ie “c# e g#” - I prefer to see notes in terms of harmonic function - so [1, 3, 5].inKey(‘c#’, \minor, 3).
I do see the utility in having \a3 as a thing, ultimately I found it more useful to separate the octave - so it is good also to have \a mean the pitch class ‘a’ (the equivalent of note: -2 in the default Event)
I could imagine for example students using patterns enjoying writing (note:\a, octave:3) or (freq: \a3) or (degree: [1, 3, 4, 6], root: \a)
I used to use “+” and “-” for quarter tones. “C#+” or “D-” for example. Easy to use and remember!
Recently I did a little test run for a system with all accidentals for ET-72 and eight-tone in haskell. It covers a lot of note names, but it’s maybe a bit too much for most things.
Euterpea is a great source to learn, the book is also very good. But unfortunately, it would not be trivial to implement any kind of microtones with it.
Yeah too bad. Mainly sharing because it’s related to Haskell & notation. It’s been ages since I used it. Maybe some of the higher level types are polymorphic enough to reuse?
Yes, I think there are many great ideas there. The :+: and :=: operators are interesting, since they construct a kind of tree data type, with vertical and horizontal leaves. It’s very appropriate to represent music scores.
data Orientation = H | V
deriving (Show)
data OrientedTree a
= Val a
| Group Orientation [OrientedTree a]
deriving (Show, Functor)
But the pitch level has a more simple approach. For example, the relation between pitches and intervals would fit very well with a vector space type.
@nathan@VIRTUALDOG@smoge
Thanks for your valuable opinions. I asked this question to be able to use these classes and methods, if they exist, to create music scores simply by constructing subclasses of the collection class, as introduced in the following post (One problem is that musicXML only seems to support quarter-tones at the moment. This would exclude other microtonal accidentals, although I would like to extend it at least up to sixteenth-tones.):
I have updated the methods suggested above a bit, added a new class SPN, and done my best to cover all your opinions as best I can:
Now sclang returns pitch names as an array containing all available pitch names. Please let me know if I missed anything.
SPN has three options for displaying the pitch name: \lily, \mus, and \ez. The default is \lily.
PitchClass is already in @josh’s Ctk Quarks, but my new methods for this class do not conflict with it. Also, my PitchClass supports quartertones. I would appreciate your opinion. I have not made a PR as I think it should be discussed before it is made.
Scientific pitch notation is a verbal expression, so the use of the Roman numeral to indicate the steps of a scale has nothing to do with it.
Anyway, what does 3 mean in .inkey('c#', \minor, 3)? Is it the octave number? Normally, a key name starting with an upper-case letter indicates a major key, and a key name starting with a lower-case letter indicates a minor key. So the second argument in .inkey() is not necessary if .inKey is only related to major-minor tonality. I have not been able to find the .inKey method, so I cannot say more at this time.
Using \a3 in events without .cps is a really good idea.
I have included LilyPond’s format for those users who are already used to LilyPond’s notation, although I am not sure how many SC users (especially beginners) are used to LilyPond’s pitch notation. I deliberately did not use LilyPond style pitch notation because it uses multiple characters for one accidental. The English naming system in LilyPond is not intuitive to me. The German naming system in LilyPond is very intuitive to me, but it is too long. The following are my own inventions (they are simpler than the LilyPond style):
Example 1 (currently used):
S: double-sharp
Q: three quarter-tone raised
s: sharp
q: quarter-tone raised
n: natural ← can be omitted
u: quarter-tone lowered is not used
f: flat
U: three quarter-tone lowered is not used
F: double-flat
Example 2:
S: double-sharp
R: three quarter-tone raised
r: sharp
n: quarter-tone raised
o: natural ← can be omitted
l: quarter-tone lowered
f: flat
L: three quarter-tone lowered
F: double-flat
Example 3:
S: double-sharp
M: three quarter-tone raised
s: sharp
m: quarter-tone raised
o: natural ← can be omitted
w: quarter-tone lowered
f: flat
W: three quarter-tone lowered
F: double-flat
Example 4:
M: double-sharp
m: three quarter-tone raised
N: sharp
n: quarter-tone raised
o: natural ← can be omitted
v: quarter-tone lowered
V: flat
w: three quarter-tone lowered
W: double-flat
There are different systems for naming pitches.
In wslib’s cpsname, the middle A (440 Hz) is A3, while the ‘Scientific Pitch Notation’ defines it as A4. In South Korea, I am used to 440 Hz as A3 with the earlier generations involved in computer music, A4 in the group of musicians and music theorists as well as your generation in the computer music field, and in Germany as a' or a1. I think A4 is generally easier for most musicians, especially in English-speaking cultures and perhaps most of the world. In computer music, A3 seems to have been widely used for 440 Hz before, but I see that many software programs offer both names (A3 and A4) according to the user’s preference. I am also familiar with Helmholz pitch notation, but this would not be considered.
@josh
In the first draft, I omitted all pitch names with flats because they are redundant under some conditions. Under other conditions, however, they are very important. Under other conditions double flats and double sharps, even triple sharps and triple flats should be considered. I just wanted to simplify these things…
I think such pitch names should be added if some users or developers think they should be there. So I did it. If I just add all the flat names, someone might ask how to get double-flatted pitch and double-sharped pitch etc. So I upload a version that includes all possibilities (N.B.: This time I also used musical symbols to improve readability, but I am not sure if it really improves readability.):
Overview of use:
(The definitions of the methods and classes are at the bottom of the post.)
What do you think about the following hierarchy and structure of notes and rests?
I think it would be better to remove SPN and PitchClass from the notation scheme I am proposing…
Notation: a subclass of the class Object, and an abstract parent class for ‘Notation Library’.
├ Attribute: an abstract parent class for its subclasses
╎ ├ Staff
╎ ├ Clef
╎ ├ Tempo
╎ ├ TimeSignature
╎ └ KeySignature
├ Entry: an abstract parent class for its subclasses
╎ ├ Intensity: a class that creates an instance of an Intensity class
╎ ├ I: the abbreviation of Intensity
╎ ├ Hairpin: a class that creates an instance of a hairpin
╎ ├ H: the abbreviation of Hairpin
╎ ├ Rest: a class that creates an instance of a rest
╎ ├ R: the abbreviation of Rest
╎ ├ Note: an abstract class for each pitch class name and the attachment to the note instance:
╎ ╎├ A: a class that creates an instance of note utilising the pitch class a
╎ ╎├ B: a class that creates an instance of note utilising the pitch class b
╎ ╎├ C: a class that creates an instance of note utilising the pitch class c
╎ ╎├ D: a class that creates an instance of note utilising the pitch class d
╎ ╎├ E: a class that creates an instance of note utilising the pitch class e
╎ ╎├ F: a class that creates an instance of note utilising the pitch class f
╎ ╎├ G: a class that creates an instance of note utilising the pitch class g
╎ ╎├ Articulation: a class that creates an instance of articulation for an instance of note
╎ ╎├ U: the abbreviation of Articulation
╎ ╎├ Tie: a class that creates an instance of tie for an instance of note
╎ ╎├ T: the abbreviation of Tie
╎ ╎├ Slur: a class that creates an instance of slur for an instance of note
╎ ╎└ S: the abbreviation of Slur
etc.
An instance of Rest can be created as follows:
R.4: rest 1/4 ← It is currently not possible in sclang.
R.c: rest 1/4 (crochet rest)
R.q: rest 1/4 (quarter rest)
R.4d: rest dotted 1/4 ← It is currently not possible in sclang.
R.cd: rest dotted 1/4 (dotted crochet rest)
R.qd: rest dotted 1/4 (dotted quarter rest)
R.8: rest 1/8 ← It is currently not possible in sclang.
R.v: rest 1/8 (quaver rest)
R.e: rest 1/8 (eighth rest)
R.8d: rest dotted 1/8 ← It is currently not possible in sclang.
R.vd: rest dotted 1/8 (dotted crochet rest)
R.ed: rest dotted 1/8 (dotted quarter rest)
etc.
An instance of Note can be created as follows:
(All methods starting with integer are currently not possible in sclang.)
A.n.4.4: a quarter note of the A natural in octave 4. MIDI pitch number 69.
g.x.4.c: a quarter note of the G double sharps in octave 4. MIDI pitch number 69.
B.ff.4.q: a quarter note of the B double flats in octave 4. MIDI pitch number 69.
A.qs.4.4d: a dotted quarter note of a quarter-tone higher than A in octave 4. MIDI pitch number 69.5.
B.tqf.4.cd: a dotted quarter note of three quarter-tone lower than B in octave 4. MIDI pitch number 69.5.
A.s.4.4dd: a double-dotted quarter note of the A sharp in octave 4. MIDI pitch number 70.
B.f.4.cdd: a double-dotted quarter note of the B flat in octave 4. MIDI pitch number 70.
C.ff.5.qdd: a double-dotted quarter note of the C double flat in octave 5. MIDI pitch number 70.