use sample as an impulse response for the reverb
This commit is contained in:
parent
fd18508266
commit
755e24315e
3 changed files with 1221 additions and 1205 deletions
|
|
@ -4,8 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Pattern, register, sequence} from './pattern.mjs';
|
import { Pattern, register, sequence } from './pattern.mjs';
|
||||||
import {zipWith} from './util.mjs';
|
import { zipWith } from './util.mjs';
|
||||||
|
|
||||||
const controls = {};
|
const controls = {};
|
||||||
const generic_params = [
|
const generic_params = [
|
||||||
|
|
@ -980,6 +980,7 @@ const generic_params = [
|
||||||
* s("bd sd").room(.8).roomsize("<0 1 2 4 8>")
|
* s("bd sd").room(.8).roomsize("<0 1 2 4 8>")
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 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?
|
||||||
|
|
@ -995,10 +996,11 @@ const generic_params = [
|
||||||
* @name iresponse
|
* @name iresponse
|
||||||
* @param {string | Pattern} Sets the impulse response
|
* @param {string | Pattern} Sets the impulse response
|
||||||
* @example
|
* @example
|
||||||
* s("bd sd").room(.8).ir("<ir0 ir1>")
|
* s("bd sd").room(.8).ir("<shaker_large:0 shaker_large:2>")
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
[['ir', 'i'], 'iresponse'],
|
[['ir', 'i'], 'iresponse'],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wave shaping distortion. CAUTION: it might get loud
|
* Wave shaping distortion. CAUTION: it might get loud
|
||||||
*
|
*
|
||||||
|
|
@ -1188,11 +1190,11 @@ controls.createParam = function (names) {
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
return {[name]: xs};
|
return { [name]: xs };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
withVal = (x) => ({[name]: x});
|
withVal = (x) => ({ [name]: x });
|
||||||
}
|
}
|
||||||
|
|
||||||
const func = (...pats) => sequence(...pats).withValue(withVal);
|
const func = (...pats) => sequence(...pats).withValue(withVal);
|
||||||
|
|
@ -1218,17 +1220,17 @@ generic_params.forEach(([names, ...aliases]) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.createParams = (...names) =>
|
controls.createParams = (...names) =>
|
||||||
names.reduce((acc, name) => Object.assign(acc, {[name]: controls.createParam(name)}), {});
|
names.reduce((acc, name) => Object.assign(acc, { [name]: controls.createParam(name) }), {});
|
||||||
|
|
||||||
controls.adsr = register('adsr', (adsr, pat) => {
|
controls.adsr = register('adsr', (adsr, pat) => {
|
||||||
adsr = !Array.isArray(adsr) ? [adsr] : adsr;
|
adsr = !Array.isArray(adsr) ? [adsr] : adsr;
|
||||||
const [attack, decay, sustain, release] = adsr;
|
const [attack, decay, sustain, release] = adsr;
|
||||||
return pat.set({attack, decay, sustain, release});
|
return pat.set({ attack, decay, sustain, release });
|
||||||
});
|
});
|
||||||
controls.ds = register('ds', (ds, pat) => {
|
controls.ds = register('ds', (ds, pat) => {
|
||||||
ds = !Array.isArray(ds) ? [ds] : ds;
|
ds = !Array.isArray(ds) ? [ds] : ds;
|
||||||
const [decay, sustain] = ds;
|
const [decay, sustain] = ds;
|
||||||
return pat.set({decay, sustain});
|
return pat.set({ decay, sustain });
|
||||||
});
|
});
|
||||||
|
|
||||||
export default controls;
|
export default controls;
|
||||||
|
|
|
||||||
|
|
@ -7,22 +7,31 @@ if (typeof AudioContext !== 'undefined') {
|
||||||
return impulse;
|
return impulse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AudioContext.prototype.adjustLength = function (duration, buffer) {
|
||||||
|
const newLength = buffer.sampleRate * duration;
|
||||||
|
const newBuffer = this.createBuffer(buffer.numberOfChannels, buffer.length, buffer.sampleRate);
|
||||||
|
for (let channel = 0; channel < buffer.numberOfChannels; channel++) {
|
||||||
|
let oldData = buffer.getChannelData(channel);
|
||||||
|
let newData = newBuffer.getChannelData(channel);
|
||||||
|
|
||||||
|
for (let i = 0; i < newLength; i++) {
|
||||||
|
newData[i] = oldData[i] || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
AudioContext.prototype.createReverb = function (duration, buffer) {
|
AudioContext.prototype.createReverb = function (duration, buffer) {
|
||||||
const convolver = this.createConvolver();
|
const convolver = this.createConvolver();
|
||||||
convolver.setDuration = (d, i) => {
|
convolver.setDuration = (dur, imp) => {
|
||||||
convolver.buffer = i !== undefined ? buffer : this.impulseResponse(d);
|
convolver.buffer = imp ? this.adjustLength(dur, imp) : this.impulseResponse(dur);
|
||||||
convolver.duration = d;
|
|
||||||
return convolver;
|
return convolver;
|
||||||
};
|
};
|
||||||
convolver.setIR = (i) => {
|
convolver.setIR = (dur, imp) => {
|
||||||
convolver.buffer = i;
|
convolver.buffer = imp ? this.adjustLength(dur, imp) : this.impulseResponse(dur);
|
||||||
return convolver;
|
return convolver;
|
||||||
};
|
};
|
||||||
if (buffer !== undefined) {
|
convolver.setDuration(duration, buffer);
|
||||||
convolver.setIR(buffer);
|
|
||||||
} else {
|
|
||||||
convolver.setDuration(duration);
|
|
||||||
}
|
|
||||||
return convolver;
|
return convolver;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,11 +122,11 @@ function getReverb(orbit, duration = 2, ir) {
|
||||||
reverbs[orbit] = reverb;
|
reverbs[orbit] = reverb;
|
||||||
}
|
}
|
||||||
if (reverbs[orbit].duration !== duration) {
|
if (reverbs[orbit].duration !== duration) {
|
||||||
reverbs[orbit] = reverbs[orbit].setDuration(duration);
|
reverbs[orbit] = reverbs[orbit].setDuration(duration, ir);
|
||||||
reverbs[orbit].duration = duration;
|
reverbs[orbit].duration = duration;
|
||||||
}
|
}
|
||||||
if (reverbs[orbit].ir !== ir) {
|
if (reverbs[orbit].ir !== ir) {
|
||||||
reverbs[orbit] = reverbs[orbit].setIR(ir);
|
reverbs[orbit] = reverbs[orbit].setIR(duration, ir);
|
||||||
reverbs[orbit].ir = ir;
|
reverbs[orbit].ir = ir;
|
||||||
}
|
}
|
||||||
return reverbs[orbit];
|
return reverbs[orbit];
|
||||||
|
|
@ -368,9 +368,14 @@ export const superdough = async (value, deadline, hapDuration) => {
|
||||||
}
|
}
|
||||||
// reverb
|
// reverb
|
||||||
let buffer;
|
let buffer;
|
||||||
|
let url;
|
||||||
if (ir !== undefined) {
|
if (ir !== undefined) {
|
||||||
let sample = getSound(ir);
|
let sample = getSound(ir);
|
||||||
let url = sample.data.samples[i % sample.data.samples.length];
|
if (Array.isArray(sample)) {
|
||||||
|
url = sample.data.samples[i % sample.data.samples.length];
|
||||||
|
} else if (typeof sample === 'object') {
|
||||||
|
url = Object.values(sample.data.samples)[i & Object.values(sample.data.samples).length];
|
||||||
|
}
|
||||||
buffer = await loadBuffer(url, ac, ir, 0);
|
buffer = await loadBuffer(url, ac, ir, 0);
|
||||||
}
|
}
|
||||||
let reverbSend;
|
let reverbSend;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue