Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microtonal systems #9

Closed
infojunkie opened this issue Jan 16, 2016 · 5 comments
Closed

Microtonal systems #9

infojunkie opened this issue Jan 16, 2016 · 5 comments

Comments

@infojunkie
Copy link

Related to #2, it would be great to support microtonal systems https://en.wikipedia.org/wiki/Microtonal_music. I am especially interested in Turkish/Arabic scales but having a flexible tuning framework that goes beyond 12 semitones would be very valuable for experimentation and composition.

@daveyarwood
Copy link
Owner

I totally agree!

Now that you mention it, I think it would be nice if this library supported non-Western music theory in general. For instance, being able to use Swara terminology when specifying notes, eg. (->note "dha4") might be a nice feature.

As far as microtones go, we could start by allowing some way of specifying half-flats and half-sharps -- that might be sufficient to cover your maqam use-case. As far as I know (which isn't terribly much) with maqam, it's standard to notate music using Western notation, so you could represent maqam rast as C D Ehb F G A Bhb C. I'm open to suggestions for how to represent half-flats and half-sharps in a convenient way -- hb and h# might be OK choices.

Three-quarter tone flat and sharp would be nice to have, too, although I have no idea what a good syntax would be for those.

I'm all in favor of adding in even more experimental things, like some sort of framework for creating things like Partch's 43-tone scale, but I'm not sure what the API would look like for things like that, how the notes would be represented, etc.

I'm very open to suggestions on all of this, PRs also welcome of course.

@infojunkie
Copy link
Author

Great, thanks!

Actually, the Turkish/Arabic tone system is more subtle than so-called quarter tones, no matter what Wikipedia says :-) The whole tone is divided into 9 "commas", from which some tones are used in scales. Screenshot attached from a great reference, Eric Ederer's "Makam and Beyond: A Progressive Approach to Near Eastern Music Theory".
screenshot from 2016-01-16 12 03 46

I will post more thoughts on the architecture of a flexible representation system, once they crystallize :-)

@daveyarwood
Copy link
Owner

I see... intriguing!

One thing to consider is that we could use dynamic vars to set the context for representation. So say we added a *music-system* var which defaults to :western. (->note :Eb4) could evaluate to note number 63 like it does currently, but (binding [*music-system* :turkish] (->note :Eb4)) might evaluate to a note with a different number that has some significance under that system. This would give us the power to use the same notation to mean different things for different cultures.

So far I've been representing note numbers as unbound MIDI note numbers (e.g. 60 is C4, 69 is A4, and if you want you can have notes above or below the 0-127 range of MIDI notes), but it might make sense to allow different music systems to have different meanings for these numbers. Dynamic vars make it easy to set up and work with different contexts like these, so there is some flexibility there.

@infojunkie
Copy link
Author

Explicitly declaring the tuning system when referring to notes is what I had in mind also. Since my clj-fu is not strong, I need to understand the concept of dynamic vars.

@daveyarwood
Copy link
Owner

The idea with dynamic vars is that their value can be different, depending on how you bind them, but the original/default value never changes.

Probably the best way to explain how they work is by example:

boot.user=> (def ^:dynamic *foo* 42)
#'boot.user/*foo*
boot.user=> *foo*
42
boot.user=> (binding [*foo* 9999] *foo*)
9999
boot.user=> *foo*
42

The binding even extends into functions that use the dynamic vars:

boot.user=> (defn get-foo [] *foo*)
#'boot.user/get-foo
boot.user=> (get-foo)
42
boot.user=> (binding [*foo* 12345] (get-foo))
12345
boot.user=> *foo*
42

A common use for dynamic vars is for configuration variables with defaults. We can set an initial or default value when we define them, and then use *binding* whenever we want to use another value dynamically, without affecting the original/default value.

I've added a few to this library already: https://github.com/daveyarwood/music-theory/blob/master/src/music_theory/pitch.cljc#L6-L9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants