From 3776791239a7055dcc5eea7f6ee5788faf1761f1 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 23 Dec 2023 12:30:55 -0500 Subject: [PATCH 1/2] working --- packages/soundfonts/fontloader.mjs | 7 ++++--- packages/superdough/sampler.mjs | 10 ++++++---- packages/superdough/util.mjs | 7 +++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 017ba763..2f214cad 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -1,6 +1,7 @@ -import { noteToMidi, freqToMidi } from '@strudel.cycles/core'; +import { noteToMidi, freqToMidi, _mod } from '@strudel.cycles/core'; import { getAudioContext, registerSound, getEnvelope } from '@strudel.cycles/webaudio'; import gm from './gm.mjs'; +import { getSoundIndex } from '../superdough/util.mjs'; let loadCache = {}; async function loadFont(name) { @@ -130,9 +131,9 @@ export function registerSoundfonts() { registerSound( name, async (time, value, onended) => { - const { n = 0 } = value; + const n = getSoundIndex(value.n, fonts.length); const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; - const font = fonts[n % fonts.length]; + const font = fonts[n]; const ctx = getAudioContext(); const bufferSource = await getFontBufferSource(font, value, ctx); bufferSource.start(time); diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 39e5b548..9dd0d2f5 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -1,4 +1,4 @@ -import { noteToMidi, valueToMidi, nanFallback } from './util.mjs'; +import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs'; import { getAudioContext, registerSound } from './index.mjs'; import { getEnvelope } from './helpers.mjs'; import { logger } from './logger.mjs'; @@ -31,10 +31,11 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol transpose = midi - 36; // C3 is middle C const ac = getAudioContext(); + let sampleUrl; if (Array.isArray(bank)) { - n = nanFallback(n, 0); - sampleUrl = bank[n % bank.length]; + const index = getSoundIndex(n, bank.length); + sampleUrl = bank[index]; } else { const midiDiff = (noteA) => noteToMidi(noteA) - midi; // object format will expect keys as notes @@ -45,7 +46,8 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol null, ); transpose = -midiDiff(closest); // semitones to repitch - sampleUrl = bank[closest][n % bank[closest].length]; + const index = getSoundIndex(n, bank[closest].length); + sampleUrl = bank[closest][index]; } if (resolveUrl) { sampleUrl = await resolveUrl(sampleUrl); diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index d49ffd6b..29eaa7bc 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -61,3 +61,10 @@ export function nanFallback(value, fallback) { } return value; } +// modulo that works with negative numbers e.g. _mod(-1, 3) = 2. Works on numbers (rather than patterns of numbers, as @mod@ from pattern.mjs does) +export const _mod = (n, m) => ((n % m) + m) % m; + +// round to nearest int, negative numbers will output a subtracted index +export const getSoundIndex = (n, numSounds) => { + return _mod(Math.round(nanFallback(n, 0)), numSounds); +}; From b5039ecce89a40a4c18b03830ad946fc28366ceb Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Thu, 28 Dec 2023 10:19:20 -0500 Subject: [PATCH 2/2] fix import --- packages/core/util.mjs | 14 ++++++++++++++ packages/soundfonts/fontloader.mjs | 3 +-- packages/superdough/sampler.mjs | 7 ++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/core/util.mjs b/packages/core/util.mjs index 2b190c82..f6223475 100644 --- a/packages/core/util.mjs +++ b/packages/core/util.mjs @@ -4,6 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ +import { logger } from './logger.mjs'; + // returns true if the given string is a note export const isNoteWithOctave = (name) => /^[a-gA-G][#bs]*[0-9]$/.test(name); export const isNote = (name) => /^[a-gA-G][#bsf]*[0-9]?$/.test(name); @@ -84,6 +86,18 @@ export const midi2note = (n) => { // modulo that works with negative numbers e.g. _mod(-1, 3) = 2. Works on numbers (rather than patterns of numbers, as @mod@ from pattern.mjs does) export const _mod = (n, m) => ((n % m) + m) % m; +export function nanFallback(value, fallback) { + if (isNaN(Number(value))) { + logger(`"${value}" is not a number, falling back to ${fallback}`, 'warning'); + return fallback; + } + return value; +} +// round to nearest int, negative numbers will output a subtracted index +export const getSoundIndex = (n, numSounds) => { + return _mod(Math.round(nanFallback(n, 0)), numSounds); +}; + export const getPlayableNoteValue = (hap) => { let { value, context } = hap; let note = value; diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 2f214cad..c2f6a19c 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -1,7 +1,6 @@ -import { noteToMidi, freqToMidi, _mod } from '@strudel.cycles/core'; +import { noteToMidi, freqToMidi, getSoundIndex } from '@strudel.cycles/core'; import { getAudioContext, registerSound, getEnvelope } from '@strudel.cycles/webaudio'; import gm from './gm.mjs'; -import { getSoundIndex } from '../superdough/util.mjs'; let loadCache = {}; async function loadFont(name) { diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 9dd0d2f5..754ccf9b 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -33,8 +33,9 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol const ac = getAudioContext(); let sampleUrl; + let index = 0; if (Array.isArray(bank)) { - const index = getSoundIndex(n, bank.length); + index = getSoundIndex(n, bank.length); sampleUrl = bank[index]; } else { const midiDiff = (noteA) => noteToMidi(noteA) - midi; @@ -46,13 +47,13 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol null, ); transpose = -midiDiff(closest); // semitones to repitch - const index = getSoundIndex(n, bank[closest].length); + index = getSoundIndex(n, bank[closest].length); sampleUrl = bank[closest][index]; } if (resolveUrl) { sampleUrl = await resolveUrl(sampleUrl); } - let buffer = await loadBuffer(sampleUrl, ac, s, n); + let buffer = await loadBuffer(sampleUrl, ac, s, index); if (speed < 0) { // should this be cached? buffer = reverseBuffer(buffer);