librosa icon indicating copy to clipboard operation
librosa copied to clipboard

Just intonation and non-western systems

Open bmcfee opened this issue 1 year ago • 4 comments

Forking this issue off from a side discussion in #1402. Now that we have a pretty stable implementation of VQT, just intonation interval construction, and translation of these intervals into western notation (via FJS), we should circle back and fill in the implementation for Indian notation systems (and others that we might want to support going forward).

Tagging @kaustuvkanti @sertansenturk @vrangasayee @hideodaikoku @hskaushik for any insight they might have here.

Carnatic notation

Back in #641 we made an early decision to lock down to an ET grid and treat svara the same way we do pitch classes in western notation. That is, Ri1 and Ri2 were treated as different spellings of the same pitch class dependent on the raga, just like C# and Db would be enharmonically equivalent and choice between the two is governed by key.

However, if we adopt the 22 sruti scheme, we now have the option to treat this a bit more carefully, since it separates Ri1 = 32/31, Ri2=16/15, etc. This is similar to how we can now separate C# from Db in a JI system.

It would be easy enough to add intervals='sruti22' as an option to VQT, equivalent to:

intervals = [1, 32/31, 16/15, 10/9, 9/8, 32/27, 6/5, 5/4, 81/64, 4/3, 27/20, 45/32, 64/45, 3/2, 128/81, 8/5, 5/3, 26/16, 16/9, 9/5, 15/8, 31/16]

This is not something easily generated by the crystal algorithm, but it seems to be well-enough established that we can just hard-code it. This would give us a 22-bin-per-octave representation that would be (i think?) universal at least for the melakarta system.

It does lead to some interesting API questions though. A few thoughts:

  1. We could think of the full sruti22 set as akin to a "chromatic" base representation. Note that many of the intervals are very close to each other, which will wreck the time resolution of the VQT (ie we'll need very wide filters to distinguish them). If a user knows which raga they're working with though, we could provide a more "diatonic" interval set based just on those in-raga intervals. These could be keyed on raga name or number, just like we do for svara spelling already, eg intervals='mela22' or intervals='kanakangi' would make a 7-bin interval set. Would this be useful?
  2. If we do the above, it seems like not a huge jump to do similar things for western notation. Eg, intervals='major', intervals='dorian', etc. These again would be hard-coded to a fixed set of 7 intervals per octave.

Would these be useful? One potentially non-obvious implication is that it would smear together out-of-key notes, rather than omit them. Maybe that's okay?

  1. Separating out these svara classes does raise some questions about note spelling, that will run us into similar territory to the SPN vs FJS conversions earlier in-thread. I imagine that what should happen here is a separate conversion function intervals_to_svara which would drive hz_to_svara just as hz_to_fjs above.

This would be easy enough to implement, but we'll need to be a little careful in how this gets wired up to axis decorations. We currently use mela_to_degrees to pluck out a subset of 12 to decorate. I expect that we might want to expand this to have an option of selecting from 22 instead of 12, but maybe there's a simpler path forward that I'm not seeing just yet.

Hindustani notation

I imagine that most of the above observations for Carnatic would generally apply to Hindustani as well (with appropriate modifications), though I'm less familiar with the details there. Any help thinking this through would be much appreciated!

Makam

Way out of my element here :sweat_smile: but I think it would be within reach. Is there a good reference we can rely on for interval sets and notation here?

Originally posted by @bmcfee in https://github.com/librosa/librosa/issues/1402#issuecomment-1205326226

bmcfee avatar Jun 15 '23 11:06 bmcfee