Merge branch 'main' into patterns-tab
This commit is contained in:
commit
e72c9cbebf
49 changed files with 712 additions and 255 deletions
|
|
@ -27,28 +27,16 @@ export function getSound(s) {
|
|||
export const resetLoadedSounds = () => soundMap.set({});
|
||||
|
||||
let audioContext;
|
||||
|
||||
export const getAudioContext = () => {
|
||||
if (!audioContext) {
|
||||
audioContext = new AudioContext();
|
||||
const maxChannelCount = audioContext.destination.maxChannelCount;
|
||||
audioContext.destination.channelCount = maxChannelCount;
|
||||
}
|
||||
return audioContext;
|
||||
};
|
||||
|
||||
let destination;
|
||||
const getDestination = () => {
|
||||
const ctx = getAudioContext();
|
||||
if (!destination) {
|
||||
destination = ctx.createGain();
|
||||
destination.connect(ctx.destination);
|
||||
}
|
||||
return destination;
|
||||
};
|
||||
|
||||
export const panic = () => {
|
||||
getDestination().gain.linearRampToValueAtTime(0, getAudioContext().currentTime + 0.01);
|
||||
destination = null;
|
||||
};
|
||||
|
||||
let workletsLoading;
|
||||
|
||||
function loadWorklets() {
|
||||
|
|
@ -95,6 +83,39 @@ export async function initAudioOnFirstClick(options) {
|
|||
let delays = {};
|
||||
const maxfeedback = 0.98;
|
||||
|
||||
let channelMerger, destinationGain;
|
||||
|
||||
// input: AudioNode, channels: ?Array<int>
|
||||
export const connectToDestination = (input, channels = [0, 1]) => {
|
||||
const ctx = getAudioContext();
|
||||
if (channelMerger == null) {
|
||||
channelMerger = new ChannelMergerNode(ctx, { numberOfInputs: ctx.destination.channelCount });
|
||||
destinationGain = new GainNode(ctx);
|
||||
channelMerger.connect(destinationGain);
|
||||
destinationGain.connect(ctx.destination);
|
||||
}
|
||||
//This upmix can be removed if correct channel counts are set throughout the app,
|
||||
// and then strudel could theoretically support surround sound audio files
|
||||
const stereoMix = new StereoPannerNode(ctx);
|
||||
input.connect(stereoMix);
|
||||
|
||||
const splitter = new ChannelSplitterNode(ctx, {
|
||||
numberOfOutputs: stereoMix.channelCount,
|
||||
});
|
||||
stereoMix.connect(splitter);
|
||||
channels.forEach((ch, i) => {
|
||||
splitter.connect(channelMerger, i % stereoMix.channelCount, clamp(ch, 0, ctx.destination.channelCount - 1));
|
||||
});
|
||||
};
|
||||
|
||||
export const panic = () => {
|
||||
if (destinationGain == null) {
|
||||
return;
|
||||
}
|
||||
destinationGain.gain.linearRampToValueAtTime(0, getAudioContext().currentTime + 0.01);
|
||||
destinationGain = null;
|
||||
};
|
||||
|
||||
function getDelay(orbit, delaytime, delayfeedback, t) {
|
||||
if (delayfeedback > maxfeedback) {
|
||||
//logger(`delayfeedback was clamped to ${maxfeedback} to save your ears`);
|
||||
|
|
@ -104,7 +125,7 @@ function getDelay(orbit, delaytime, delayfeedback, t) {
|
|||
const ac = getAudioContext();
|
||||
const dly = ac.createFeedbackDelay(1, delaytime, delayfeedback);
|
||||
dly.start?.(t); // for some reason, this throws when audion extension is installed..
|
||||
dly.connect(getDestination());
|
||||
connectToDestination(dly, [0, 1]);
|
||||
delays[orbit] = dly;
|
||||
}
|
||||
delays[orbit].delayTime.value !== delaytime && delays[orbit].delayTime.setValueAtTime(delaytime, t);
|
||||
|
|
@ -163,7 +184,7 @@ function getReverb(orbit, duration, fade, lp, dim, ir) {
|
|||
if (!reverbs[orbit]) {
|
||||
const ac = getAudioContext();
|
||||
const reverb = ac.createReverb(duration, fade, lp, dim, ir);
|
||||
reverb.connect(getDestination());
|
||||
connectToDestination(reverb, [0, 1]);
|
||||
reverbs[orbit] = reverb;
|
||||
}
|
||||
if (
|
||||
|
|
@ -241,6 +262,7 @@ export const superdough = async (value, deadline, hapDuration) => {
|
|||
source,
|
||||
gain = 0.8,
|
||||
postgain = 1,
|
||||
density = 0.03,
|
||||
// filters
|
||||
ftype = '12db',
|
||||
fanchor = 0.5,
|
||||
|
|
@ -268,7 +290,7 @@ export const superdough = async (value, deadline, hapDuration) => {
|
|||
bpsustain = 1,
|
||||
bprelease = 0.01,
|
||||
bandq = 1,
|
||||
|
||||
channels = [1, 2],
|
||||
//phaser
|
||||
phaser,
|
||||
phaserdepth = 0.75,
|
||||
|
|
@ -301,6 +323,10 @@ export const superdough = async (value, deadline, hapDuration) => {
|
|||
compressorRelease,
|
||||
} = value;
|
||||
gain = nanFallback(gain, 1);
|
||||
|
||||
//music programs/audio gear usually increments inputs/outputs from 1, so imitate that behavior
|
||||
channels = (Array.isArray(channels) ? channels : [channels]).map((ch) => ch - 1);
|
||||
|
||||
gain *= velocity; // legacy fix for velocity
|
||||
let toDisconnect = []; // audio nodes that will be disconnected when the source has ended
|
||||
const onended = () => {
|
||||
|
|
@ -434,9 +460,9 @@ export const superdough = async (value, deadline, hapDuration) => {
|
|||
}
|
||||
|
||||
// last gain
|
||||
const post = gainNode(postgain);
|
||||
const post = new GainNode(ac, { gain: postgain });
|
||||
chain.push(post);
|
||||
post.connect(getDestination());
|
||||
connectToDestination(post, channels);
|
||||
|
||||
// delay
|
||||
let delaySend;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue