mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-22 02:58:32 +00:00
add octaves control for arpeggios
This commit is contained in:
parent
d231ded7a2
commit
52b8d9d361
@ -579,6 +579,7 @@ const generic_params = [
|
|||||||
['dictionary', 'dict'], // which dictionary to use for the voicings
|
['dictionary', 'dict'], // which dictionary to use for the voicings
|
||||||
['anchor'], // the top note to align the voicing to, defaults to c5
|
['anchor'], // the top note to align the voicing to, defaults to c5
|
||||||
['offset'], // how the voicing is offset from the anchored position
|
['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
|
[['mode', 'anchor']], // below = anchor note will be removed from the voicing, useful for melody harmonization
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -76,11 +76,11 @@ export const midi2note = (midi, sharp = false) => {
|
|||||||
return pc + oct;
|
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));
|
notes = notes.map((note) => (typeof note === 'string' ? noteToMidi(note) : note));
|
||||||
const octOffset = Math.floor(offset / notes.length) * 12;
|
const octOffset = Math.floor(offset / notes.length) * octaves * 12;
|
||||||
offset = _mod(offset, 12);
|
offset = _mod(offset, notes.length);
|
||||||
return notes[offset % notes.length] + octOffset;
|
return notes[offset] + octOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// different ways to resolve the note to compare the anchor to (see renderVoicing)
|
// different ways to resolve the note to compare the anchor to (see renderVoicing)
|
||||||
@ -90,7 +90,7 @@ let modeTarget = {
|
|||||||
above: (v) => v[0],
|
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 [root, symbol] = tokenizeChord(chord);
|
||||||
const rootChroma = pc2chroma(root);
|
const rootChroma = pc2chroma(root);
|
||||||
anchor = anchor?.note || anchor;
|
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));
|
notes = notes.filter((_, i) => voicingMidi[i] !== noteToMidi(anchor));
|
||||||
}
|
}
|
||||||
if (n !== undefined) {
|
if (n !== undefined) {
|
||||||
return [scaleStep(notes, n)];
|
return [scaleStep(notes, n, octaves)];
|
||||||
}
|
}
|
||||||
return notes;
|
return notes;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -196,10 +196,10 @@ export const voicing = register('voicing', function (pat) {
|
|||||||
.fmap((value) => {
|
.fmap((value) => {
|
||||||
// destructure voicing controls out
|
// destructure voicing controls out
|
||||||
value = typeof value === 'string' ? { chord: value } : value;
|
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 =
|
dictionary =
|
||||||
typeof dictionary === 'string' ? voicingRegistry[dictionary] : { dictionary, mode: 'below', anchor: 'c5' };
|
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)
|
return stack(...notes)
|
||||||
.note()
|
.note()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user