mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-13 06:38:31 +00:00
commit
b7b576e38b
@ -581,6 +581,11 @@ const generic_params = [
|
||||
'size',
|
||||
'a pattern of numbers from 0 to 1. Sets the perceptual size (reverb time) of the `room` to be used in reverb.',
|
||||
],
|
||||
[
|
||||
'f',
|
||||
'roomsize',
|
||||
'a pattern of numbers from 0 to 1. Sets the perceptual size (reverb time) of the `room` to be used in reverb.',
|
||||
],
|
||||
// ['f', 'sagogo', ''],
|
||||
// ['f', 'sclap', ''],
|
||||
// ['f', 'sclaves', ''],
|
||||
|
||||
20
packages/webaudio/reverb.mjs
Normal file
20
packages/webaudio/reverb.mjs
Normal file
@ -0,0 +1,20 @@
|
||||
if (typeof AudioContext !== 'undefined') {
|
||||
AudioContext.prototype.impulseResponse = function (duration) {
|
||||
const length = this.sampleRate * duration;
|
||||
const impulse = this.createBuffer(2, length, this.sampleRate);
|
||||
const IR = impulse.getChannelData(0);
|
||||
for (let i = 0; i < length; i++) IR[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, duration);
|
||||
return impulse;
|
||||
};
|
||||
|
||||
AudioContext.prototype.createReverb = function (duration) {
|
||||
const convolver = this.createConvolver();
|
||||
convolver.setDuration = (d) => {
|
||||
convolver.buffer = this.impulseResponse(d);
|
||||
convolver.duration = duration;
|
||||
return convolver;
|
||||
};
|
||||
convolver.setDuration(duration);
|
||||
return convolver;
|
||||
};
|
||||
}
|
||||
@ -8,6 +8,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
import * as strudel from '@strudel.cycles/core';
|
||||
import { fromMidi, toMidi } from '@strudel.cycles/core';
|
||||
import './feedbackdelay.mjs';
|
||||
import './reverb.mjs';
|
||||
import { loadBuffer, reverseBuffer } from './sampler.mjs';
|
||||
const { Pattern } = strudel;
|
||||
import './vowel.mjs';
|
||||
@ -207,6 +208,21 @@ function getDelay(orbit, delaytime, delayfeedback, t) {
|
||||
return delays[orbit];
|
||||
}
|
||||
|
||||
let reverbs = {};
|
||||
function getReverb(orbit, duration = 2) {
|
||||
if (!reverbs[orbit]) {
|
||||
const ac = getAudioContext();
|
||||
const reverb = ac.createReverb(duration);
|
||||
reverb.connect(getDestination());
|
||||
reverbs[orbit] = reverb;
|
||||
}
|
||||
if (reverbs[orbit].duration !== duration) {
|
||||
reverbs[orbit] = reverbs[orbit].setDuration(duration);
|
||||
reverbs[orbit].duration = duration;
|
||||
}
|
||||
return reverbs[orbit];
|
||||
}
|
||||
|
||||
function effectSend(input, effect, wet) {
|
||||
const send = gainNode(wet);
|
||||
input.connect(send);
|
||||
@ -260,6 +276,9 @@ export const webaudioOutput = async (hap, deadline, hapDuration) => {
|
||||
cut,
|
||||
loop,
|
||||
orbit = 1,
|
||||
room,
|
||||
size = 2,
|
||||
roomsize = size,
|
||||
} = hap.value;
|
||||
const { velocity = 1 } = hap.context;
|
||||
gain *= velocity; // legacy fix for velocity
|
||||
@ -386,12 +405,18 @@ export const webaudioOutput = async (hap, deadline, hapDuration) => {
|
||||
const delyNode = getDelay(orbit, delaytime, delayfeedback, t);
|
||||
delaySend = effectSend(post, delyNode, delay);
|
||||
}
|
||||
// reverb
|
||||
let reverbSend;
|
||||
if (room > 0 && roomsize > 0) {
|
||||
const reverbNode = getReverb(orbit, roomsize);
|
||||
reverbSend = effectSend(post, reverbNode, room);
|
||||
}
|
||||
|
||||
// connect chain elements together
|
||||
chain.slice(1).reduce((last, current) => last.connect(current), chain[0]);
|
||||
|
||||
// disconnect all nodes when source node has ended:
|
||||
chain[0].onended = () => chain.concat([delaySend]).forEach((n) => n?.disconnect());
|
||||
chain[0].onended = () => chain.concat([delaySend, reverbSend]).forEach((n) => n?.disconnect());
|
||||
} catch (e) {
|
||||
console.warn('.out error:', e);
|
||||
}
|
||||
|
||||
@ -1743,6 +1743,19 @@ exports[`renders tunes > tune: caverave 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders tunes > tune: chop 1`] = `
|
||||
[
|
||||
"0/1 -> 1/4: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0,\\"end\\":0.0078125,\\"pan\\":0,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"1/4 -> 1/2: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0.0078125,\\"end\\":0.015625,\\"pan\\":0,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"1/2 -> 3/4: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0.015625,\\"end\\":0.0234375,\\"pan\\":0,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"3/4 -> 1/1: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0.0234375,\\"end\\":0.03125,\\"pan\\":0,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"3/4 -> 1/1: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0,\\"end\\":0.0078125,\\"pan\\":1,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"1/2 -> 3/4: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0.0078125,\\"end\\":0.015625,\\"pan\\":1,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"1/4 -> 1/2: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0.015625,\\"end\\":0.0234375,\\"pan\\":1,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
"0/1 -> 1/4: {\\"s\\":\\"p\\",\\"speed\\":0.03125,\\"unit\\":\\"c\\",\\"begin\\":0.0234375,\\"end\\":0.03125,\\"pan\\":1,\\"shape\\":0.4,\\"decay\\":0.1,\\"sustain\\":0.6}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders tunes > tune: customTrigger 1`] = `
|
||||
[
|
||||
"0/1 -> 1/8: {\\"freq\\":55.33,\\"s\\":\\"sawtooth\\"}",
|
||||
@ -1771,6 +1784,13 @@ exports[`renders tunes > tune: customTrigger 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders tunes > tune: delay 1`] = `
|
||||
[
|
||||
"0/1 -> 1/2: {\\"s\\":\\"bd\\",\\"delay\\":0,\\"delaytime\\":0.16,\\"delayfeedback\\":0.8,\\"speed\\":-1}",
|
||||
"1/2 -> 1/1: {\\"s\\":\\"sd\\",\\"delay\\":0,\\"delaytime\\":0.16,\\"delayfeedback\\":0.8,\\"speed\\":-1}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders tunes > tune: echoPiano 1`] = `
|
||||
[
|
||||
"0/1 -> 1/2: {\\"note\\":\\"D3\\",\\"clip\\":1,\\"s\\":\\"piano\\",\\"release\\":0.1,\\"pan\\":0.4814814814814815}",
|
||||
@ -13380,6 +13400,15 @@ exports[`renders tunes > tune: meltingsubmarine 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders tunes > tune: orbit 1`] = `
|
||||
[
|
||||
"0/1 -> 1/2: {\\"s\\":\\"bd\\",\\"delay\\":0.5,\\"delaytime\\":0.33,\\"delayfeedback\\":0.6,\\"speed\\":-1}",
|
||||
"1/2 -> 1/1: {\\"s\\":\\"sd\\",\\"delay\\":0.5,\\"delaytime\\":0.33,\\"delayfeedback\\":0.6,\\"speed\\":-1}",
|
||||
"0/1 -> 1/2: {\\"s\\":\\"hh\\",\\"delay\\":0.8,\\"delaytime\\":0.08,\\"delayfeedback\\":0.7,\\"orbit\\":2,\\"speed\\":-1}",
|
||||
"1/2 -> 1/1: {\\"s\\":\\"hh\\",\\"delay\\":0.8,\\"delaytime\\":0.08,\\"delayfeedback\\":0.7,\\"orbit\\":2,\\"speed\\":-1}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders tunes > tune: outroMusic 1`] = `
|
||||
[
|
||||
"0/1 -> 3/1: {\\"n\\":\\"B3\\",\\"s\\":\\"0040_FluidR3_GM_sf2_file\\",\\"attack\\":0.05,\\"decay\\":0.1,\\"sustain\\":0.7,\\"cutoff\\":1111.7252990603447,\\"gain\\":0.3}",
|
||||
|
||||
@ -897,3 +897,33 @@ stack(
|
||||
x? ~ ~ x ~ x@3\`),
|
||||
roots.struct("x [~ x?0.2] x [~ x?] | x!4 | x@2 ~ ~ ~ x x x").transpose("0 7")
|
||||
).slow(2).pianoroll().note().piano().out();`;
|
||||
|
||||
export const chop = `samples({ p: 'https://cdn.freesound.org/previews/648/648433_11943129-lq.mp3' })
|
||||
|
||||
s("p")
|
||||
.loopAt(32,1)
|
||||
.chop(128)
|
||||
.jux(rev)
|
||||
.shape(.4)
|
||||
.decay(.1)
|
||||
.sustain(.6)
|
||||
.out()`;
|
||||
|
||||
export const delay = `stack(
|
||||
s("bd <sd cp>")
|
||||
.delay("<0 .5>")
|
||||
.delaytime(".16 | .33")
|
||||
.delayfeedback(".6 | .8")
|
||||
).sometimes(x=>x.speed("-1")).out()`;
|
||||
|
||||
export const orbit = `stack(
|
||||
s("bd <sd cp>")
|
||||
.delay(.5)
|
||||
.delaytime(.33)
|
||||
.delayfeedback(.6),
|
||||
s("hh*2")
|
||||
.delay(.8)
|
||||
.delaytime(.08)
|
||||
.delayfeedback(.7)
|
||||
.orbit(2)
|
||||
).sometimes(x=>x.speed("-1")).out()`;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user