- make dictionary a control

- standalone voicing function
- simplify voicing control names
This commit is contained in:
Felix Roos 2023-07-11 22:49:34 +02:00
parent d5c0309885
commit 0b3a8a5f65
3 changed files with 24 additions and 14 deletions

View File

@ -509,7 +509,7 @@ const generic_params = [
* @superDirtOnly * @superDirtOnly
*/ */
['octave'], ['octave'],
['offset'], // TODO: what is this? not found in tidal doc
// ['ophatdecay'], // ['ophatdecay'],
// TODO: example // TODO: example
/** /**
@ -574,11 +574,12 @@ const generic_params = [
// ['velocity'], // ['velocity'],
['voice'], // TODO: synth param ['voice'], // TODO: synth param
// voicings // voicings // https://github.com/tidalcycles/strudel/issues/506
['chord'], // https://github.com/tidalcycles/strudel/issues/506 ['chord'], // chord to voice, like C Eb Fm7 G7. the symbols can be defined via addVoicings
['voiceBelow', 'voicebelow'], // https://github.com/tidalcycles/strudel/issues/506 ['dictionary', 'dict'], // which dictionary to use for the voicings
['voiceMax', 'voicemax'], // https://github.com/tidalcycles/strudel/issues/506 ['anchor'], // the top note to align the voicing to, defaults to c5
['voiceOffset', 'voiceoffset'], // https://github.com/tidalcycles/strudel/issues/506 ['offset'], // how the voicing is offset from the anchored position
['mode'], // below = anchor note will be removed from the voicing, useful for melody harmonization
/** /**
* Sets the level of reverb. * Sets the level of reverb.

View File

@ -54,6 +54,15 @@ export const x2chroma = (x) => {
} }
}; };
export const x2midi = (x) => {
if (typeof x === 'number') {
return x;
}
if (typeof x === 'string') {
return note2midi(x);
}
};
// duplicate: util.mjs (does not support sharp flag) // duplicate: util.mjs (does not support sharp flag)
export const midi2note = (midi, sharp = false) => { export const midi2note = (midi, sharp = false) => {
const oct = Math.floor(midi / 12) - 1; const oct = Math.floor(midi / 12) - 1;

View File

@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th
*/ */
import { stack, register } from '@strudel.cycles/core'; import { stack, register } from '@strudel.cycles/core';
import { voiceBelow, note2midi } from './tonleiter.mjs'; import { voiceBelow, note2midi, x2midi } from './tonleiter.mjs';
import _voicings from 'chord-voicings'; import _voicings from 'chord-voicings';
const { dictionaryVoicing, minTopNoteDiff } = _voicings.default || _voicings; // parcel module resolution fuckup const { dictionaryVoicing, minTopNoteDiff } = _voicings.default || _voicings; // parcel module resolution fuckup
@ -136,18 +136,18 @@ export const rootNotes = register('rootNotes', function (octave, pat) {
}); });
}); });
export const voicing = register('voicing', function (dictionary, pat) { export const voicing = register('voicing', function (pat) {
return pat return pat
.fmap((value) => { .fmap((value) => {
let { voiceMax: max, voiceBelow: below, voiceOffset: offset, chord, n, ...rest } = value; // TODO: default dictionary?
let top = max || below; let { anchor, mode, offset, chord, n, dictionary, ...rest } = value;
top = top?.note || top || 'c5'; anchor = anchor?.note || anchor || 'c5';
if (typeof dictionary === 'string') { if (typeof dictionary === 'string') {
dictionary = voicingRegistry[dictionary]?.dictionary; dictionary = voicingRegistry[dictionary]?.dictionary;
} }
let notes = voiceBelow(top, chord, dictionary, offset, n); let notes = voiceBelow(anchor, chord, dictionary, offset, n);
if (below) { if (mode === 'below') {
notes = notes.filter((n) => note2midi(n) !== note2midi(top)); notes = notes.filter((n) => x2midi(n) !== note2midi(anchor));
} }
return stack(...notes) return stack(...notes)
.note() .note()