diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index bd8b35ed..d83e271f 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -579,6 +579,7 @@ const generic_params = [ ['dictionary', 'dict'], // which dictionary to use for the voicings ['anchor'], // the top note to align the voicing to, defaults to c5 ['offset'], // how the voicing is offset from the anchored position + ['octaves'], // how many octaves are voicing steps spread apart, defaults to 1 [['mode', 'anchor']], // below = anchor note will be removed from the voicing, useful for melody harmonization /** diff --git a/packages/tonal/index.mjs b/packages/tonal/index.mjs index 15eb9c4a..fc1b7f97 100644 --- a/packages/tonal/index.mjs +++ b/packages/tonal/index.mjs @@ -3,3 +3,5 @@ import './voicings.mjs'; export * from './tonal.mjs'; export * from './voicings.mjs'; + +import './ireal.mjs'; diff --git a/packages/tonal/ireal.mjs b/packages/tonal/ireal.mjs new file mode 100644 index 00000000..e6faef9e --- /dev/null +++ b/packages/tonal/ireal.mjs @@ -0,0 +1,523 @@ +// explore them here: https://codesandbox.io/s/voicing-explorer-ireal-47tkx5?file=/src/ireal.js:0-16036 +// scraped via: https://codesandbox.io/s/ireal-midi-scraper-2-gjz2mr?file=/src/index.js + +export const simple = { + 2: ['1P 5P 8P 9M', '1P 5P 8P 9M 12P', '5P 8P 9M 12P'], + 5: ['1P 5P 8P 12P', '5P 8P 12P 15P'], + 6: ['1P 5P 6M 8P 10M', '1P 5P 8P 10M 13M', '3M 5P 8P 10M 13M', '5P 8P 10M 12P 13M'], + 7: [ + '1P 5P 7m 8P 10M', + '1P 7m 8P 10M 12P', + '3M 7m 8P 10M 12P', + '3M 7m 8P 10M 14m', + '3M 7m 10M 12P 15P', + '7m 10M 12P 14m 15P', + '7m 10M 12P 15P 17M', + ], + 9: [ + '1P 5P 7m 9M 10M', + '1P 7m 9M 10M 12P', + '3M 7m 8P 9M 12P', + '7m 9M 10M 14m 15P', + '3M 7m 8P 12P 16M', + '7m 10M 12P 15P 16M', + ], + 11: ['1P 5P 7m 9M 11P', '5P 7m 8P 9M 11P', '7m 8P 9M 11P 12P', '7m 8P 11P 12P 16M'], + 13: ['1P 6M 7m 9M 10M', '1P 7m 9M 10M 13M', '3M 7m 8P 9M 13M', '7m 8P 9M 10M 13M', '7m 9M 10M 13M 15P'], + 69: ['1P 5P 6M 9M 10M', '1P 5P 9M 10M 13M', '3M 5P 8P 9M 13M', '5P 8P 9M 10M 13M'], + add9: ['1P 5P 8P 9M 10M', '1P 5P 9M 10M 12P', '3M 8P 9M 10M 12P', '3M 8P 9M 12P 15P', '5P 8P 9M 12P 17M'], + '+': [ + '1P 3M 6m 8P 10M', + '1P 6m 8P 10M 13m', + '3M 6m 8P 10M 13m', + '3M 8P 10M 13m 15P', + '6m 8P 10M 13m 15P', + '6m 10M 13m 15P 17M', + ], + o: ['1P 5d 8P 10m 12d', '3m 8P 10m 12d 15P', '5d 8P 10m 12d 15P'], + h: [ + '3m 5d 7m 8P 10m', + '1P 5d 7m 10m 12d', + '3m 7m 8P 10m 12d', + '3m 7m 8P 12d 14m', + '5d 7m 8P 10m 14m', + '5d 8P 10m 12d 14m', + '7m 10m 12d 14m 15P', + '5d 8P 10m 14m 17m', + ], + sus: ['1P 4P 5P 8P', '1P 4P 5P 8P 11P', '5P 8P 11P 12P', '5P 8P 11P 12P 15P'], + '^': ['1P 5P 8P 10M', '1P 5P 8P 10M 12P', '3M 5P 8P 10M 12P', '3M 8P 10M 12P 15P', '5P 8P 10M 12P 15P'], + '-': ['1P 3m 5P 8P 10m', '1P 5P 8P 10m 12P', '3m 5P 8P 10m 12P', '5P 8P 10m 12P 15P'], + '^7': ['1P 5P 7M 10M 12P', '1P 10M 12P 14M', '3M 8P 10M 12P 14M', '5P 8P 10M 12P 14M', '5P 8P 10M 14M 17M'], + '-7': [ + '1P 3m 5P 7m 10m', + '1P 5P 7m 10m 12P', + '3m 7m 8P 10m 12P', + '3m 7m 8P 10m 14m', + '5P 7m 8P 10m 14m', + '7m 10m 12P 14m 15P', + '5P 8P 10m 14m 17m', + '7m 10m 12P 15P 17m', + ], + '7sus': ['1P 5P 7m 8P 11P', '5P 8P 11P 12P 14m', '7m 8P 11P 12P 14m', '7m 11P 12P 14m 18P'], + h7: [ + '3m 5d 7m 8P 10m', + '1P 5d 7m 10m 12d', + '1P 7m 10m 12d', + '3m 7m 8P 10m 12d', + '3m 7m 8P 12d 14m', + '5d 7m 8P 10m 14m', + '5d 8P 10m 12d 14m', + '7m 10m 12d 14m 15P', + '5d 8P 10m 14m 17m', + ], + o7: [ + '1P 6M 8P 10m 12d', + '1P 6M 10m 12d 13M', + '3m 8P 10m 12d 13M', + '3m 8P 12d 13M 15P', + '5d 10m 12d 13M 15P', + '5d 10m 13M 15P 17m', + '6M 12d 13M 15P 17m', + '6M 12d 15P 17m 19d', + ], + '^9': [ + '1P 5P 7M 9M 10M', + '1P 7M 9M 10M 12P', + '3M 7M 8P 9M 12P', + '3M 7M 8P 12P 16M', + '5P 8P 10M 14M 16M', + '7M 8P 10M 12P 16M', + ], + '^13': ['1P 6M 7M 9M 10M', '1P 7M 9M 10M 13M', '3M 7M 8P 9M 13M', '3M 7M 8P 13M 16M', '7M 8P 10M 13M 16M'], + '^7#11': ['1P 5P 7M 10M 12d', '3M 7M 8P 10M 12d', '1P 7M 10M 12d 14M', '3M 7M 8P 12d 14M', '5P 8P 10M 12d 14M'], + '^9#11': ['1P 3M 5d 7M 9M', '1P 7M 9M 10M 12d', '3M 7M 8P 9M 12d', '3M 8P 9M 12d 14M'], + '^7#5': ['1P 6m 7M 10M 13m', '3M 7M 8P 10M 13m', '6m 7M 8P 10M 13m'], + '-6': [ + '1P 3m 5P 6M 8P', + '1P 5P 6M 8P 10m', + '3m 5P 6M 8P 10m', + '1P 5P 8P 10m 13M', + '3m 5P 8P 10m 13M', + '5P 8P 10m 12P 13M', + '5P 8P 10m 13M 15P', + ], + '-69': [ + '1P 3m 5P 6M 9M', + '3m 5P 6M 8P 9M', + '3m 6M 9M 10m 12P', + '1P 5P 9M 10m 13M', + '3m 5P 8P 9M 13M', + '5P 8P 9M 10m 13M', + '5P 8P 10m 13M 16M', + ], + '-^7': ['1P 3m 5P 7M 10m', '1P 5P 7M 10m 12P', '3m 7M 8P 10m 12P', '5P 7M 8P 10m 14M', '5P 8P 10m 14M 17m'], + '-^9': ['1P 3m 5P 7M 9M', '1P 7M 9M 10m 12P', '3m 7M 8P 9M 12P', '5P 8P 9M 10m 14M'], + '-9': [ + '1P 3m 5P 7m 9M', + '3m 5P 7m 8P 9M', + '3m 7m 8P 9M 12P', + '5P 8P 9M 10m 14m', + '3m 7m 9M 12P 15P', + '7m 10m 12P 15P 16M', + ], + '-add9': ['1P 2M 3m 5P 8P', '1P 3m 5P 9M', '3m 5P 8P 9M 12P', '5P 8P 9M 10m 12P'], + '-11': [ + '1P 3m 7m 9M 11P', + '3m 7m 8P 9M 11P', + '1P 4P 7m 10m 12P', + '5P 8P 11P 14m', + '3m 7m 9M 11P 15P', + '5P 8P 11P 14m 16M', + '7m 10m 12P 15P 18P', + ], + '-7b5': [ + '3m 5d 7m 8P 10m', + '1P 7m 10m 12d', + '1P 5d 7m 10m 12d', + '3m 7m 8P 10m 12d', + '3m 7m 8P 12d 14m', + '5d 7m 8P 10m 14m', + '5d 8P 10m 12d 14m', + '7m 10m 12d 14m 15P', + '5d 8P 10m 14m 17m', + ], + h9: ['1P 7m 9M 10m 12d', '3m 7m 8P 9M 12d', '5d 8P 9M 10m 14m', '7m 10m 12d 15P 16M'], + '-b6': ['1P 5P 6m 8P 10m', '1P 5P 8P 10m 13m', '3m 5P 8P 10m 13m', '5P 8P 10m 13m', '5P 8P 10m 13m 15P'], + '-#5': ['1P 6m 8P 10m 13m', '3m 6m 8P 10m 13m', '6m 8P 10m 13m 15P'], + '7b9': ['1P 3M 7m 9m 10M', '3M 7m 8P 9m 10M', '3M 7m 8P 9m 14m', '7m 9m 10M 14m 15P'], + '7#9': ['1P 3M 7m 10m', '3M 7m 8P 10m 14m', '7m 10m 10M 14m 15P'], + '7#11': ['1P 3M 7m 10M 12d', '3M 7m 8P 10M 12d', '7m 10M 12d 14m 15P'], + '7b5': ['1P 3M 7m 10M 12d', '3M 7m 8P 10M 12d', '7m 10M 12d 14m 15P'], + '7#5': ['1P 3M 7m 10M 13m', '3M 7m 8P 10M 13m', '3M 7m 8P 13m 14m', '7m 10M 13m 14m 15P'], + '9#11': ['1P 7m 9M 10M 12d', '3M 7m 8P 9M 12d', '7m 10M 12d 15P 16M'], + '9b5': ['1P 7m 9M 10M 12d', '3M 7m 8P 9M 12d', '7m 10M 12d 15P 16M'], + '9#5': ['1P 7m 9M 10M 13m', '3M 7m 9M 10M 13m', '3M 7m 9M 13m 14m', '7m 10M 13m 14m 16M', '7m 10M 13m 16M 17M'], + '7b13': ['1P 3M 7m 10M 13m', '3M 7m 8P 10M 13m', '3M 7m 8P 13m 14m', '7m 10M 13m 14m 15P'], + '7#9#5': ['1P 3M 7m 10m 13m', '3M 7m 10m 13m 15P', '7m 10M 13m 15P 17m'], + '7#9b5': ['1P 3M 7m 10m 12d', '3M 7m 10m 12d 15P', '7m 10M 12d 15P 17m'], + '7#9#11': ['1P 3M 7m 10m 12d', '3M 7m 10m 12d 15P', '7m 10M 12d 15P 17m'], + '7b9#11': ['1P 7m 9m 10M 12d', '3M 7m 8P 9m 12d', '7m 8P 10M 12d 16m'], + '7b9b5': ['1P 7m 9m 10M 12d', '3M 7m 8P 9m 12d', '7m 8P 10M 12d 16m'], + '7b9#5': ['1P 7m 9m 10M 13m', '3M 7m 8P 9m 13m', '7m 9m 10M 13m 15P'], + '7b9#9': ['1P 3M 7m 9m 10m', '3M 7m 8P 9m 10m', '7m 8P 10M 16m 17m'], + '7b9b13': ['1P 7m 9m 10M 13m', '3M 7m 8P 9m 13m', '7m 9m 10M 13m 15P'], + '7alt': [ + '3M 7m 8P 9m 12d', + '1P 7m 10m 10M 13m', + '3M 7m 8P 10m 13m', + '3M 7m 9m 12d 15P', + '3M 7m 10m 13m 15P', + '7m 10M 12d 15P 17m', + '7m 10M 13m 15P 17m', + ], + '13#11': ['1P 6M 7m 10M 12d', '3M 7m 9M 12d 13M', '7m 10M 12d 13M 16M'], + '13b9': ['1P 3M 6M 7m 9m', '1P 6M 7m 9m 10M', '3M 7m 9m 10M 13M', '3M 7m 10M 13M 16m', '7m 10M 13M 16m 17M'], + '13#9': ['1P 3M 6M 7m 10m', '3M 7m 8P 10m 13M', '7m 10M 13M 14m 17m'], + '7b9sus': ['1P 5P 7m 9m 11P', '5P 7m 8P 9m 11P', '7m 8P 11P 14m 16m'], + '7susadd3': ['1P 4P 5P 7m 10M', '5P 8P 10M 11P 14m', '7m 11P 12P 15P 17M'], + '9sus': ['1P 5P 7m 9M 11P', '5P 7m 8P 9M 11P', '7m 8P 9M 11P 12P', '7m 8P 11P 12P 16M'], + '13sus': ['1P 4P 6M 7m 9M', '1P 7m 9M 11P 13M', '5P 7m 9M 11P 13M', '7m 9M 11P 13M 15P'], + '7b13sus': ['1P 5P 7m 11P 13m', '5P 7m 8P 11P 13m', '7m 11P 13m 14m 15P'], +}; + +export const complex = { + 2: ['1P 5P 6M 8P 9M', '1P 5P 8P 9M 12P', '5P 8P 9M 12P 13M', '5P 8P 9M 12P 15P'], + 5: ['1P 5P 8P 12P', '1P 5P 8P 9M 12P', '5P 8P 12P 15P', '5P 8P 12P 15P 16M'], + 6: ['1P 5P 6M 9M 10M', '1P 5P 9M 10M 13M', '3M 5P 9M 10M 13M', '5P 8P 9M 10M 13M', '3M 6M 9M 12P 15P'], + 7: [ + '1P 5P 7m 8P 10M', + '1P 7m 8P 10M 12P', + '3M 7m 8P 10M 12P', + '3M 7m 8P 10M 14m', + '3M 7m 10M 12P 15P', + '7m 10M 12P 14m 15P', + '7m 10M 12P 15P 17M', + '7m 10M 14m 17M 19P', + ], + 9: [ + '1P 6M 7m 9M 10M', + '3M 7m 9M 10M 12P', + '1P 7m 9M 10M 13M', + '3M 7m 9M 10M 13M', + '3M 7m 9M 12P 15P', + '7m 10M 12P 13M 16M', + '7m 10M 13M 16M 17M', + '7m 10M 13M 16M 19P', + ], + 11: [ + '1P 4P 6M 7m 9M', + '1P 5P 7m 9M 11P', + '4P 6M 7m 9M 11P', + '5P 8P 9M 11P 14m', + '7m 9M 11P 13M 15P', + '7m 11P 12P 14m 18P', + ], + 13: [ + '3M 7m 9M 10M 13M', + '3M 7m 9M 13M 15P', + '3M 7m 10M 13M 16M', + '7m 10M 12P 13M 16M', + '7m 10M 13M 16M 17M', + '7m 10M 13M 16M 19P', + ], + 69: ['1P 5P 6M 9M 10M', '1P 5P 9M 10M 13M', '3M 5P 9M 10M 13M', '5P 8P 9M 10M 13M', '3M 6M 9M 12P 15P'], + add9: [ + '1P 5P 8P 9M 10M', + '1P 5P 9M 10M 12P', + '3M 8P 9M 10M 12P', + '3M 8P 9M 12P 15P', + '5P 8P 9M 10M 15P', + '5P 8P 9M 12P 17M', + ], + '+': [ + '1P 6m 8P 9M 10M', + '1P 6m 8P 10M 13m', + '3M 8P 9M 10M 13m', + '3M 8P 10M 13m 15P', + '6m 10M 13m 15P 16M', + '6m 10M 13m 15P 17M', + ], + o: [ + '1P 6M 8P 10m 12d', + '1P 6M 10m 12d 13M', + '3m 8P 10m 12d 13M', + '3m 8P 12d 13M 15P', + '5d 10m 12d 13M 15P', + '5d 10m 13M 15P 17m', + '6M 12d 13M 15P 17m', + '6M 12d 15P 17m 19d', + ], + h: [ + '1P 5d 7m 10m 11P', + '3m 5d 7m 8P 11P', + '5d 7m 8P 10m 11P', + '1P 7m 10m 12d', + '3m 7m 8P 12d 14m', + '5d 8P 10m 11P 14m', + '7m 10m 11P 12d 14m', + '7m 10m 12d 14m 15P', + '5d 8P 10m 14m 17m', + ], + sus: [ + '1P 4P 5P 8P 9M', + '1P 4P 5P 8P 11P', + '1P 5P 8P 9M 11P', + '5P 8P 9M 11P 12P', + '5P 8P 11P 12P 13M', + '5P 8P 11P 13M 15P', + ], + '^': [ + '1P 3M 5P 6M 9M', + '1P 5P 8P 10M 12P', + '3M 5P 9M 10M 12P', + '1P 5P 8P 10M 13M', + '3M 8P 10M 13M 15P', + '5P 9M 10M 12P 15P', + ], + '-': [ + '1P 3m 5P 8P 10m', + '1P 3m 5P 9M 11P', + '3m 5P 8P 9M 11P', + '5P 8P 9M 10m 11P', + '1P 5P 9M 10m 12P', + '3m 5P 8P 10m 12P', + '5P 8P 10m 12P 15P', + ], + '^7': [ + '1P 6M 7M 9M 10M', + '3M 7M 9M 10M 12P', + '1P 7M 9M 10M 13M', + '3M 7M 9M 10M 13M', + '3M 7M 9M 12P 13M', + '3M 7M 9M 13M 14M', + '3M 7M 10M 13M 16M', + '7M 10M 13M 14M 16M', + '7M 10M 13M 16M 17M', + '7M 10M 13M 16M 19P', + ], + '-7': [ + '1P 3m 5P 7m 9M', + '1P 3m 5P 7m 10m', + '1P 5P 7m 10m 11P', + '3m 7m 8P 10m 11P', + '1P 5P 7m 10m 12P', + '3m 7m 9M 10m 12P', + '3m 7m 8P 10m 14m', + '5P 7m 9M 10m 14m', + '7m 10m 11P 14m 15P', + '7m 10m 12P 15P 16M', + '5P 8P 11P 14m 17m', + '7m 10m 12P 15P 17m', + ], + '7sus': [ + '1P 4P 6M 7m 9M', + '1P 5P 7m 9M 11P', + '4P 6M 7m 9M 11P', + '5P 8P 9M 11P 14m', + '7m 9M 11P 13M 15P', + '7m 11P 12P 14m 18P', + ], + h7: [ + '1P 5d 7m 10m 11P', + '3m 5d 7m 8P 11P', + '5d 7m 8P 10m 11P', + '1P 7m 10m 12d', + '3m 7m 8P 10m 12d', + '3m 7m 8P 12d 14m', + '5d 8P 10m 11P 14m', + '7m 10m 11P 12d 14m', + '7m 10m 12d 14m 15P', + '5d 8P 10m 14m 17m', + ], + o7: [ + '1P 6M 8P 10m 12d', + '1P 6M 10m 12d 13M', + '3m 8P 10m 12d 13M', + '3m 8P 12d 13M 15P', + '5d 10m 12d 13M 15P', + '5d 10m 13M 15P 17m', + '6M 12d 13M 15P 17m', + '6M 12d 15P 17m 19d', + ], + '^9': [ + '1P 6M 7M 9M 10M', + '1P 7M 9M 10M 13M', + '3M 7M 9M 10M 13M', + '3M 7M 9M 12P 13M', + '3M 7M 8P 9M 13M', + '3M 7M 9M 13M 14M', + '3M 7M 10M 13M 16M', + '7M 10M 13M 14M 16M', + '7M 10M 13M 16M 17M', + '7M 10M 13M 16M 19P', + ], + '^13': [ + '1P 6M 7M 9M 10M', + '1P 7M 9M 10M 13M', + '3M 7M 9M 12P 13M', + '3M 7M 9M 10M 13M', + '3M 7M 8P 9M 13M', + '3M 7M 9M 13M 14M', + '3M 7M 10M 13M 16M', + '7M 10M 13M 14M 16M', + '7M 10M 13M 16M 17M', + '7M 10M 13M 16M 19P', + ], + '^7#11': [ + '1P 3M 5d 7M 9M', + '1P 7M 9M 10M 12d', + '3M 7M 9M 10M 12d', + '3M 7M 9M 12d 13M', + '3M 7M 10M 12d 14M', + '7M 10M 12d 13M 14M', + '7M 10M 12d 13M 16M', + '7M 10M 12d 14M 17M', + ], + '^9#11': [ + '1P 3M 5d 7M 9M', + '1P 7M 9M 10M 12d', + '3M 7M 9M 10M 12d', + '3M 7M 9M 12d 13M', + '3M 7M 9M 12d 14M', + '7M 10M 12d 14M 16M', + '7M 10M 12d 13M 16M', + ], + '^7#5': ['1P 6m 7M 10M 13m', '3M 7M 9M 10M 13m', '3M 7M 10M 13m 14M', '7M 10M 13m 14M 16M', '7M 10M 13m 14M 17M'], + '-6': [ + '1P 3m 5P 6M 9M', + '3m 5P 6M 8P 9M', + '1P 5P 6M 10m 11P', + '3m 5P 6M 8P 11P', + '1P 5P 9M 10m 13M', + '3m 5P 8P 9M 13M', + '5P 8P 10m 11P 13M', + '5P 8P 10m 13M 16M', + ], + '-69': [ + '1P 3m 5P 6M 9M', + '3m 5P 6M 8P 9M', + '3m 6M 9M 10m 12P', + '1P 5P 9M 10m 13M', + '3m 5P 8P 9M 13M', + '5P 8P 9M 10m 13M', + '5P 8P 10m 13M 16M', + ], + '-^7': [ + '1P 3m 5P 7M 9M', + '1P 5P 7M 10m 11P', + '3m 7M 9M 10m 11P', + '3m 7M 9M 10m 12P', + '3m 7M 9M 12P 14M', + '7M 10m 11P 12P 14M', + '7M 10m 12P 14M 16M', + ], + '-^9': [ + '1P 3m 5P 7M 9M', + '1P 5P 7M 10m 11P', + '3m 7M 9M 10m 11P', + '3m 7M 9M 10m 12P', + '3m 7M 9M 12P 14M', + '7M 10m 11P 12P 14M', + '7M 10m 12P 14M 16M', + ], + '-9': [ + '1P 3m 5P 7m 9M', + '1P 3m 7m 9M 11P', + '3m 7m 9M 10m 11P', + '3m 7m 9M 10m 12P', + '3m 7m 9M 10m 14m', + '3m 7m 9M 12P 15P', + '7m 10m 11P 14m 16M', + '7m 10m 12P 16M 18P', + ], + '-add9': ['1P 2M 3m 5P 8P', '1P 3m 5P 9M', '3m 5P 8P 9M 12P', '5P 8P 9M 10m 12P'], + '-11': [ + '3m 5P 7m 9M 11P', + '7m 9M 10m 11P', + '1P 4P 7m 10m 12P', + '3m 7m 9M 11P 12P', + '7m 9M 10m 11P 12P', + '3m 7m 9M 11P 14m', + '4P 10m 12P 14m', + '5P 8P 11P 14m', + '5P 8P 11P 14m 16M', + '7m 10m 12P 16M 18P', + '7m 10m 11P 16M 21m', + ], + '-7b5': [ + '1P 5d 7m 10m 11P', + '3m 5d 7m 8P 11P', + '5d 7m 8P 10m 11P', + '1P 7m 10m 12d', + '3m 7m 8P 10m 12d', + '3m 7m 8P 12d 14m', + '5d 8P 10m 11P 14m', + '7m 10m 11P 12d 14m', + '7m 10m 12d 14m 15P', + '5d 8P 10m 14m 17m', + ], + h9: [ + '3m 5d 7m 9M 11P', + '1P 7m 9M 10m 12d', + '3m 7m 9M 12d 14m', + '5d 8P 9M 10m 14m', + '7m 10m 11P 12d 14m', + '7m 10m 12d 14m 16M', + ], + '-b6': ['1P 3m 5P 6m 8P', '3m 5P 8P 11P 13m', '5P 8P 10m 11P 13m'], + '-#5': ['1P 6m 8P 10m 13m', '3m 6m 8P 11P 13m', '6m 8P 10m 13m 15P'], + '7b9': ['1P 3M 7m 9m 10M', '3M 7m 8P 9m 10M', '3M 7m 8P 9m 14m', '7m 9m 10M 14m 15P'], + '7#9': ['1P 3M 7m 10m', '3M 7m 10m 10M 12P', '3M 7m 10m 12P 14m', '7m 10M 12P 14m 17m'], + '7#11': ['1P 3M 7m 9M 12d', '3M 7m 9M 12d 13M', '7m 10M 12d 13M 16M'], + '7b5': ['1P 3M 7m 9M 12d', '3M 7m 9M 12d 13M', '7m 10M 12d 13M 16M'], + '7#5': ['1P 3M 7m 10M 13m', '3M 7m 8P 10M 13m', '3M 7m 8P 13m 14m', '7m 10M 13m 14m 15P', '7m 10M 13m 14m 17M'], + '9#11': ['1P 7m 9M 10M 12d', '3M 7m 8P 9M 12d', '7m 10M 12d 15P 16M'], + '9b5': ['1P 7m 9M 10M 12d', '3M 7m 8P 9M 12d', '7m 10M 12d 15P 16M'], + '9#5': ['1P 7m 9M 10M 13m', '3M 7m 9M 10M 13m', '3M 7m 9M 13m 14m', '7m 10M 13m 14m 16M', '7m 10M 13m 16M 17M'], + '7b13': ['1P 3M 7m 10M 13m', '3M 7m 8P 10M 13m', '3M 7m 8P 13m 14m', '7m 10M 13m 14m 15P', '7m 10M 13m 14m 17M'], + '7#9#5': ['3M 7m 10m 10M 13m', '3M 7m 10m 13m 14m', '7m 10M 13m 14m 17m'], + '7#9b5': ['3M 7m 10m 10M 12d', '3M 7m 10m 12d 14m', '7m 10M 12d 14m 17m'], + '7#9#11': ['3M 7m 10m 10M 12d', '3M 7m 10m 12d 14m', '7m 10M 12d 14m 17m'], + '7b9#11': ['3M 7m 9m 10M 12d', '3M 7m 9m 12d 14m', '7m 8P 10M 12d 16m', '7m 10M 12d 14m 16m'], + '7b9b5': ['3M 7m 9m 10M 12d', '3M 7m 9m 12d 14m', '7m 8P 10M 12d 16m', '7m 10M 12d 14m 16m'], + '7b9#5': ['1P 7m 9m 10M 13m', '3M 7m 9m 10M 13m', '3M 7m 10M 13m 16m', '7m 10M 13m 14m 16m', '7m 10M 13m 16m 17M'], + '7b9#9': ['1P 3M 7m 9m 10m', '3M 7m 10m 13m 16m', '7m 10M 13m 16m 17m'], + '7b9b13': ['1P 7m 9m 10M 13m', '3M 7m 9m 10M 13m', '3M 7m 10M 13m 16m', '7m 10M 13m 14m 16m', '7m 10M 13m 16m 17M'], + '7alt': [ + '3M 7m 8P 10m 13m', + '3M 7m 9m 12d 13m', + '3M 7m 9m 10m 13m', + '3M 7m 10m 13m 14m', + '3M 7m 9m 12d 14m', + '3M 7m 10m 13m 15P', + '3M 7m 10m 13m 16m', + '7m 10M 12d 14m 16m', + '7m 10M 12d 13m 16m', + '7m 10M 13m 15P 17m', + '7m 10M 13m 16m 17m', + '7m 10M 13m 16m 19d', + ], + '13#11': ['3M 7m 9M 12d 13M', '7m 10M 12d 13M 16M'], + '13b9': ['3M 7m 9m 10M 13M', '3M 7m 10M 13M 16m', '7m 10M 13M 16m 17M'], + '13#9': ['3M 7m 10m 10M 13M', '7m 10M 13M 14m 17m'], + '7b9sus': ['1P 5P 7m 9m 11P', '5P 7m 8P 9m 11P', '7m 8P 11P 14m 16m'], + '7susadd3': ['1P 4P 5P 7m 10M', '5P 8P 10M 11P 14m', '7m 11P 12P 15P 17M'], + '9sus': [ + '1P 4P 6M 7m 9M', + '1P 5P 7m 9M 11P', + '4P 6M 7m 9M 11P', + '5P 8P 9M 11P 14m', + '7m 9M 11P 13M 15P', + '7m 11P 12P 14m 18P', + ], + '13sus': [ + '1P 4P 6M 7m 9M', + '1P 7m 9M 11P 13M', + '4P 7m 9M 11P 13M', + '7m 9M 11P 13M 15P', + '7m 11P 13M 14m 16M', + '7m 11P 13M 16M 18P', + ], + '7b13sus': ['1P 5P 7m 11P 13m', '5P 7m 8P 11P 13m', '7m 11P 13m 14m 15P'], +}; diff --git a/packages/tonal/tonleiter.mjs b/packages/tonal/tonleiter.mjs index 56c3e35b..e2d24b27 100644 --- a/packages/tonal/tonleiter.mjs +++ b/packages/tonal/tonleiter.mjs @@ -76,11 +76,11 @@ export const midi2note = (midi, sharp = false) => { return pc + oct; }; -export function scaleStep(notes, offset) { +export function scaleStep(notes, offset, octaves = 1) { notes = notes.map((note) => (typeof note === 'string' ? noteToMidi(note) : note)); - const octOffset = Math.floor(offset / notes.length) * 12; - offset = _mod(offset, 12); - return notes[offset % notes.length] + octOffset; + const octOffset = Math.floor(offset / notes.length) * octaves * 12; + offset = _mod(offset, notes.length); + return notes[offset] + octOffset; } // different ways to resolve the note to compare the anchor to (see renderVoicing) @@ -90,7 +90,7 @@ let modeTarget = { above: (v) => v[0], }; -export function renderVoicing({ chord, dictionary, offset = 0, n, mode = 'below', anchor = 'c5' }) { +export function renderVoicing({ chord, dictionary, offset = 0, n, mode = 'below', anchor = 'c5', octaves = 1 }) { const [root, symbol] = tokenizeChord(chord); const rootChroma = pc2chroma(root); anchor = anchor?.note || anchor; @@ -124,7 +124,7 @@ export function renderVoicing({ chord, dictionary, offset = 0, n, mode = 'below' notes = notes.filter((_, i) => voicingMidi[i] !== noteToMidi(anchor)); } if (n !== undefined) { - return [scaleStep(notes, n)]; + return [scaleStep(notes, n, octaves)]; } return notes; } diff --git a/packages/tonal/voicings.mjs b/packages/tonal/voicings.mjs index bd11a961..a99a043b 100644 --- a/packages/tonal/voicings.mjs +++ b/packages/tonal/voicings.mjs @@ -7,6 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th import { stack, register } from '@strudel.cycles/core'; import { renderVoicing } from './tonleiter.mjs'; import _voicings from 'chord-voicings'; +import { complex, simple } from './ireal.mjs'; const { dictionaryVoicing, minTopNoteDiff } = _voicings.default || _voicings; // parcel module resolution fuckup const lefthand = { @@ -195,10 +196,10 @@ export const voicing = register('voicing', function (pat) { .fmap((value) => { // destructure voicing controls out value = typeof value === 'string' ? { chord: value } : value; - let { dictionary = 'default', chord, anchor, offset, mode, n, ...rest } = value; + let { dictionary = 'default', chord, anchor, offset, mode, n, octaves, ...rest } = value; dictionary = typeof dictionary === 'string' ? voicingRegistry[dictionary] : { dictionary, mode: 'below', anchor: 'c5' }; - let notes = renderVoicing({ ...dictionary, chord, anchor, offset, mode, n }); + let notes = renderVoicing({ ...dictionary, chord, anchor, offset, mode, n, octaves }); return stack(...notes) .note() @@ -206,3 +207,29 @@ export const voicing = register('voicing', function (pat) { }) .outerJoin(); }); + +export function voicingAlias(symbol, alias, setOrSets) { + setOrSets = !Array.isArray(setOrSets) ? [setOrSets] : setOrSets; + setOrSets.forEach((set) => { + set[alias] = set[symbol]; + }); +} + +// no symbol = major chord +voicingAlias('^', '', [simple, complex]); + +Object.keys(simple).forEach((symbol) => { + // add aliases for "-" === "m" + if (symbol.includes('-')) { + let alias = symbol.replace('-', 'm'); + voicingAlias(symbol, alias, [complex, simple]); + } + // add aliases for "^" === "M" + if (symbol.includes('^')) { + let alias = symbol.replace('^', 'M'); + voicingAlias(symbol, alias, [complex, simple]); + } +}); + +registerVoicings('ireal', simple); +registerVoicings('ireal-ext', complex);