Closed napulen closed 2 years ago
Thanks for the thoughtful comments!
I will unpack all of the acronyms and let you know when it's done.
As for citing: a lot of the functions implemented in the library are either novel, or "organic", such that they do not have documented authorship. The ones that do, often carry the author's name in the name of the function, and those have the reference in the description.
For instance in scale.get.lerdahl_attraction()
, edo.get.maximal_carey_coherence_failures()
, scale.count.rahn_differences()
, etc. all include a citation to the paper that describes the algorithm.
Lastly, I can see where the documentation may be confusing and I will make effort to make it clearer. Specifically, your comments make me think that the tuning aspect of the library is not emphasized enough.
Let me clarify here first, and hopefully, I'll find a way to make it clearer in the documentation as well. I see why you prefer "specified in semitones" over "specified in PCs". However, those phrases are interchangeable only in 12EDO.
In 12EDO, the pitch-classes [4 9] (like you say) represent 4 and 9 semitones above 0. However, in 24EDO the pitch-classes [4 9] represent 4 and 9 quarter-tones above 0 (as the octave in this tuning is divided into 24 equal parts, not 12, hence quarter-tones rather than semitones). A more extreme example: in 1200EDO, where the octave will be cut into 1200 parts, [4 9] will represent 4 and 9 cents above 0. For that reason, I must keep the less intuitive, but more accurate "specified in PCs" wording. Where the pitch classes have different sizes in different tunings.
Similarly, the difference between chord_quality([4]) and M3s() is a practical and a conceptual one. chord_quality([4]) "thinks" in terms of set-theory and M3s are calculated by finding the closest pitch-classes to an acoustic ratio of 5:4 (with a default tolerance of 20 cents)
So if we had 3 tuning contexts:
let edo12 = new EDO(12) //12 equal divisions of the octave - Standard
let edo17 = new EDO(17) //17 equal divisions of the octave
let edo31 = new EDO(31) //31 equal divisions of the octave - Turkish tuning
//Let's define a basic (seemingly) "major" scale in all contexts
let scale12 = edo12.scale([0,2,4,5,7,9,11])
let scale17 = edo17.scale([0,2,4,5,7,9,11])
let scale31 = edo31.scale([0,2,4,5,7,9,11])
//in the scale [0, 2, 4, 5, 7, 9 ,11] [4] can be found in [0 4] [5 9] [7 11]
//Because the pitch classes are the same, the following output is not surprising
scale12.count.chord_quality([4]) // returns 3
scale17.count.chord_quality([4]) // returns 3
scale31.count.chord_quality([4]) // returns 3
But, in edo12 a Major 3rd corresponds to an interval of size [4], in edo17 there's no interval within 20 cents of a 5:4 ratio, and in edo31 a Major 3rd corresponds with an interval of size [10].
Therefore:
scale12.count.M3s() // as expected returns 3
scale17.count.M3s() // returns 0 because acoustically there's no major 3rds in 17EDO
scale 31.count.M3s() // returns 0 as well, because while 31EDO has Major 3rds, the given pitches in THIS tuning do not contain a major 3rd ([10])
As you can see, this is not so trivial. I will try to make this clearer in the documentation.
You may want to check out this demo to gain some intuition. I encourage you to change the number of divisions from the default 12 to something else: https://michaelsel.github.io/edoJS/demos/scale_explorer2.html
As for citing: a lot of the functions implemented in the library are either novel, or "organic", such that they do not have documented authorship. The ones that do, often carry the author's name in the name of the function, and those have the reference in the description. For instance in scale.get.lerdahl_attraction() , edo.get.maximal_carey_coherence_failures(), scale.count.rahn_differences(), etc. all include a citation to the paper that describes the algorithm.
My bad. You are right! Thanks for the clarification.
Let me clarify here first, and hopefully, I'll find a way to make it clearer in the documentation as well. I see why you prefer "specified in semitones" over "specified in PCs". However, those phrases are interchangeable only in 12EDO. In 12EDO, the pitch-classes [4 9] (like you say) represent 4 and 9 semitones above 0. However, in 24EDO the pitch-classes [4 9] represent 4 and 9 quarter-tones above 0 (as the octave in this tuning is divided into 24 equal parts, not 12, hence quarter-tones rather than semitones). A more extreme example: in 1200EDO, where the octave will be cut into 1200 parts, [4 9] will represent 4 and 9 cents above 0. For that reason, I must keep the less intuitive, but more accurate "specified in PCs" wording. Where the pitch classes have different sizes in different tunings.
I see what you mean.
To me, the concept of pitch class is still somewhat incorrect in this context, because the function will transpose those pitch classes. If I understand correctly the logic of
let scale = edo.scale([0,2,4,5,7,9,11]) //define new scale (Major)
//Major 7th
scale.count.chord_quality([4, 7, 11]) //returns 2
It will count [0, 4, 7, 11]
and [5 9, 0, 4]
, where (9, 0, 4)
are not the pitch classes you indicated in the input but transpositions of them. To me, that speaks of your input as intervals, not pitch classes.
Still, I understand your point. Semitones are not a generalizable intervallic unit beyond 12EDO.
How about intervallic unit as a general term to replace semitone in this context?
In 12EDO, the intervallic unit is a semitone In 24EDO, the intervallic unit is a quartertone In 1200EDO, the intervallic unit is a cent
Your input accepts a list of intervallic units from the root.
This is probably outside the scope of the review. Just making for some discussion.
I must admit that I almost exclusively work on 12EDO, so I have found this project very useful in revealing my own biases :).
You may want to check out this demo to gain some intuition. I encourage you to change the number of divisions from the default 12 to something else: https://michaelsel.github.io/edoJS/demos/scale_explorer2.html
Pretty cool demos, by the way!
I absolutely love you suggested term. I updated the documentation where appropriate. Where I must use "pitch classes" I added the remark: "pitch classes" according to the current tuning system used. 0-11 in 12EDO, 0-16 in 17EDO, etc.
The edits on the documentation look good. In my opinion, it reads better now.
This was a nice discussion! Closing now.
This issue is related to the following review: https://github.com/openjournals/joss-reviews/issues/3784
I was playing around with a few functions of the library on my browser (e.g., chord_quality).
First of all, kudos for providing at least one example (with output) of every function! This was very useful when playing with the library.
Secondly, here are a few comments for improving the documentation:
PCs
, but relying on unexplained acronyms makes the text harder to approach. I'd prefer to have each acronym expanded at least the first time it is used in a given page. This would make the documentation easier to approach.edo.js
implementing algorithms from the music research literature[^1], however, in the documentation, the relationship between major algorithms in music research and custom functions is not clearly presented. In most music-processing libraries, a reference to the source publication/algorithm is shown in the API documentation. See, for example, theReferences
sections of librosa, madmom, or essentia. Something similar here would be very useful.chord_quality
doeschord_quality([4])
andM3s()
? Is it just a shortcut? This would be useful in the documentationTake all these, especially the third point, as suggestions. I understand it would require a significant amount of work to implement.
[^1]: The precise claim is: EDO.js implements major algorithms presented in the music theory and music cognition literature (e.g., Balzano, 1982; Carey, 2007; Carey & Clampitt, 1989; Lerdahl &10 others, 2001; Rahn, 1991; Vassilakis, 2001)