mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-20 10:08:29 +00:00
can now pass meta data to setSound
+ added types for synth and sample + list sample count for samples in sounds tab (as before)
This commit is contained in:
parent
b08a0b8102
commit
35ef26c013
@ -149,7 +149,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setSound(key, (options) => onTriggerSample(options, value));
|
setSound(key, (options) => onTriggerSample(options, value), { type: 'sample', samples: value });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,31 +4,35 @@ import { getOscillator, gainNode, getADSR } from './helpers.mjs';
|
|||||||
|
|
||||||
export function registerSynthSounds() {
|
export function registerSynthSounds() {
|
||||||
['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => {
|
['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => {
|
||||||
setSound(wave, ({ hap, duration, t }) => {
|
setSound(
|
||||||
// destructure adsr here, because the default should be different for synths and samples
|
wave,
|
||||||
const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value;
|
({ hap, duration, t }) => {
|
||||||
let { n, note, freq } = hap.value;
|
// destructure adsr here, because the default should be different for synths and samples
|
||||||
// with synths, n and note are the same thing
|
const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value;
|
||||||
n = note || n || 36;
|
let { n, note, freq } = hap.value;
|
||||||
if (typeof n === 'string') {
|
// with synths, n and note are the same thing
|
||||||
n = toMidi(n); // e.g. c3 => 48
|
n = note || n || 36;
|
||||||
}
|
if (typeof n === 'string') {
|
||||||
// get frequency
|
n = toMidi(n); // e.g. c3 => 48
|
||||||
if (!freq && typeof n === 'number') {
|
}
|
||||||
freq = fromMidi(n); // + 48);
|
// get frequency
|
||||||
}
|
if (!freq && typeof n === 'number') {
|
||||||
// maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default)
|
freq = fromMidi(n); // + 48);
|
||||||
// make oscillator
|
}
|
||||||
const o = getOscillator({ t, s: wave, freq, duration, release });
|
// maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default)
|
||||||
// chain.push(o);
|
// make oscillator
|
||||||
// level down oscillators as they are really loud compared to samples i've tested
|
const o = getOscillator({ t, s: wave, freq, duration, release });
|
||||||
//chain.push(gainNode(0.3));
|
// chain.push(o);
|
||||||
const g = gainNode(0.3);
|
// level down oscillators as they are really loud compared to samples i've tested
|
||||||
// TODO: make adsr work with samples without pops
|
//chain.push(gainNode(0.3));
|
||||||
// envelope
|
const g = gainNode(0.3);
|
||||||
const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration);
|
// TODO: make adsr work with samples without pops
|
||||||
//chain.push(adsr);
|
// envelope
|
||||||
return o.connect(g).connect(adsr);
|
const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration);
|
||||||
});
|
//chain.push(adsr);
|
||||||
|
return o.connect(g).connect(adsr);
|
||||||
|
},
|
||||||
|
{ type: 'synth' },
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,8 @@ import { map } from 'nanostores';
|
|||||||
|
|
||||||
export const soundMap = map();
|
export const soundMap = map();
|
||||||
// onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode
|
// onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode
|
||||||
export function setSound(key, onTrigger) {
|
export function setSound(key, onTrigger, data = {}) {
|
||||||
soundMap.setKey(key, onTrigger);
|
soundMap.setKey(key, { onTrigger, data });
|
||||||
}
|
}
|
||||||
export const resetLoadedSounds = () => soundMap.set({});
|
export const resetLoadedSounds = () => soundMap.set({});
|
||||||
|
|
||||||
@ -166,7 +166,8 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => {
|
|||||||
if (source) {
|
if (source) {
|
||||||
node = source(options);
|
node = source(options);
|
||||||
} else if (soundMap.get()[s]) {
|
} else if (soundMap.get()[s]) {
|
||||||
node = await soundMap.get()[s](options);
|
const { onTrigger } = soundMap.get()[s];
|
||||||
|
node = await onTrigger(options);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`sound ${s} not found! Is it loaded?`);
|
throw new Error(`sound ${s} not found! Is it loaded?`);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -196,15 +196,15 @@ function ConsoleTab({ log }) {
|
|||||||
|
|
||||||
function SoundsTab() {
|
function SoundsTab() {
|
||||||
const sounds = useStore(soundMap);
|
const sounds = useStore(soundMap);
|
||||||
|
const getSamples = (samples) =>
|
||||||
|
Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1;
|
||||||
return (
|
return (
|
||||||
<div id="sounds-tab" className="break-normal w-full px-4 dark:text-white text-stone-900">
|
<div id="sounds-tab" className="break-normal w-full px-4 dark:text-white text-stone-900">
|
||||||
{/* <span>{loadedSamples.length} banks loaded:</span> */}
|
{/* <span>{loadedSamples.length} banks loaded:</span> */}
|
||||||
{Object.entries(sounds).map(([name, samples]) => (
|
{Object.entries(sounds).map(([name, { data }]) => (
|
||||||
<span key={name} className="cursor-pointer hover:opacity-50" onClick={() => {}}>
|
<span key={name} className="cursor-pointer hover:opacity-50" onClick={() => {}}>
|
||||||
{' '}
|
{' '}
|
||||||
{name}
|
{name} {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''}
|
||||||
{/* (
|
|
||||||
{Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1}) */}
|
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user