mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
ramp cut audio node
This commit is contained in:
parent
8962e5a4f0
commit
6f9bcc53dc
@ -212,6 +212,7 @@ export function webAudioTimeout(audioContext, onComplete, startTime, stopTime) {
|
|||||||
constantNode.onended = () => {
|
constantNode.onended = () => {
|
||||||
onComplete();
|
onComplete();
|
||||||
};
|
};
|
||||||
|
return constantNode
|
||||||
}
|
}
|
||||||
const mod = (freq, range = 1, type = 'sine') => {
|
const mod = (freq, range = 1, type = 'sine') => {
|
||||||
const ctx = getAudioContext();
|
const ctx = getAudioContext();
|
||||||
|
|||||||
@ -345,7 +345,9 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
|
|||||||
};
|
};
|
||||||
let envEnd = holdEnd + release + 0.01;
|
let envEnd = holdEnd + release + 0.01;
|
||||||
bufferSource.stop(envEnd);
|
bufferSource.stop(envEnd);
|
||||||
const stop = (endTime, playWholeBuffer) => {};
|
const stop = (endTime) => {
|
||||||
|
bufferSource.stop(endTime)
|
||||||
|
};
|
||||||
const handle = { node: out, bufferSource, stop };
|
const handle = { node: out, bufferSource, stop };
|
||||||
|
|
||||||
// cut groups
|
// cut groups
|
||||||
|
|||||||
@ -379,7 +379,7 @@ export function resetGlobalEffects() {
|
|||||||
analysersData = {};
|
analysersData = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
let allAudioNodeChains = new Map();
|
let activeSoundSources = new Map();
|
||||||
|
|
||||||
export const superdough = async (value, t, hapDuration) => {
|
export const superdough = async (value, t, hapDuration) => {
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
@ -480,30 +480,24 @@ export const superdough = async (value, t, hapDuration) => {
|
|||||||
|
|
||||||
gain = nanFallback(gain, 1);
|
gain = nanFallback(gain, 1);
|
||||||
|
|
||||||
const chainID = Math.round(Math.random() * 10000);
|
const chainID = Math.round(Math.random() * 1000000);
|
||||||
|
|
||||||
// oldest audio nodes will be removed if maximum polyphony is exceeded
|
// oldest audio nodes will be destroyed if maximum polyphony is exceeded
|
||||||
for (let i = 0; i <= allAudioNodeChains.size - maxPolyphony; i++) {
|
for (let i = 0; i <= activeSoundSources.size - maxPolyphony; i++) {
|
||||||
const ch = allAudioNodeChains.entries().next();
|
const ch = activeSoundSources.entries().next();
|
||||||
const key = ch.value[0];
|
const source = ch.value[1];
|
||||||
const chain = ch.value[1];
|
const chainID = ch.value[0];
|
||||||
if (key == null) {
|
const endTime = t + .25;
|
||||||
continue;
|
source?.node?.gain?.linearRampToValueAtTime(0, endTime);
|
||||||
}
|
source?.stop?.(endTime);
|
||||||
chain?.forEach((node) => node?.disconnect());
|
activeSoundSources.delete(chainID);
|
||||||
allAudioNodeChains.delete(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//music programs/audio gear usually increments inputs/outputs from 1, so imitate that behavior
|
//music programs/audio gear usually increments inputs/outputs from 1, so imitate that behavior
|
||||||
channels = (Array.isArray(channels) ? channels : [channels]).map((ch) => ch - 1);
|
channels = (Array.isArray(channels) ? channels : [channels]).map((ch) => ch - 1);
|
||||||
|
|
||||||
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
|
||||||
|
let audioNodes = [];
|
||||||
|
|
||||||
const onended = () => {
|
|
||||||
const chain = allAudioNodeChains.get(chainID);
|
|
||||||
chain?.forEach((n) => n?.disconnect());
|
|
||||||
allAudioNodeChains.delete(chainID);
|
|
||||||
};
|
|
||||||
if (bank && s) {
|
if (bank && s) {
|
||||||
s = `${bank}_${s}`;
|
s = `${bank}_${s}`;
|
||||||
value.s = s;
|
value.s = s;
|
||||||
@ -515,10 +509,15 @@ export const superdough = async (value, t, hapDuration) => {
|
|||||||
sourceNode = source(t, value, hapDuration);
|
sourceNode = source(t, value, hapDuration);
|
||||||
} else if (getSound(s)) {
|
} else if (getSound(s)) {
|
||||||
const { onTrigger } = getSound(s);
|
const { onTrigger } = getSound(s);
|
||||||
const soundHandle = await onTrigger(t, value, onended);
|
const onEnded = () => {
|
||||||
|
audioNodes.forEach((n) => n?.disconnect());
|
||||||
|
activeSoundSources.delete(chainID);
|
||||||
|
};
|
||||||
|
const soundHandle = await onTrigger(t, value, onEnded);
|
||||||
|
|
||||||
if (soundHandle) {
|
if (soundHandle) {
|
||||||
sourceNode = soundHandle.node;
|
sourceNode = soundHandle.node;
|
||||||
soundHandle.stop(t + hapDuration);
|
activeSoundSources.set(chainID, soundHandle);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`sound ${s} not found! Is it loaded?`);
|
throw new Error(`sound ${s} not found! Is it loaded?`);
|
||||||
@ -648,6 +647,7 @@ export const superdough = async (value, t, hapDuration) => {
|
|||||||
if (delay > 0 && delaytime > 0 && delayfeedback > 0) {
|
if (delay > 0 && delaytime > 0 && delayfeedback > 0) {
|
||||||
const delyNode = getDelay(orbit, delaytime, delayfeedback, t);
|
const delyNode = getDelay(orbit, delaytime, delayfeedback, t);
|
||||||
delaySend = effectSend(post, delyNode, delay);
|
delaySend = effectSend(post, delyNode, delay);
|
||||||
|
audioNodes.push(delaySend);
|
||||||
}
|
}
|
||||||
// reverb
|
// reverb
|
||||||
let reverbSend;
|
let reverbSend;
|
||||||
@ -665,6 +665,7 @@ export const superdough = async (value, t, hapDuration) => {
|
|||||||
}
|
}
|
||||||
const reverbNode = getReverb(orbit, roomsize, roomfade, roomlp, roomdim, roomIR);
|
const reverbNode = getReverb(orbit, roomsize, roomfade, roomlp, roomdim, roomIR);
|
||||||
reverbSend = effectSend(post, reverbNode, room);
|
reverbSend = effectSend(post, reverbNode, room);
|
||||||
|
audioNodes.push(reverbSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
// analyser
|
// analyser
|
||||||
@ -672,11 +673,13 @@ export const superdough = async (value, t, hapDuration) => {
|
|||||||
if (analyze) {
|
if (analyze) {
|
||||||
const analyserNode = getAnalyserById(analyze, 2 ** (fft + 5));
|
const analyserNode = getAnalyserById(analyze, 2 ** (fft + 5));
|
||||||
analyserSend = effectSend(post, analyserNode, 1);
|
analyserSend = effectSend(post, analyserNode, 1);
|
||||||
|
audioNodes.push(analyserSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect chain elements together
|
// connect chain elements together
|
||||||
chain.slice(1).reduce((last, current) => last.connect(current), chain[0]);
|
chain.slice(1).reduce((last, current) => last.connect(current), chain[0]);
|
||||||
allAudioNodeChains.set(chainID, [...chain, delaySend, reverbSend, analyserSend]);
|
audioNodes = audioNodes.concat(chain);
|
||||||
|
// activeSoundSources.set(chainID, [...chain, delaySend, reverbSend, analyserSend].filter(Boolean));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const superdoughTrigger = (t, hap, ct, cps) => {
|
export const superdoughTrigger = (t, hap, ct, cps) => {
|
||||||
|
|||||||
@ -63,7 +63,9 @@ export function registerSynthSounds() {
|
|||||||
stop(envEnd);
|
stop(envEnd);
|
||||||
return {
|
return {
|
||||||
node,
|
node,
|
||||||
stop: (releaseTime) => {},
|
stop: (endTime) => {
|
||||||
|
stop(endTime);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ type: 'synth', prebake: true },
|
{ type: 'synth', prebake: true },
|
||||||
@ -110,7 +112,9 @@ export function registerSynthSounds() {
|
|||||||
let envGain = gainNode(1);
|
let envGain = gainNode(1);
|
||||||
envGain = o.connect(envGain);
|
envGain = o.connect(envGain);
|
||||||
|
|
||||||
webAudioTimeout(
|
getParamADSR(envGain.gain, attack, decay, sustain, release, 0, 0.3 * gainAdjustment, begin, holdend, 'linear');
|
||||||
|
|
||||||
|
let timeoutNode = webAudioTimeout(
|
||||||
ac,
|
ac,
|
||||||
() => {
|
() => {
|
||||||
o.disconnect();
|
o.disconnect();
|
||||||
@ -123,11 +127,11 @@ export function registerSynthSounds() {
|
|||||||
end,
|
end,
|
||||||
);
|
);
|
||||||
|
|
||||||
getParamADSR(envGain.gain, attack, decay, sustain, release, 0, 0.3 * gainAdjustment, begin, holdend, 'linear');
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
node: envGain,
|
node: envGain,
|
||||||
stop: (time) => {},
|
stop: (time) => {
|
||||||
|
timeoutNode.stop(time);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ prebake: true, type: 'synth' },
|
{ prebake: true, type: 'synth' },
|
||||||
@ -169,7 +173,10 @@ export function registerSynthSounds() {
|
|||||||
let envGain = gainNode(1);
|
let envGain = gainNode(1);
|
||||||
envGain = o.connect(envGain);
|
envGain = o.connect(envGain);
|
||||||
|
|
||||||
webAudioTimeout(
|
|
||||||
|
getParamADSR(envGain.gain, attack, decay, sustain, release, 0, 1, begin, holdend, 'linear');
|
||||||
|
|
||||||
|
let timeoutNode = webAudioTimeout(
|
||||||
ac,
|
ac,
|
||||||
() => {
|
() => {
|
||||||
o.disconnect();
|
o.disconnect();
|
||||||
@ -182,11 +189,11 @@ export function registerSynthSounds() {
|
|||||||
end,
|
end,
|
||||||
);
|
);
|
||||||
|
|
||||||
getParamADSR(envGain.gain, attack, decay, sustain, release, 0, 1, begin, holdend, 'linear');
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
node: envGain,
|
node: envGain,
|
||||||
stop: (time) => {},
|
stop: (time) => {
|
||||||
|
timeoutNode.stop(time);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ prebake: true, type: 'synth' },
|
{ prebake: true, type: 'synth' },
|
||||||
@ -229,7 +236,9 @@ export function registerSynthSounds() {
|
|||||||
stop(envEnd);
|
stop(envEnd);
|
||||||
return {
|
return {
|
||||||
node,
|
node,
|
||||||
stop: (releaseTime) => {},
|
stop: (endTime) => {
|
||||||
|
stop(endTime)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ type: 'synth', prebake: true },
|
{ type: 'synth', prebake: true },
|
||||||
@ -299,6 +308,7 @@ export function getOscillator(s, t, value) {
|
|||||||
return {
|
return {
|
||||||
node: noiseMix?.node || o,
|
node: noiseMix?.node || o,
|
||||||
stop: (time) => {
|
stop: (time) => {
|
||||||
|
// console.info(time)
|
||||||
fmModulator.stop(time);
|
fmModulator.stop(time);
|
||||||
vibratoOscillator?.stop(time);
|
vibratoOscillator?.stop(time);
|
||||||
noiseMix?.stop(time);
|
noiseMix?.stop(time);
|
||||||
|
|||||||
@ -663,6 +663,9 @@ registerProcessor('phase-vocoder-processor', PhaseVocoderProcessor);
|
|||||||
class PulseOscillatorProcessor extends AudioWorkletProcessor {
|
class PulseOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
// this.port.onmessage = (event) => {
|
||||||
|
// console.info(event)
|
||||||
|
// };
|
||||||
this.pi = _PI;
|
this.pi = _PI;
|
||||||
this.phi = -this.pi; // phase
|
this.phi = -this.pi; // phase
|
||||||
this.Y0 = 0; // feedback memories
|
this.Y0 = 0; // feedback memories
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user