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

Inversions #82

Open
mulhoon opened this issue May 18, 2015 · 9 comments
Open

Inversions #82

mulhoon opened this issue May 18, 2015 · 9 comments

Comments

@mulhoon
Copy link

mulhoon commented May 18, 2015

What is the easiest way of creating a chord inversion? i.e moving the root to the top
Am (A, C, E) -> (C, E, A)
Would it be useful to have a chord function for creating these?

Awesome library!

Thanks

@saebekassebil
Copy link
Owner

Hey Nic, and thank you very much!

There's no built-in support for inverting chords, because it should be pretty easy. Basically you just have to shift around the intervals you get from chord#voicing().

However, I just found out this is unnecessarily complex, because what you get back from chord#voicing() is Intervals, while, what you set is strings (Intervals in simpleFormat).

I'll have a look at how I can simplify that. Thanks for reporting!

@mulhoon
Copy link
Author

mulhoon commented May 19, 2015

Thanks so much!
At first I was thinking something like .inversion(1) .inversion(2) would be cool
Would that be too complex? or better to write as an external function?

Nic

@saebekassebil
Copy link
Owner

I actually find it a bit problematic that the chord objects are mutable. I think it might be better if they were immutable(?).

I think inversion functions are cool, but let me just think about whether they belong on teoria, or in a separate module.

What about:

var teoria = require('teoria');
var rotate = require('rotate-array');

var Am1 = teoria.chord('Am');
var Am2 = Am1.voicing(rotate(Am1.voicing(), 1));
var Am3 = Am2.voicing(rotate(Am2.voicing(), 1));

@mulhoon
Copy link
Author

mulhoon commented May 19, 2015

That would work fine for me if you'd rather it not be in teoria.
Do the voicings need changing to make this work?

@mulhoon
Copy link
Author

mulhoon commented May 19, 2015

I also had a thought that the new vars Am2 and Am3 would still have the chord name of 'Am' Would it be useful for example that, .name displays 'Am (1st inv.)' or maybe a readable flag that tells whether it has been inverted? Just a thought.

Thanks again,
Nic

@fenomas
Copy link

fenomas commented Jan 22, 2016

Just want to chime in that some kind of support for inversions would be really useful. I gather we're meant to do it ourselves, but for idiots like me the whole point of using teoria is that I'm not confident I understand how to do it correctly.

FWIW, right now I'm doing something like:

var vs = chord.voicing()
var vnames = vs.map(function(int){ return int.toString() })
vnames[0] = 'P8'
chord.voicing(vnames)

But I've no idea if that would be correct for all chords, etc.

@saebekassebil
Copy link
Owner

Hey Andy, thanks for chiming in! Eh, you're totally right we need abstractions for "not-expert" users. Let's look for a good way to do this. What kind of methods would be helpful to you?

Maybe?

chord.inversion() // Returns the current inversion (1, 2, 3, etc)
chord.invert() // Inverts the chord one more time (1 -> 2, 2 -> 3, 3 -> 1)
chord.invert(n) // Sets the inversion number directly

Can you think of something more please let me know :)

@fenomas
Copy link

fenomas commented Jan 23, 2016

Thank you for the great library Jakob!

Regarding your questions, the APIs you listed are basically what I'd hoped for, but you should take that with a grain of salt because I'm too much of a beginner to know if they make sense or not! (As a side note, would it make sense to also have invert(0) return the chord to the original voicing?)

As an alternate view, I'd originally supposed that inversions would be a matter of voicing, rather than the chord's notes, so I'd started writing myself a function like:

var c = teoria.chord('C');                 // c4, e4, g4
c.transposeVoicingByOctave([ 1, 0, -1 ]);  // c5, e4, g3

I gather that would let one construct any inversion one wanted. But looking at teoria's implementation I see that notes are derived from voicing, not the reverse, so perhaps fiddling with the voicing doesn't make sense. (In fact, if chords are best thought of as immutable, I'm not sure I should be calling that method at all. It essentially lets you overwrite the chord's notes, right?)

@BHSPitMonkey
Copy link

Just some thoughts on this:

If you don't like the idea of the Chord data model containing this kind of "state", then perhaps inversions could be computed on-the-fly:

var c = teoria.chord('C');
c.notes(); // Note objects: [c4 e4 g4]
c.notes(1); // Note objects: [e4 g4 c5]

This approach seems like it would undermine the purpose of Chord.bass(), however. If you could set the inversion of an existing Chord, then that function has an opportunity to make sense (though it would just return the first element of the array returned from notes()).

Personally, I'd like to be able to initialize a chord like "Am", then be able to independently modify its inversion and bass octave, and then finally retrieve an array of Note objects (with appropriate ordering and octaves), but I'm willing to work around whatever API design you prefer in the end - it's your project!

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

4 participants