mirror of
https://codeberg.org/uzu/strudel
synced 2026-10-04 08:21:59 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 39013c09ef | |||
| 9d425dfff6 |
@@ -396,18 +396,6 @@ export const { velocity } = registerControl('velocity');
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const { gain } = registerControl('gain');
|
export const { gain } = registerControl('gain');
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies a linear gain adjustment
|
|
||||||
*
|
|
||||||
* @name gainlinear
|
|
||||||
* @synonyms gainlin
|
|
||||||
* @param {number | Pattern} amount gainlin
|
|
||||||
* @example
|
|
||||||
* s("hh*8").gainlin(".4!2 1 .4!2 1 .4 1").fast(2)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export const { gainlinear, gainlin } = registerControl('gainlinear', 'gainlin');
|
|
||||||
/**
|
/**
|
||||||
* Gain applied after all effects have been processed.
|
* Gain applied after all effects have been processed.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getCommonSampleInfo } from './util.mjs';
|
import { getCommonSampleInfoFromBank } from './util.mjs';
|
||||||
import { registerSound, registerWaveTable } from './index.mjs';
|
import { registerSound, registerWaveTable } from './index.mjs';
|
||||||
import { getAudioContext } from './audioContext.mjs';
|
import { getAudioContext } from './audioContext.mjs';
|
||||||
import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs';
|
import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs';
|
||||||
@@ -23,35 +23,34 @@ function humanFileSize(bytes, si) {
|
|||||||
return bytes.toFixed(1) + ' ' + units[u];
|
return bytes.toFixed(1) + ' ' + units[u];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSampleInfo(hapValue, bank) {
|
|
||||||
const { speed = 1.0 } = hapValue;
|
|
||||||
const { transpose, url, index, midi, label } = getCommonSampleInfo(hapValue, bank);
|
|
||||||
let playbackRate = Math.abs(speed) * Math.pow(2, transpose / 12);
|
|
||||||
return { transpose, url, index, midi, label, playbackRate };
|
|
||||||
}
|
|
||||||
|
|
||||||
// takes hapValue and returns buffer + playbackRate.
|
export const getSampleBuffer = async (label, sampleUrl, resolveUrl) => {
|
||||||
export const getSampleBuffer = async (hapValue, bank, resolveUrl) => {
|
|
||||||
let { url: sampleUrl, label, playbackRate } = getSampleInfo(hapValue, bank);
|
|
||||||
if (resolveUrl) {
|
if (resolveUrl) {
|
||||||
sampleUrl = await resolveUrl(sampleUrl);
|
sampleUrl = await resolveUrl(sampleUrl);
|
||||||
}
|
}
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
const buffer = await loadBuffer(sampleUrl, ac, label);
|
const buffer = await loadBuffer(sampleUrl, ac, label);
|
||||||
|
return buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
function getBufferPlaybackRate(hapValue, buffer, transpose) {
|
||||||
|
const { speed = 1.0 } = hapValue;
|
||||||
|
let playbackRate = Math.abs(speed) * Math.pow(2, transpose / 12);
|
||||||
if (hapValue.unit === 'c') {
|
if (hapValue.unit === 'c') {
|
||||||
playbackRate = playbackRate * buffer.duration;
|
playbackRate = playbackRate * buffer.duration;
|
||||||
}
|
}
|
||||||
return { buffer, playbackRate };
|
return playbackRate;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// creates playback ready AudioBufferSourceNode from hapValue
|
// creates playback ready AudioBufferSourceNode from hapValue
|
||||||
export const getSampleBufferSource = async (hapValue, bank, resolveUrl) => {
|
export function getSampleBufferSource(hapValue, buffer,transpose) {
|
||||||
let { buffer, playbackRate } = await getSampleBuffer(hapValue, bank, resolveUrl);
|
|
||||||
if (hapValue.speed < 0) {
|
if (hapValue.speed < 0) {
|
||||||
// should this be cached?
|
// should this be cached?
|
||||||
buffer = reverseBuffer(buffer);
|
buffer = reverseBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
const playbackRate = getBufferPlaybackRate(hapValue, buffer, transpose)
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
const bufferSource = ac.createBufferSource();
|
const bufferSource = ac.createBufferSource();
|
||||||
bufferSource.buffer = buffer;
|
bufferSource.buffer = buffer;
|
||||||
@@ -264,7 +263,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option
|
|||||||
|
|
||||||
const cutGroups = [];
|
const cutGroups = [];
|
||||||
|
|
||||||
export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
|
export async function onTriggerSample(t, value, onended, bufferSrc) {
|
||||||
let {
|
let {
|
||||||
s,
|
s,
|
||||||
nudge = 0, // TODO: is this in seconds?
|
nudge = 0, // TODO: is this in seconds?
|
||||||
@@ -286,7 +285,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
|
|||||||
// destructure adsr here, because the default should be different for synths and samples
|
// destructure adsr here, because the default should be different for synths and samples
|
||||||
let [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]);
|
let [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]);
|
||||||
|
|
||||||
const { bufferSource, sliceDuration, offset } = await getSampleBufferSource(value, bank, resolveUrl);
|
const { bufferSource, sliceDuration, offset } = bufferSrc
|
||||||
|
|
||||||
// asny stuff above took too long?
|
// asny stuff above took too long?
|
||||||
if (ac.currentTime > t) {
|
if (ac.currentTime > t) {
|
||||||
@@ -348,14 +347,21 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getBufferSrcFromBank(hapValue, bank, resolveUrl = undefined) {
|
||||||
|
const { transpose, url, label } = getCommonSampleInfoFromBank(hapValue, bank)
|
||||||
|
let buffer = await getSampleBuffer(label,url, resolveUrl);
|
||||||
|
return getSampleBufferSource(hapValue, buffer, transpose)
|
||||||
|
}
|
||||||
|
|
||||||
function registerSample(key, bank, params) {
|
function registerSample(key, bank, params) {
|
||||||
registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, bank), {
|
registerSound(key, async (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, await getBufferSrcFromBank(hapValue, bank, undefined)), {
|
||||||
type: 'sample',
|
type: 'sample',
|
||||||
samples: bank,
|
samples: bank,
|
||||||
...params,
|
...params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function registerSampleSource(key, bank, params) {
|
export function registerSampleSource(key, bank, params) {
|
||||||
const isWavetable = key.startsWith('wt_');
|
const isWavetable = key.startsWith('wt_');
|
||||||
if (isWavetable) {
|
if (isWavetable) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export function registerSound(key, onTrigger, data = {}) {
|
|||||||
soundMap.setKey(key, { onTrigger, data });
|
soundMap.setKey(key, { onTrigger, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
let gainCurveFunc = (val) => Math.pow(val, 2);
|
let gainCurveFunc = (val) => val;
|
||||||
|
|
||||||
export function applyGainCurve(val) {
|
export function applyGainCurve(val) {
|
||||||
return gainCurveFunc(val);
|
return gainCurveFunc(val);
|
||||||
@@ -141,9 +141,9 @@ export const getAudioDevices = async () => {
|
|||||||
return devicesMap;
|
return devicesMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultDefaultValues = {
|
let defaultDefaultValues = {
|
||||||
s: 'triangle',
|
s: 'triangle',
|
||||||
gain: 1,
|
gain: 0.8,
|
||||||
postgain: 1,
|
postgain: 1,
|
||||||
density: '.03',
|
density: '.03',
|
||||||
ftype: '12db',
|
ftype: '12db',
|
||||||
@@ -166,6 +166,17 @@ const defaultDefaultValues = {
|
|||||||
fft: 8,
|
fft: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const defaultDefaultDefaultValues = Object.freeze({ ...defaultDefaultValues });
|
||||||
|
|
||||||
|
export function setDefault(control, value) {
|
||||||
|
// const main = getControlName(control); // we cant do this because superdough is independent of strudel/core
|
||||||
|
defaultDefaultValues[control] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetDefaults() {
|
||||||
|
defaultDefaultValues = { ...defaultDefaultDefaultValues };
|
||||||
|
}
|
||||||
|
|
||||||
let defaultControls = new Map(Object.entries(defaultDefaultValues));
|
let defaultControls = new Map(Object.entries(defaultDefaultValues));
|
||||||
|
|
||||||
export function setDefaultValue(key, value) {
|
export function setDefaultValue(key, value) {
|
||||||
@@ -184,17 +195,9 @@ export function resetDefaultValues() {
|
|||||||
}
|
}
|
||||||
export function setVersionDefaults(version) {
|
export function setVersionDefaults(version) {
|
||||||
resetDefaultValues();
|
resetDefaultValues();
|
||||||
const v = Number(version);
|
if (version === '1.0') {
|
||||||
if (v <= 1.0) {
|
|
||||||
setDefaultValue('fanchor', 0.5);
|
setDefaultValue('fanchor', 0.5);
|
||||||
}
|
}
|
||||||
if (v <= 1.2) {
|
|
||||||
setDefaultValue('gain', 0.8);
|
|
||||||
setGainCurve((v) => v);
|
|
||||||
} else {
|
|
||||||
setDefaultValue('gain', 1);
|
|
||||||
setGainCurve((v) => Math.pow(v, 2));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const resetLoadedSounds = () => soundMap.set({});
|
export const resetLoadedSounds = () => soundMap.set({});
|
||||||
@@ -403,7 +406,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
bank,
|
bank,
|
||||||
source,
|
source,
|
||||||
gain = getDefaultValue('gain'),
|
gain = getDefaultValue('gain'),
|
||||||
gainlinear,
|
|
||||||
postgain = getDefaultValue('postgain'),
|
postgain = getDefaultValue('postgain'),
|
||||||
density = getDefaultValue('density'),
|
density = getDefaultValue('density'),
|
||||||
duckorbit,
|
duckorbit,
|
||||||
@@ -501,9 +503,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
|||||||
velocity = applyGainCurve(velocity);
|
velocity = applyGainCurve(velocity);
|
||||||
tremolodepth = applyGainCurve(tremolodepth);
|
tremolodepth = applyGainCurve(tremolodepth);
|
||||||
gain *= velocity; // velocity currently only multiplies with gain. it might do other things in the future
|
gain *= velocity; // velocity currently only multiplies with gain. it might do other things in the future
|
||||||
if (gainlinear != null) {
|
|
||||||
gain *= gainlinear;
|
|
||||||
}
|
|
||||||
|
|
||||||
const end = t + hapDuration;
|
const end = t + hapDuration;
|
||||||
const endWithRelease = end + release;
|
const endWithRelease = end + release;
|
||||||
|
|||||||
@@ -80,12 +80,13 @@ export function secondsToCycle(t, cps) {
|
|||||||
// deduces relevant info for sample loading from hap.value and sample definition
|
// deduces relevant info for sample loading from hap.value and sample definition
|
||||||
// it encapsulates the core sampler logic into a pure and synchronous function
|
// it encapsulates the core sampler logic into a pure and synchronous function
|
||||||
// hapValue: Hap.value, bank: sample bank definition for sound "s" (values in strudel.json format)
|
// hapValue: Hap.value, bank: sample bank definition for sound "s" (values in strudel.json format)
|
||||||
export function getCommonSampleInfo(hapValue, bank) {
|
export function getCommonSampleInfoFromBank(hapValue, bank) {
|
||||||
const { s, n = 0 } = hapValue;
|
const { s, n = 0 } = hapValue;
|
||||||
let midi = valueToMidi(hapValue, 36);
|
let midi = valueToMidi(hapValue, 36);
|
||||||
let transpose = midi - 36; // C3 is middle C;
|
|
||||||
let url;
|
let url;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
let {transpose, label} = getCommonSampleInfo(hapValue)
|
||||||
|
|
||||||
if (Array.isArray(bank)) {
|
if (Array.isArray(bank)) {
|
||||||
index = getSoundIndex(n, bank.length);
|
index = getSoundIndex(n, bank.length);
|
||||||
url = bank[index];
|
url = bank[index];
|
||||||
@@ -102,6 +103,20 @@ export function getCommonSampleInfo(hapValue, bank) {
|
|||||||
index = getSoundIndex(n, bank[closest].length);
|
index = getSoundIndex(n, bank[closest].length);
|
||||||
url = bank[closest][index];
|
url = bank[closest][index];
|
||||||
}
|
}
|
||||||
const label = `${s}:${index}`;
|
label = `${s}:${index}`;
|
||||||
return { transpose, url, index, midi, label };
|
return { transpose, url, label };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getCommonSampleInfo(hapValue) {
|
||||||
|
const { s, n = 0 } = hapValue;
|
||||||
|
let midi = valueToMidi(hapValue, 36);
|
||||||
|
let transpose = midi - 36; // C3 is middle C;
|
||||||
|
const label = `${s}:${n}`;
|
||||||
|
return { transpose, label };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getAudioContext, registerSound } from './index.mjs';
|
import { getAudioContext, registerSound } from './index.mjs';
|
||||||
import { getCommonSampleInfo } from './util.mjs';
|
import { getCommonSampleInfoFromBank } from './util.mjs';
|
||||||
import {
|
import {
|
||||||
applyFM,
|
applyFM,
|
||||||
applyParameterModulators,
|
applyParameterModulators,
|
||||||
@@ -216,7 +216,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) {
|
|||||||
warpmode = Warpmode[warpmode.toUpperCase()] ?? Warpmode.NONE;
|
warpmode = Warpmode[warpmode.toUpperCase()] ?? Warpmode.NONE;
|
||||||
}
|
}
|
||||||
const frequency = getFrequencyFromValue(value);
|
const frequency = getFrequencyFromValue(value);
|
||||||
const { url, label } = getCommonSampleInfo(value, tables);
|
const { url, label } = getCommonSampleInfoFromBank(value, tables);
|
||||||
const payload = await getPayload(url, label, frameLen);
|
const payload = await getPayload(url, label, frameLen);
|
||||||
let holdEnd = t + duration;
|
let holdEnd = t + duration;
|
||||||
if (clip !== undefined) {
|
if (clip !== undefined) {
|
||||||
|
|||||||
@@ -4527,75 +4527,6 @@ exports[`runs examples > example "gain" example index 0 1`] = `
|
|||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "gainlinear" example index 0 1`] = `
|
|
||||||
[
|
|
||||||
"[ 0/1 → 1/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 1/16 → 1/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 1/8 → 3/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 3/16 → 1/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 1/4 → 5/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 5/16 → 3/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 3/8 → 7/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 7/16 → 1/2 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 1/2 → 9/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 9/16 → 5/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 5/8 → 11/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 11/16 → 3/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 3/4 → 13/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 13/16 → 7/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 7/8 → 15/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 15/16 → 1/1 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 1/1 → 17/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 17/16 → 9/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 9/8 → 19/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 19/16 → 5/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 5/4 → 21/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 21/16 → 11/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 11/8 → 23/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 23/16 → 3/2 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 3/2 → 25/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 25/16 → 13/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 13/8 → 27/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 27/16 → 7/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 7/4 → 29/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 29/16 → 15/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 15/8 → 31/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 31/16 → 2/1 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 2/1 → 33/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 33/16 → 17/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 17/8 → 35/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 35/16 → 9/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 9/4 → 37/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 37/16 → 19/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 19/8 → 39/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 39/16 → 5/2 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 5/2 → 41/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 41/16 → 21/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 21/8 → 43/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 43/16 → 11/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 11/4 → 45/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 45/16 → 23/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 23/8 → 47/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 47/16 → 3/1 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 3/1 → 49/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 49/16 → 25/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 25/8 → 51/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 51/16 → 13/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 13/4 → 53/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 53/16 → 27/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 27/8 → 55/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 55/16 → 7/2 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 7/2 → 57/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 57/16 → 29/8 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 29/8 → 59/16 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 59/16 → 15/4 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 15/4 → 61/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 61/16 → 31/8 | s:hh gainlinear:1 ]",
|
|
||||||
"[ 31/8 → 63/16 | s:hh gainlinear:0.4 ]",
|
|
||||||
"[ 63/16 → 4/1 | s:hh gainlinear:1 ]",
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`runs examples > example "gap" example index 0 1`] = `[]`;
|
exports[`runs examples > example "gap" example index 0 1`] = `[]`;
|
||||||
|
|
||||||
exports[`runs examples > example "grow" example index 0 1`] = `
|
exports[`runs examples > example "grow" example index 0 1`] = `
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { registerSampleSource } from '@strudel/webaudio';
|
import { getSampleBufferSource, onTriggerSample, registerSampleSource } from '@strudel/webaudio';
|
||||||
import { isAudioFile } from './files.mjs';
|
import { isAudioFile } from './files.mjs';
|
||||||
import { logger } from '@strudel/core';
|
import { getSoundIndex, logger } from '@strudel/core';
|
||||||
|
import { registerSound } from '@strudel/webaudio';
|
||||||
|
import { getCommonSampleInfo } from '../../../packages/superdough/util.mjs';
|
||||||
|
|
||||||
//utilites for writing and reading to the indexdb
|
//utilites for writing and reading to the indexdb
|
||||||
|
|
||||||
@@ -25,6 +27,15 @@ function clearAllIDB() {
|
|||||||
|
|
||||||
export function clearIDB(dbName) {
|
export function clearIDB(dbName) {
|
||||||
return window.indexedDB.deleteDatabase(dbName);
|
return window.indexedDB.deleteDatabase(dbName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function registerSampleFromIdb(key, bank, params) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// queries the DB, and registers the sounds so they can be played
|
// queries the DB, and registers the sounds so they can be played
|
||||||
@@ -52,31 +63,76 @@ export function registerSamplesFromDB(config = userSamplesDBConfig, onComplete =
|
|||||||
if (!isAudioFile(title)) {
|
if (!isAudioFile(title)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const splitRelativePath = soundFile.id.split('/');
|
const splitRelativePath = soundFile.id.split('/');
|
||||||
let parentDirectory =
|
let parentDirectory =
|
||||||
//fallback to file name before period and seperator if no parent directory
|
//fallback to file name before period and seperator if no parent directory
|
||||||
splitRelativePath[splitRelativePath.length - 2] ?? soundFile.id.split(/\W+/)[0] ?? 'user';
|
splitRelativePath[splitRelativePath.length - 2] ?? soundFile.id.split(/\W+/)[0] ?? 'user';
|
||||||
const blob = soundFile.blob;
|
|
||||||
|
// const blob = soundFile.blob;
|
||||||
return blobToDataUrl(blob).then((soundPath) => {
|
|
||||||
const titlePathMap = sounds.get(parentDirectory) ?? new Map();
|
const titlePathMap = sounds.get(parentDirectory) ?? new Map();
|
||||||
|
|
||||||
titlePathMap.set(title, soundPath);
|
titlePathMap.set(title, soundFile.id);
|
||||||
|
|
||||||
sounds.set(parentDirectory, titlePathMap);
|
sounds.set(parentDirectory, titlePathMap);
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
// return blobToDataUrl(blob).then((soundPath) => {
|
||||||
|
// const titlePathMap = sounds.get(parentDirectory) ?? new Map();
|
||||||
|
|
||||||
|
// titlePathMap.set(title, soundPath);
|
||||||
|
|
||||||
|
// sounds.set(parentDirectory, titlePathMap);
|
||||||
|
// return;
|
||||||
|
// });
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
sounds.forEach((titlePathMap, key) => {
|
sounds.forEach((titlePathMap, key) => {
|
||||||
const value = Array.from(titlePathMap.keys())
|
const bank = Array.from(titlePathMap.keys())
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return a.localeCompare(b);
|
return a.localeCompare(b);
|
||||||
})
|
})
|
||||||
.map((title) => titlePathMap.get(title));
|
.map((title) => titlePathMap.get(title));
|
||||||
|
|
||||||
registerSampleSource(key, value, { prebake: false });
|
|
||||||
|
|
||||||
|
|
||||||
|
registerSound(key, async (t, hapValue, onended) => {
|
||||||
|
const { s, n = 0 } = hapValue;
|
||||||
|
const index = getSoundIndex(n, bank.length);
|
||||||
|
let {transpose, label} = getCommonSampleInfo(hapValue)
|
||||||
|
const storeKey = bank[index];
|
||||||
|
|
||||||
|
openDB(config, (objectStore) => {
|
||||||
|
const getRequest = objectStore.get(storeKey);
|
||||||
|
getRequest.onsuccess = async (event) => {
|
||||||
|
const result = event.target.result;
|
||||||
|
let buffer = result?.blob.arrayBuffer ? await result.blob.arrayBuffer() : null;
|
||||||
|
console.info(buffer)
|
||||||
|
if (buffer) {
|
||||||
|
const bufferSource = getSampleBufferSource(hapValue,buffer,transpose)
|
||||||
|
onTriggerSample(t, hapValue, onended, bufferSource)
|
||||||
|
} else {
|
||||||
|
logger(`Could not load sample for ${storeKey}`, 'error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
// const buffer = objectStore.getKey(key)
|
||||||
|
// const bufferSource = getSampleBufferSource(hapValue,buffer,transpose)
|
||||||
|
|
||||||
|
// onTriggerSample(t, hapValue, onended, await getBufferSrcFromBank(hapValue, bank, undefined))
|
||||||
|
|
||||||
|
}, {
|
||||||
|
type: 'sample',
|
||||||
|
samples: bank,
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// registerSampleSource(key, value, { prebake: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
logger('imported sounds registered!', 'success');
|
logger('imported sounds registered!', 'success');
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
resetGlobalEffects,
|
resetGlobalEffects,
|
||||||
resetLoadedSounds,
|
resetLoadedSounds,
|
||||||
initAudioOnFirstClick,
|
initAudioOnFirstClick,
|
||||||
|
resetDefaults,
|
||||||
} from '@strudel/webaudio';
|
} from '@strudel/webaudio';
|
||||||
import { setVersionDefaultsFrom } from './util.mjs';
|
import { setVersionDefaultsFrom } from './util.mjs';
|
||||||
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
||||||
@@ -181,6 +182,7 @@ export function useReplContext() {
|
|||||||
|
|
||||||
const resetEditor = async () => {
|
const resetEditor = async () => {
|
||||||
(await getModule('@strudel/tonal'))?.resetVoicings();
|
(await getModule('@strudel/tonal'))?.resetVoicings();
|
||||||
|
resetDefaults();
|
||||||
resetGlobalEffects();
|
resetGlobalEffects();
|
||||||
clearCanvas();
|
clearCanvas();
|
||||||
clearHydra();
|
clearHydra();
|
||||||
|
|||||||
Reference in New Issue
Block a user