tonaljs / tonal

A functional music theory library for Javascript
https://tonaljs.github.io/tonal/docs
3.78k stars 217 forks source link

Voicing.get could be more general #228

Open felixroos opened 3 years ago

felixroos commented 3 years ago

Copied from https://github.com/tonaljs/tonal/pull/224#issuecomment-727252979

To allow adding other strategies to find voicings later (without needing to change Voicing.get / add a separate method).

Before:

function get(
  chord: string,
  range: string[] = defaultRange,
  dictionary = defaultDictionary,
  voiceLeading = defaultVoiceLeading,
  lastVoicing?: string[]
)

After:

function get(
  chord: string,
  voicingGenerator: VoicingGenerator,
  voiceLeading = defaultVoiceLeading,
  lastVoicing?: string[]
)

This method now has no hard wired connection to voicing dictionary. The voicingGenerator param expects a function that takes a chord and returns a set of intervals:

type VoicingGenerator = (chord: string) => IntervalSet;

As one way of generating voicings, we could create a generator with VoicingDictionary:

VoicingDictionary.generator(range, dictionary) => VoicingGenerator;

Example:

const lookup = VoicingDictionary.generator(['E3','D5'], lefthand);
lookup('C^7')
/*
  ["E3", "G3", "B3", "D4"],
  ["E4", "G4", "B4", "D5"],
  ["B3", "D4", "E4", "G4"],
*/

// in practice, we might directly pass the generator to Voicing.get:
const { topNoteDiff } = VoiceLeading;
const lastVoicing = ["C4", "E4", "G4", "B4"];
Voicing.get('F^7', lookup,  topNoteDiff, lastVoicing);
// ["C4", "E4", "F4", "A4"]

Currently, there is only one way of generating voicings (dictionary), but this call signature would allow adding others later (like voicing permutation).

Please tell me if this makes any sense? It is kind of abstract but I think it could be really powerful.

danigb commented 3 years ago

Yes, this is abstract (music theory is! 😂 ) but makes sense.

I really like the idea (agree is much powerful) but not sure still about the API. Let me give it some thoughts...

felixroos commented 3 years ago

@danigb haha I just added keyboard shortcuts to the sandbox. Check out my "interpretation" of giant steps 😆

felixroos commented 3 years ago

Update: The sandbox now evolved into a little app I call asdf-piano. The Voicing.search part is now controllable with arrow keys left and right + the voicings above and below the current selection will always use the tightest voice leading. Also added a hotkey to press the pedal. I'll use it as a test rig for the content of voicing-dictionary this weekend :relaxed:

danigb commented 2 years ago

Hi @felixroos

Was nice to meet you at wac. I'm planning to move tonal to "low maintenance only mode" (well: make explicit what it is: I'm not working in tonal anymore...).

Basically my idea is to solve some small issues, remove deprecated things and publish a 5.0 version. After that, work only on bug fixes or small compatibility updates.

So, regarding your voice packages, I don't know what to do with them. For me the options are:

Thoughts?

felixroos commented 2 years ago

Hey @danigb yes it was nice meeting you, sorry I vanished so quickly, maybe we meet again another day!

It's sad you don't want to develop tonal further but of course I respect the decision, also if you don't want to publish the voicings package as is.

I already made a repo with similar features: https://github.com/felixroos/chord-voicings for use in strudel, maybe that could be the starting point? Having this inside the tonaljs org will increase the chance for people to find it, which will increase the number of ears receiving nice chord voicings :)