Merge pull request #718 from Bubobubobubobubo/reverb
Better convolution reverb by generating impulse responses
This commit is contained in:
commit
0b888ac54d
7 changed files with 341 additions and 42 deletions
|
|
@ -19,3 +19,4 @@ vite.config.js
|
||||||
**/dev-dist
|
**/dev-dist
|
||||||
**/dist
|
**/dist
|
||||||
/src-tauri/target/**/*
|
/src-tauri/target/**/*
|
||||||
|
reverbGen.mjs
|
||||||
|
|
@ -979,20 +979,64 @@ const generic_params = [
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
[['room', 'size']],
|
[['room', 'size']],
|
||||||
|
/**
|
||||||
|
* Reverb lowpass starting frequency (in hertz).
|
||||||
|
* When this property is changed, the reverb will be recaculated, so only change this sparsely..
|
||||||
|
*
|
||||||
|
* @name roomlp
|
||||||
|
* @synonyms rlp
|
||||||
|
* @param {number} frequency between 0 and 20000hz
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(0.5).rlp(10000)
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(0.5).rlp(5000)
|
||||||
|
*/
|
||||||
|
['roomlp', 'rlp'],
|
||||||
|
/**
|
||||||
|
* Reverb lowpass frequency at -60dB (in hertz).
|
||||||
|
* When this property is changed, the reverb will be recaculated, so only change this sparsely..
|
||||||
|
*
|
||||||
|
* @name roomdim
|
||||||
|
* @synonyms rdim
|
||||||
|
* @param {number} frequency between 0 and 20000hz
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(0.5).rlp(10000).rdim(8000)
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(0.5).rlp(5000).rdim(400)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
['roomdim', 'rdim'],
|
||||||
|
/**
|
||||||
|
* Reverb fade time (in seconds).
|
||||||
|
* When this property is changed, the reverb will be recaculated, so only change this sparsely..
|
||||||
|
*
|
||||||
|
* @name roomfade
|
||||||
|
* @synonyms rfade
|
||||||
|
* @param {number} seconds for the reverb to fade
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(0.5).rlp(10000).rfade(0.5)
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(0.5).rlp(5000).rfade(4)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
['roomfade', 'rfade'],
|
||||||
/**
|
/**
|
||||||
* Sets the room size of the reverb, see {@link room}.
|
* Sets the room size of the reverb, see {@link room}.
|
||||||
|
* When this property is changed, the reverb will be recaculated, so only change this sparsely..
|
||||||
*
|
*
|
||||||
* @name roomsize
|
* @name roomsize
|
||||||
* @param {number | Pattern} size between 0 and 10
|
* @param {number | Pattern} size between 0 and 10
|
||||||
* @synonyms size, sz
|
* @synonyms rsize, sz, size
|
||||||
* @example
|
* @example
|
||||||
* s("bd sd").room(.8).roomsize("<0 1 2 4 8>")
|
* s("bd sd").room(.8).rsize(1)
|
||||||
|
* @example
|
||||||
|
* s("bd sd").room(.8).rsize(4)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// TODO: find out why :
|
// TODO: find out why :
|
||||||
// s("bd sd").room(.8).roomsize("<0 .2 .4 .6 .8 [1,0]>").osc()
|
// s("bd sd").room(.8).roomsize("<0 .2 .4 .6 .8 [1,0]>").osc()
|
||||||
// .. does not work. Is it because room is only one effect?
|
// .. does not work. Is it because room is only one effect?
|
||||||
['size', 'sz', 'roomsize'],
|
['roomsize', 'size', 'sz', 'rsize'],
|
||||||
// ['sagogo'],
|
// ['sagogo'],
|
||||||
// ['sclap'],
|
// ['sclap'],
|
||||||
// ['sclaves'],
|
// ['sclaves'],
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,30 @@
|
||||||
if (typeof AudioContext !== 'undefined') {
|
import reverbGen from './reverbGen.mjs';
|
||||||
AudioContext.prototype.impulseResponse = function (duration, channels = 1) {
|
|
||||||
const length = this.sampleRate * duration;
|
|
||||||
const impulse = this.createBuffer(channels, 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) {
|
if (typeof AudioContext !== 'undefined') {
|
||||||
|
AudioContext.prototype.generateReverb = reverbGen.generateReverb;
|
||||||
|
AudioContext.prototype.createReverb = function (duration, fade, lp, dim) {
|
||||||
const convolver = this.createConvolver();
|
const convolver = this.createConvolver();
|
||||||
convolver.setDuration = (d) => {
|
convolver.generate = (d, fade, lp, dim) => {
|
||||||
convolver.buffer = this.impulseResponse(d);
|
this.generateReverb(
|
||||||
convolver.duration = duration;
|
{
|
||||||
return convolver;
|
audioContext: this,
|
||||||
|
sampleRate: 44100,
|
||||||
|
numChannels: 2,
|
||||||
|
decayTime: d,
|
||||||
|
fadeInTime: fade,
|
||||||
|
lpFreqStart: lp,
|
||||||
|
lpFreqEnd: dim,
|
||||||
|
},
|
||||||
|
(buffer) => {
|
||||||
|
convolver.buffer = buffer;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
convolver.duration = d;
|
||||||
|
convolver.fade = fade;
|
||||||
|
convolver.lp = lp;
|
||||||
|
convolver.dim = dim;
|
||||||
};
|
};
|
||||||
convolver.setDuration(duration);
|
convolver.generate(duration, fade, lp, dim);
|
||||||
return convolver;
|
return convolver;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make the reverb more exciting
|
|
||||||
// check out https://blog.gskinner.com/archives/2019/02/reverb-web-audio-api.html
|
|
||||||
|
|
|
||||||
129
packages/superdough/reverbGen.mjs
Normal file
129
packages/superdough/reverbGen.mjs
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
// Copyright 2014 Alan deLespinasse
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
var reverbGen = {};
|
||||||
|
|
||||||
|
/** Generates a reverb impulse response.
|
||||||
|
|
||||||
|
@param {!Object} params TODO: Document the properties.
|
||||||
|
@param {!function(!AudioBuffer)} callback Function to call when
|
||||||
|
the impulse response has been generated. The impulse response
|
||||||
|
is passed to this function as its parameter. May be called
|
||||||
|
immediately within the current execution context, or later. */
|
||||||
|
reverbGen.generateReverb = function (params, callback) {
|
||||||
|
var audioContext = params.audioContext || new AudioContext();
|
||||||
|
var sampleRate = params.sampleRate || 44100;
|
||||||
|
var numChannels = params.numChannels || 2;
|
||||||
|
// params.decayTime is the -60dB fade time. We let it go 50% longer to get to -90dB.
|
||||||
|
var totalTime = params.decayTime * 1.5;
|
||||||
|
var decaySampleFrames = Math.round(params.decayTime * sampleRate);
|
||||||
|
var numSampleFrames = Math.round(totalTime * sampleRate);
|
||||||
|
var fadeInSampleFrames = Math.round((params.fadeInTime || 0) * sampleRate);
|
||||||
|
// 60dB is a factor of 1 million in power, or 1000 in amplitude.
|
||||||
|
var decayBase = Math.pow(1 / 1000, 1 / decaySampleFrames);
|
||||||
|
var reverbIR = audioContext.createBuffer(numChannels, numSampleFrames, sampleRate);
|
||||||
|
for (var i = 0; i < numChannels; i++) {
|
||||||
|
var chan = reverbIR.getChannelData(i);
|
||||||
|
for (var j = 0; j < numSampleFrames; j++) {
|
||||||
|
chan[j] = randomSample() * Math.pow(decayBase, j);
|
||||||
|
}
|
||||||
|
for (var j = 0; j < fadeInSampleFrames; j++) {
|
||||||
|
chan[j] *= j / fadeInSampleFrames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyGradualLowpass(reverbIR, params.lpFreqStart || 0, params.lpFreqEnd || 0, params.decayTime, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Creates a canvas element showing a graph of the given data.
|
||||||
|
|
||||||
|
@param {!Float32Array} data An array of numbers, or a Float32Array.
|
||||||
|
@param {number} width Width in pixels of the canvas.
|
||||||
|
@param {number} height Height in pixels of the canvas.
|
||||||
|
@param {number} min Minimum value of data for the graph (lower edge).
|
||||||
|
@param {number} max Maximum value of data in the graph (upper edge).
|
||||||
|
@return {!CanvasElement} The generated canvas element. */
|
||||||
|
reverbGen.generateGraph = function (data, width, height, min, max) {
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
var gc = canvas.getContext('2d');
|
||||||
|
gc.fillStyle = '#000';
|
||||||
|
gc.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
gc.fillStyle = '#fff';
|
||||||
|
var xscale = width / data.length;
|
||||||
|
var yscale = height / (max - min);
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
gc.fillRect(i * xscale, height - (data[i] - min) * yscale, 1, 1);
|
||||||
|
}
|
||||||
|
return canvas;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Applies a constantly changing lowpass filter to the given sound.
|
||||||
|
|
||||||
|
@private
|
||||||
|
@param {!AudioBuffer} input
|
||||||
|
@param {number} lpFreqStart
|
||||||
|
@param {number} lpFreqEnd
|
||||||
|
@param {number} lpFreqEndAt
|
||||||
|
@param {!function(!AudioBuffer)} callback May be called
|
||||||
|
immediately within the current execution context, or later.*/
|
||||||
|
var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) {
|
||||||
|
if (lpFreqStart == 0) {
|
||||||
|
callback(input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var channelData = getAllChannelData(input);
|
||||||
|
var context = new OfflineAudioContext(input.numberOfChannels, channelData[0].length, input.sampleRate);
|
||||||
|
var player = context.createBufferSource();
|
||||||
|
player.buffer = input;
|
||||||
|
var filter = context.createBiquadFilter();
|
||||||
|
|
||||||
|
lpFreqStart = Math.min(lpFreqStart, input.sampleRate / 2);
|
||||||
|
lpFreqEnd = Math.min(lpFreqEnd, input.sampleRate / 2);
|
||||||
|
|
||||||
|
filter.type = 'lowpass';
|
||||||
|
filter.Q.value = 0.0001;
|
||||||
|
filter.frequency.setValueAtTime(lpFreqStart, 0);
|
||||||
|
filter.frequency.linearRampToValueAtTime(lpFreqEnd, lpFreqEndAt);
|
||||||
|
|
||||||
|
player.connect(filter);
|
||||||
|
filter.connect(context.destination);
|
||||||
|
player.start();
|
||||||
|
context.oncomplete = function (event) {
|
||||||
|
callback(event.renderedBuffer);
|
||||||
|
};
|
||||||
|
context.startRendering();
|
||||||
|
|
||||||
|
window.filterNode = filter;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @private
|
||||||
|
@param {!AudioBuffer} buffer
|
||||||
|
@return {!Array.<!Float32Array>} An array containing the Float32Array of each channel's samples. */
|
||||||
|
var getAllChannelData = function (buffer) {
|
||||||
|
var channels = [];
|
||||||
|
for (var i = 0; i < buffer.numberOfChannels; i++) {
|
||||||
|
channels[i] = buffer.getChannelData(i);
|
||||||
|
}
|
||||||
|
return channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @private
|
||||||
|
@return {number} A random number from -1 to 1. */
|
||||||
|
var randomSample = function () {
|
||||||
|
return Math.random() * 2 - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default reverbGen;
|
||||||
|
|
@ -107,17 +107,25 @@ function getDelay(orbit, delaytime, delayfeedback, t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let reverbs = {};
|
let reverbs = {};
|
||||||
function getReverb(orbit, duration = 2) {
|
|
||||||
|
function getReverb(orbit, duration = 2, fade, lp, dim) {
|
||||||
|
// If no reverb has been created for a given orbit, create one
|
||||||
if (!reverbs[orbit]) {
|
if (!reverbs[orbit]) {
|
||||||
const ac = getAudioContext();
|
const ac = getAudioContext();
|
||||||
const reverb = ac.createReverb(duration);
|
const reverb = ac.createReverb(duration, fade, lp, dim);
|
||||||
reverb.connect(getDestination());
|
reverb.connect(getDestination());
|
||||||
reverbs[orbit] = reverb;
|
reverbs[orbit] = reverb;
|
||||||
}
|
}
|
||||||
if (reverbs[orbit].duration !== duration) {
|
|
||||||
reverbs[orbit] = reverbs[orbit].setDuration(duration);
|
if (
|
||||||
reverbs[orbit].duration = duration;
|
reverbs[orbit].duration !== duration ||
|
||||||
|
reverbs[orbit].fade !== fade ||
|
||||||
|
reverbs[orbit].lp !== lp ||
|
||||||
|
reverbs[orbit].dim !== dim
|
||||||
|
) {
|
||||||
|
reverbs[orbit].generate(duration, fade, lp, dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reverbs[orbit];
|
return reverbs[orbit];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +223,10 @@ export const superdough = async (value, deadline, hapDuration) => {
|
||||||
delaytime = 0.25,
|
delaytime = 0.25,
|
||||||
orbit = 1,
|
orbit = 1,
|
||||||
room,
|
room,
|
||||||
size = 2,
|
roomfade = 0.1,
|
||||||
|
roomlp = 15000,
|
||||||
|
roomdim = 1000,
|
||||||
|
roomsize = 2,
|
||||||
velocity = 1,
|
velocity = 1,
|
||||||
analyze, // analyser wet
|
analyze, // analyser wet
|
||||||
fft = 8, // fftSize 0 - 10
|
fft = 8, // fftSize 0 - 10
|
||||||
|
|
@ -353,8 +364,8 @@ export const superdough = async (value, deadline, hapDuration) => {
|
||||||
}
|
}
|
||||||
// reverb
|
// reverb
|
||||||
let reverbSend;
|
let reverbSend;
|
||||||
if (room > 0 && size > 0) {
|
if (room > 0 && roomsize > 0) {
|
||||||
const reverbNode = getReverb(orbit, size);
|
const reverbNode = getReverb(orbit, roomsize, roomfade, roomlp, roomdim);
|
||||||
reverbSend = effectSend(post, reverbNode, room);
|
reverbSend = effectSend(post, reverbNode, room);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3663,16 +3663,107 @@ exports[`runs examples > example "room" example index 1 1`] = `
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomdim" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.5 roomlp:10000 roomdim:8000 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomdim" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.5 roomlp:5000 roomdim:400 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomfade" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.5 roomlp:10000 roomfade:0.5 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomfade" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.5 roomlp:5000 roomfade:4 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomlp" example index 0 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.5 roomlp:10000 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.5 roomlp:10000 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomlp" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.5 roomlp:5000 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.5 roomlp:5000 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "roomsize" example index 0 1`] = `
|
exports[`runs examples > example "roomsize" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/2 | s:bd room:0.8 size:0 ]",
|
"[ 0/1 → 1/2 | s:bd room:0.8 roomsize:1 ]",
|
||||||
"[ 1/2 → 1/1 | s:sd room:0.8 size:0 ]",
|
"[ 1/2 → 1/1 | s:sd room:0.8 roomsize:1 ]",
|
||||||
"[ 1/1 → 3/2 | s:bd room:0.8 size:1 ]",
|
"[ 1/1 → 3/2 | s:bd room:0.8 roomsize:1 ]",
|
||||||
"[ 3/2 → 2/1 | s:sd room:0.8 size:1 ]",
|
"[ 3/2 → 2/1 | s:sd room:0.8 roomsize:1 ]",
|
||||||
"[ 2/1 → 5/2 | s:bd room:0.8 size:2 ]",
|
"[ 2/1 → 5/2 | s:bd room:0.8 roomsize:1 ]",
|
||||||
"[ 5/2 → 3/1 | s:sd room:0.8 size:2 ]",
|
"[ 5/2 → 3/1 | s:sd room:0.8 roomsize:1 ]",
|
||||||
"[ 3/1 → 7/2 | s:bd room:0.8 size:4 ]",
|
"[ 3/1 → 7/2 | s:bd room:0.8 roomsize:1 ]",
|
||||||
"[ 7/2 → 4/1 | s:sd room:0.8 size:4 ]",
|
"[ 7/2 → 4/1 | s:sd room:0.8 roomsize:1 ]",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`runs examples > example "roomsize" example index 1 1`] = `
|
||||||
|
[
|
||||||
|
"[ 0/1 → 1/2 | s:bd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 1/2 → 1/1 | s:sd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 1/1 → 3/2 | s:bd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 3/2 → 2/1 | s:sd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 2/1 → 5/2 | s:bd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 5/2 → 3/1 | s:sd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 3/1 → 7/2 | s:bd room:0.8 roomsize:4 ]",
|
||||||
|
"[ 7/2 → 4/1 | s:sd room:0.8 roomsize:4 ]",
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,24 +183,40 @@ global effects use the same chain for all events of the same orbit:
|
||||||
|
|
||||||
<JsDoc client:idle name="orbit" h={0} />
|
<JsDoc client:idle name="orbit" h={0} />
|
||||||
|
|
||||||
## delay
|
## Delay
|
||||||
|
|
||||||
|
### delay
|
||||||
|
|
||||||
<JsDoc client:idle name="delay" h={0} />
|
<JsDoc client:idle name="delay" h={0} />
|
||||||
|
|
||||||
## delaytime
|
### delaytime
|
||||||
|
|
||||||
<JsDoc client:idle name="delaytime" h={0} />
|
<JsDoc client:idle name="delaytime" h={0} />
|
||||||
|
|
||||||
## delayfeedback
|
### delayfeedback
|
||||||
|
|
||||||
<JsDoc client:idle name="delayfeedback" h={0} />
|
<JsDoc client:idle name="delayfeedback" h={0} />
|
||||||
|
|
||||||
## room
|
## Reverb
|
||||||
|
|
||||||
|
### room
|
||||||
|
|
||||||
<JsDoc client:idle name="room" h={0} />
|
<JsDoc client:idle name="room" h={0} />
|
||||||
|
|
||||||
## roomsize
|
### roomsize
|
||||||
|
|
||||||
<JsDoc client:idle name="roomsize" h={0} />
|
<JsDoc client:idle name="roomsize" h={0} />
|
||||||
|
|
||||||
|
### roomfade
|
||||||
|
|
||||||
|
<JsDoc client:idle name="roomfade" h={0} />
|
||||||
|
|
||||||
|
### roomlp
|
||||||
|
|
||||||
|
<JsDoc client:idle name="roomlp" h={0} />
|
||||||
|
|
||||||
|
### roomdim
|
||||||
|
|
||||||
|
<JsDoc client:idle name="roomdim" h={0} />
|
||||||
|
|
||||||
Next, we'll look at strudel's support for [Csound](/learn/csound).
|
Next, we'll look at strudel's support for [Csound](/learn/csound).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue