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

Make it possible to create interval from semitones #120

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

automata
Copy link

@automata automata commented Sep 5, 2017

I was looking for a way to create an interval from number of semitones from a reference note, something similar with music.js's Interval.fromSemitones().

It's a bit verbose (please let me know if there's a better way), but it works as expected:

teoria.Interval().fromSemitones(0).name()  // => 'unison'
teoria.Interval().fromSemitones(1).name()  // => 'second'

I also added a helpful method to transpose a note without mutating it:

c = teoria.note('c')
c.name()  // => 'c'
c.transposeNew(teoria.Interval().fromSemitones(1)).name() // => 'd'
c.name()  // => 'c' (no changes on original note)

With the original Note.transpose() method we change the note itself:

c = teoria.note('c')
c.name()  // => 'c'
c.transpose(teoria.Interval().fromSemitones(1)).name() // => 'd'
c.name()  // => 'd' (note changed)

Please let me know if there's something I can improve on the PR. I'm actually using it on this live coding language where it's handy to create notes from intervals defined by semitones.

@AtActionPark
Copy link

Im currently working on a music theory library as well, and had to tackle the same issue.

A number of semitones is not enough to define an interval, because of the existence of enharmonic intervals (ex augmented fourth and diminished 5th both have a distance of 6 semitones).

If you only care about the pitch class or the frequency of the resulting notes, this is not a problem, and will indeed work, but this can not be implemented naively in a musical theory library imo

@saebekassebil
Copy link
Owner

AS @AtActionPark is saying, this isn't really possible to do "correctly", because an interval of 6 semitones can both be an #4 or b5, and 2 semitones can be M2 og d3. What I think is doable is to make a function that returns all possible intervals for a given semitone-defined interval. So:

Interval.fromSemitones(6) -> ['A4', 'd5']

ordered after what interval is most common. (M2 over d3, etc).

@saebekassebil
Copy link
Owner

I think i've already implemented something like that in https://github.com/saebekassebil/piu - maybe you could rip that functionality out, make it its own module, and I'd be happy to include it in teoria :)

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

Successfully merging this pull request may close these issues.

3 participants