From d84c917f19a161ce12ad5436535fb6e1f125125c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 27 Oct 2023 22:50:21 +0200 Subject: [PATCH] fix: scale offset --- packages/tonal/tonal.mjs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 99a11c538..3b6fe41ee 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -7,6 +7,19 @@ This program is free software: you can redistribute it and/or modify it under th import { Note, Interval, Scale } from '@tonaljs/tonal'; import { register, _mod } from '@strudel.cycles/core'; +const octavesInterval = (octaves) => (octaves <= 0 ? -1 : 1) + octaves * 7 + 'P'; + +function scaleStep(step, scale) { + scale = scale.replaceAll(':', ' '); + step = Math.ceil(step); + const { intervals, tonic } = Scale.get(scale); + const { pc, oct = 3 } = Note.get(tonic); + const octaveOffset = Math.floor(step / intervals.length); + const scaleStep = _mod(step, intervals.length); + const interval = Interval.add(intervals[scaleStep], octavesInterval(octaveOffset)); + return Note.transpose(pc + oct, interval); +} + // transpose note inside scale by offset steps // function scaleOffset(scale: string, offset: number, note: string) { function scaleOffset(scale, offset, note) { @@ -155,11 +168,7 @@ export const scale = register('scale', function (scale, pat) { } const asNumber = Number(note); if (!isNaN(asNumber)) { - // TODO: worth keeping for supporting ':' in (non-mininotation) strings? - scale = scale.replaceAll(':', ' '); - let [tonic, scaleName] = Scale.tokenize(scale); - const { pc, oct = 3 } = Note.get(tonic); - note = scaleOffset(pc + ' ' + scaleName, asNumber, pc + oct); + note = scaleStep(asNumber, scale); } return hap.withValue(() => (isObject ? { ...hap.value, note } : note)).setContext({ ...hap.context, scale }); });