RFC: working on making chord naming/chordList more consistent

@tedthetrumpet @Raph @RTylerMclaughlin @kit-christopher @yaxu

This is my first foray into some actual haskell programming, I'm keen for your thoughts:

It's a (very) basic implementation of an open chord voicing - given a chord (which at this point needs to be 3 or more notes long), it takes the root and fifth (index 0 and 2), drops them an octave, then adds the third and any remaining notes untouched.

Major7:

*Sound.Tidal.ParseBP> runParser parseChord 0 "heck" "'maj7"
Right [0,4,7,11]
*Sound.Tidal.ParseBP> runParser parseChord 0 "heck" "'maj7'o"
Right [-12,-5,4,11]

Major13:

*Sound.Tidal.ParseBP> runParser parseChord 0 "heck" "'maj13"
Right [0,4,7,11,14,17,21]
*Sound.Tidal.ParseBP> runParser parseChord 0 "heck" "'maj13'o"
Right [-12,-5,4,11,14,17,21]

the code:

I get that it's super simple, but I think it will make most chords far more directly usable - feedback very welcome!

3 Likes

That's great. Using the same technique, it might be possible to implement the whole family of drop-n voicings : drop-2, drop-3, etc... These will definitely sound really jazzy / funky as they mimic what guitar / piano players do on a daily basis.

Your technique works great for orchestral textures and sound clouds. I think it's possible to go even further by completely exploding the voices on different octaves with some kind of factor defining the gravity of the explosion :thinking:. Playing with pads or arpegiated textures this way is fun and rewarding most of the time.

3 Likes

@Raph i long for the day when i can code explosion gravity into my compositions!

1 Like

yes! I had to read up on what the drop voicing entails, but that's totally doable!

where I see a sticking point, and this will just require some haskell knowledge (and learning on my part), is:

Currently the code is not equipped to handle the stacking of these ' (prime) chord modifiers - you can have 'ii OR you can have '6 but you cannot chain them together ala 'maj7'ii'6

In my opinion, they should be able to be stacked, and they should be processed left to right, because the order of processing will change the output
I'm certainly not equipped with haskell facilities to write this yet, but I'm happy to get working on it -

Notation decisions:
To add drop voicing, you could do it using maj7'dN - this would correspond nicely to the usual text notation for drop chords, however a precendent has been set in tidal already for inversions ('maj7'iii), so should we continue that using 'maj7'ddd instead?

Alternatively, we could introduce a breaking change (or an alternate notation) for inversions which could then apply to drop voicings:
'maj7'iN and 'maj7'dN

@yaxu (and everyone else following this thread) - what are your thoughts on this?

2 Likes

i love this idea and think it will really tidy up the existing inversion syntax (since it's kind of confusing anyway). i think things will get really fun when we can build patterns inside each of the chord arguments. (i've already opened a ticket about this). i would love to be able to pattern out inversions AND steps without having to resort to lengthy workarounds. below is an example of what i have in mind.

n (arp "down" "c'maj7'<i2 i3 d2!2>'<4 8 16>")

otherwise you'd have to type out something like 15 variations within angled brackets just to achieve the above.

3 Likes

Yeah, this is an excellent idea! Even further outside my skkllset to implement, but a very "tidal" endpoint😉

Thanks again @cleary for pushing the ball forward with these commits.

Drop voicings would be lovely. I agree 100% with @Raph , to me it's the natural extension of the open voicing 'o modifier.

Patterning them would be amazing. It would be a gateway into advanced, unfamiliar harmonies. Jazz pianists might even use TidalCycles to study new shapes. And i love the explode octaves idea haha.
This is really approaching a grammar of voicings. :slight_smile:

OK, so as cleary pointed out, order definitely matters with drops and inversions.
Here is a maj7 example, assuming these modifiers are chainable and left-associative:

[0,4,7,11]'ii'd2

apply second inversion -> [4,7,11,12]
apply drop 2 -> [4, -5, 11, 12] = [-5, 4, 11, 12]

[0,4,7,11]'d2'ii

apply drop 2 -> [-8, 0, 7, 11]
apply second inversion -> [0, 7, 11, 4] = [0, 4, 7, 11]

As this example illustrates, different chords are produced by swapping the modifiers.

It is interesting that the second chaining order ends up producing the original unmodified chord. Hmmm....

2 Likes

Hey all, it's a huge thread and I may have missed something.

I 100% love this. The idea that you can only invert a chord so far, aside from western theory heritage, doesn't follow the Zero-One-Infinity rule, and this is a very neat solution. I also miss a general invert function (as in invert 5 "0'min6")
edit: it would be dope being able to write "[0,2,4]'iN" for inverting anonymous chords

I wanna pitch in on this: music as data has benefits in itself. One can quickly try the same melody/voicing under different keys, for instance (good luck with that on a regular notation software).

About chords: this may sound kind of dumb, but how would you play an aliasless chord shape ("[0,4,7,13]", for instance) over a pattern using just mini-notation? You can only really do "<0 -4>" |+ "[0,4,7,13]" as far as I know. It's great to have 'maj7, 'maj6 and 'maj9, but these are not a universal solution - I can't say 'majm13 and expect the engine to understand that (quote below). We could do this though: "<0 4>'[maj,13]" by having the engine "stack" chord groups, and perform an addition when it matches an integer - the ' operator is really just a pattern addition with a lookup, if I understand it right.

This can be just personal, but one thing I find mildly frustrating is that s and f are eagerly evaluated, meaning scale "minor" "0 2s 4 7" is not a major arpeggio (evaluates to "0 5 7 12"), when it feels like it should be (as in "0 4 7 12"). This is because s is evaluated before the call to scale, but I don't really think that's what a user would expect to achieve. Similarly, typing scale "major" "0 2b 4 7" feels like it should be minor - isn't that how key signatures work in sheet notation? (flattening/sharpening 'escapes' the current key)

Anyway, this is a great thread, and it makes me super excited for the next tidal updates :smiley:

4 Likes

@ghales on @cleary ‘s point about inversion and drop “functions”—i.e. i3 instead of iii... yes 100%! Something like “[0,7,14,17, 22]’i5’d3” would combine chaining and “infinite” inversion and drop functions. (The “zero one infinity” idea really cleared this up for me.). This would address much of @kit-christopher’s suggestions too, I believe.

Euclidean functions in mini-notation “0,5,7” are the best precedent for this being possible (and eventually patternable), I think??? Unless I’m forgettting something?

Also, great point @ghales about sharping being a way to get outside the scale.

2 Likes

I would like to second Raph's suggestion about including some new syntactic sugar for defining our own pitch collections on the fly. I think the strength of Tidal is in how it does things differently and is fun and responsive sandbox environment. It would be great to be able to quickly define these pitch collections and then be able to transform them with inversions and drop or open voicings as well. Currently the discussion on harmony has been tertiary focused but implementing something like what Raph describes would make working in quartal, quintal, and secundal harmonies far easier and more flexible.

Edit: Also on a related note has anybody had experience with Euterpea and/or reading the Haskell School of Music? http://euterpea.com/haskell-school-of-music/. I have been slowing going through this book and it is actually quite awesome how it takes you step by step through the process of creating Euterpea and is a decent (if fast paced) intro to Haskell programming. Anyway I'm reading it currently while trying to learn Haskell with "Learn You a Haskell", so I'll report back about anything interesting I find that might give us some insight into how to proceed.

2 Likes

Some great stuff in here! I've skimmed quickly, and plan to revisit in detail but I'll just call out a couple of highlights:

This is cool! I think this could be a good next step on my learning journey

The concept of arbitrary pitch collections is something that is very present in my head when I'm thinking about this stuff - a set of common use chord shortcuts, and then the ability to quickly define and modify arbitrary note collections as though they were a standard chord, is an endpoint I'm hoping to get to

This looks from the outside like something I will need to work through too - thanks a lot!
as a side note, I have a selfish interest in using this project to advance my haskell skills in order to contribute more, but I am interested in seeing what others are coming up with too and my time is extremely limited, so please feel free to work on and share stuff that will move us along :slight_smile:

2 Likes

a couple more updates, I went back to the drawing board to redo my workflow so that I could separate breaking changes, dependent changes, etc so all the github links above don't really apply anymore (they still exist, but link to unattached forks).

I've made three PRs now,

  1. Adding domN and addN chords - merged
  2. Sorting and consistent naming changes - pending merged
  3. Add open voicing for chords 'o option - pending merged

None of these include any breaking changes, so I'm hoping they'll be acceptable to add to the next minor release (1.7.2).

...and with that, I think I've met the initial improvement targets. I've got a good idea of where I'll be heading from here, based on the comments, I think everyone is in agreement with that direction, namely:

  1. allow stacking of chord modifiers (ie 'maj7'ii'o'10 should work as expected) Issue #777
  2. add dropN notation (ie 'maj7'd2) @Raph
  3. update inversion notation in line with drop notation (ie 'maj7'i2 for second inversion) @RTylerMclaughlin
  4. allow patterning of the chord modifiers (eg 'maj7'i<2 3 4>) @kit-christopher Issue #620
  5. allow "exploding" chords ie spreading them over N octaves @Raph
  6. consider adding complementary functions for each of these modifiers (ie invert 2 "0'maj7" as a complement to "0'maj7'i2") @ghales
  7. define our own pitch collections on the fly, so that they can be manipulated/patterned in the same way as our predefined chords @Raph @wshbmusic

I would call these the intermediary steps, before we head into @jwaldmann's semantics territory -

If I get through this batch on my own, I will be in far better shape skill-wise to consider attacking the semantics application ... wish me luck! :slight_smile:

11 Likes

huge leap forward! so excited to see these changes come to fruition!

1 Like

eek I forgot one!

  1. added :slight_smile:

Nice one @cleary! I've merged the PRs. What could be really nice is having a list of expected mini-notation chords together with expected outputs. Then we can add that to the automated tests to catch regressions.

Thankyou!

Can do, I'll look at this next :+1:

1 Like

Hi,

hope this isn't is (1) a dump question: Is there a place where I can learn about the new chord naming conventions or is this knowledge right now only available within this thread?

(1) EDIT: oops... :wink: I really don't mean to ask dump question on purpose.

1 Like

Hi, this will be a place when it happens, I'll update the tidal cycles wiki as well

At this point there are no major changes, I've just made things more consistent (eg ref the m9 but no min9 mentioned above

Next change will be a test suite, then I'll probably start on the complementary functions option (6), which I think might be the next easiest task/best path to learn from.

None of these will introduce any changes to the current notation though

2 Likes

A quick update, I've procrastinated long enough and am looking at this again, beginning with the unit tests. I have a steep curve ahead, and it's slow going but if you're interested there's a branch here where I'm working:

3 Likes

chord test PR is in

Next on the list is to make 'o not crash when chord length is < 3 and add a test case :wink:

Then I may try and look at #777 - going to need some more steep learning I think

2 Likes