rename controls

This commit is contained in:
Jade (Rose) Rowland
2025-09-28 09:19:39 -04:00
parent 91eb50f1c1
commit 23d4bfa9d9
3 changed files with 144 additions and 108 deletions
+88 -74
View File
@@ -90,193 +90,191 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound');
/**
* Position in the wavetable of the wavetable oscillator
*
* @name wtPos
* @name wt
* @param {number | Pattern} position Position in the wavetable from 0 to 1
* @synonyms wavetablePosition
* @example
* s("squelch").bank("wt_digital").seg(8).note("F1").wtPos("0 0.25 0.5 0.75 1")
* s("squelch").bank("wt_digital").seg(8).note("F1").wt("0 0.25 0.5 0.75 1")
*/
export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetablePosition');
export const { wt, wavetablePosition } = registerControl('wt', 'wavetablePosition');
/**
* Amount of envelope applied wavetable oscillator's position envelope
*
* @name wtenv
* @param {number | Pattern} amount between 0 and 1
*/
export const { wtenv } = registerControl('wtenv');
/**
* Attack time of the wavetable oscillator's position envelope
*
* @name wtPosAttack
* @synonyms wtPosAtt
* @name wtattack
* @synonyms wtatt
* @param {number | Pattern} time attack time in seconds
*/
export const { wtPosAttack, wtPosAtt } = registerControl('wtPosAttack', 'wtPosAtt');
export const { wtattack, wtatt } = registerControl('wtattack', 'wtatt');
/**
* Decay time of the wavetable oscillator's position envelope
*
* @name wtPosDecay
* @synonyms wtPosDec
* @name wtdecay
* @synonyms wtdec
* @param {number | Pattern} time decay time in seconds
*/
export const { wtPosDecay, wtPosDec } = registerControl('wtPosDecay', 'wtPosDec');
export const { wtdecay, wtdec } = registerControl('wtdecay', 'wtdec');
/**
* Sustain time of the wavetable oscillator's position envelope
*
* @name wtPosAttack
* @synonyms wtPosSus
* @name wtsustain
* @synonyms wtsus
* @param {number | Pattern} gain sustain level (0 to 1)
*/
export const { wtPosSustain, wtPosSus } = registerControl('wtPosSustain', 'wtPosSus');
export const { wtsustain, wtsus } = registerControl('wtsustain', 'wtsus');
/**
* Release time of the wavetable oscillator's position envelope
*
* @name wtPosRelease
* @synonyms wtPosRel
* @name wtrelease
* @synonyms wtrel
* @param {number | Pattern} time release time in seconds
*/
export const { wtPosRelease, wtPosRel } = registerControl('wtPosRelease', 'wtPosRel');
export const { wtrelease, wtrel } = registerControl('wtrelease', 'wtrel');
/**
* Rate of the LFO for the wavetable oscillator's position
*
* @name wtPosRate
* @name wtrate
* @param {number | Pattern} rate rate in hertz
*/
export const { wtPosRate } = registerControl('wtPosRate');
export const { wtrate } = registerControl('wtrate');
/**
* cycle synced rate of the LFO for the wavetable oscillator's position
*
* @name wtsync
* @param {number | Pattern} rate rate in cycles
*/
export const { wtsync } = registerControl('wtsync');
/**
* Depth of the LFO for the wavetable oscillator's position
*
* @name wtPosDepth
* @name wtdepth
* @param {number | Pattern} depth depth of modulation
*/
export const { wtPosDepth } = registerControl('wtPosDepth');
/**
* Whether to sync the LFO for the wavetable oscillator's position
*
* @name wtPosSynced
* @param {number | Pattern} synced Whether to sync the lfo to CPM. > 0.5 will be synced
*/
export const { wtPosSynced } = registerControl('wtPosSynced');
export const { wtdepth } = registerControl('wtdepth');
/**
* Shape of the LFO for the wavetable oscillator's position
*
* @name wtPosShape
* @name wtshape
* @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..)
*/
export const { wtPosShape } = registerControl('wtPosShape');
export const { wtshape } = registerControl('wtshape');
/**
* DC offset of the LFO for the wavetable oscillator's position
*
* @name wtPosDCOffset
* @name wtdc
* @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar
*/
export const { wtPosDCOffset } = registerControl('wtPosDCOffset');
export const { wtdc } = registerControl('wtdc');
/**
* Skew of the LFO for the wavetable oscillator's position
*
* @name wtPosSkew
* @name wtskew
* @param {number | Pattern} skew How much to bend the LFO shape
*/
export const { wtPosSkew } = registerControl('wtPosSkew');
export const { wtskew } = registerControl('wtskew');
/**
* Amount of warp (alteration of the waveform) to apply to the wavetable oscillator
*
* @name wtWarp
* @name warp
* @param {number | Pattern} amount Warp of the wavetable from 0 to 1
* @synonyms wavetableWarp
* @example
* s("basique").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1")
* .wtWarpMode("spin")
* s("basique").bank("wt_digital").seg(8).note("F1").warp("0 0.25 0.5 0.75 1")
* .warpmode("spin")
*/
export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp');
export const { warp, wavetableWarp } = registerControl('warp', 'wavetableWarp');
/**
* Attack time of the wavetable oscillator's warp envelope
*
* @name wtWarpAttack
* @synonyms wtWarpAtt
* @name warpattack
* @synonyms warpatt
* @param {number | Pattern} time attack time in seconds
*/
export const { wtWarpAttack, wtWarpAtt } = registerControl('wtWarpAttack', 'wtWarpAtt');
export const { warpattack, warpatt } = registerControl('warpattack', 'warpatt');
/**
* Decay time of the wavetable oscillator's warp envelope
*
* @name wtWarpDecay
* @synonyms wtWarpDec
* @name warpdecay
* @synonyms warpdec
* @param {number | Pattern} time decay time in seconds
*/
export const { wtWarpDecay, wtWarpDec } = registerControl('wtWarpDecay', 'wtWarpDec');
export const { warpdecay, warpdec } = registerControl('warpdecay', 'warpdec');
/**
* Sustain time of the wavetable oscillator's warp envelope
*
* @name wtWarpAttack
* @synonyms wtWarpSus
* @name warpsustain
* @synonyms warpsus
* @param {number | Pattern} gain sustain level (0 to 1)
*/
export const { wtWarpSustain, wtWarpSus } = registerControl('wtWarpSustain', 'wtWarpSus');
export const { warpsustain, warpsus } = registerControl('warpsustain', 'warpsus');
/**
* Release time of the wavetable oscillator's warp envelope
*
* @name wtWarpRelease
* @synonyms wtWarpRel
* @name warprelease
* @synonyms warprel
* @param {number | Pattern} time release time in seconds
*/
export const { wtWarpRelease, wtWarpRel } = registerControl('wtWarpRelease', 'wtWarpRel');
export const { warprelease, warprel } = registerControl('warprelease', 'warprel');
/**
* Rate of the LFO for the wavetable oscillator's warp
*
* @name wtWarpRate
* @name warprate
* @param {number | Pattern} rate rate in hertz
*/
export const { wtWarpRate } = registerControl('wtWarpRate');
export const { warprate } = registerControl('warprate');
/**
* Depth of the LFO for the wavetable oscillator's warp
*
* @name wtWarpDepth
* @name warpdepth
* @param {number | Pattern} depth depth of modulation
*/
export const { wtWarpDepth } = registerControl('wtWarpDepth');
/**
* Whether to sync the LFO for the wavetable oscillator's warp
*
* @name wtWarpSynced
* @param {number | Pattern} synced Whether to sync the lfo to CPM. > 0.5 will be synced
*/
export const { wtWarpSynced } = registerControl('wtWarpSynced');
export const { warpdepth } = registerControl('warpdepth');
/**
* Shape of the LFO for the wavetable oscillator's warp
*
* @name wtWarpShape
* @name warpshape
* @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..)
*/
export const { wtWarpShape } = registerControl('wtWarpShape');
export const { warpshape } = registerControl('warpshape');
/**
* DC offset of the LFO for the wavetable oscillator's warp
*
* @name wtWarpDCOffset
* @name warpdc
* @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar
*/
export const { wtWarpDCOffset } = registerControl('wtWarpDCOffset');
export const { warpdc } = registerControl('warpdc');
/**
* Skew of the LFO for the wavetable oscillator's warp
*
* @name wtWarpSkew
* @name warpskew
* @param {number | Pattern} skew How much to bend the LFO shape
*/
export const { wtWarpSkew } = registerControl('wtWarpSkew');
export const { warpskew } = registerControl('warpskew');
/**
* Type of warp (alteration of the waveform) to apply to the wavetable oscillator.
@@ -284,27 +282,43 @@ export const { wtWarpSkew } = registerControl('wtWarpSkew');
* The current options are: none, asym, bendp, bendm, bendmp, sync, quant, fold, pwm, orbit,
* spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip
*
* @name wtWarpMode
* @name warpmode
* @param {number | string | Pattern} mode Warp mode
* @synonyms wavetableWarpMode
* @example
* s("morgana").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1")
* .wtWarpMode("<asym bendp spin logistic sync wormhole brownian>*2")
* s("morgana").bank("wt_digital").seg(8).note("F1").warp("0 0.25 0.5 0.75 1")
* .warpmode("<asym bendp spin logistic sync wormhole brownian>*2")
*
*/
export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', 'wavetableWarpMode');
export const { warpmode, wavetableWarpMode } = registerControl('warpmode', 'wavetableWarpMode');
/**
* Amount of randomness of the initial phase of the wavetable oscillator.
*
* @name wtPhaseRand
* @name wtphaserand
* @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random)
* @synonyms wavetablePhaseRand
* @example
* s("basique").bank("wt_digital").seg(16).wtPhaseRand("<0 1>")
* s("basique").bank("wt_digital").seg(16).wtphaserand("<0 1>")
*
*/
export const { wtPhaseRand, wavetablePhaseRand } = registerControl('wtPhaseRand', 'wavetablePhaseRand');
export const { wtphaserand, wavetablePhaseRand } = registerControl('wtphaserand', 'wavetablePhaseRand');
/**
* Amount of envelope applied wavetable oscillator's position envelope
*
* @name warpenv
* @param {number | Pattern} amount between 0 and 1
*/
export const { warpenv } = registerControl('warpenv');
/**
* cycle synced rate of the LFO for the wavetable warp position
*
* @name warpsync
* @param {number | Pattern} rate rate in cycles
*/
export const { warpsync } = registerControl('warpsync');
/**
* Define a custom webaudio node to use as a sound source.
+1 -1
View File
@@ -555,7 +555,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
audioNodes.forEach((n) => n?.disconnect());
activeSoundSources.delete(chainID);
};
const soundHandle = await onTrigger(t, value, onEnded);
const soundHandle = await onTrigger(t, value, onEnded, cps);
if (soundHandle) {
sourceNode = soundHandle.node;
+55 -33
View File
@@ -14,7 +14,7 @@ import {
import { logger } from './logger.mjs';
const WT_MAX_MIP_LEVELS = 6;
export const WarpMode = Object.freeze({
export const Warpmode = Object.freeze({
NONE: 0,
ASYM: 1,
MIRROR: 2,
@@ -177,11 +177,17 @@ const _processTables = (json, baseUrl, frameLen, options = {}) => {
};
export function registerWaveTable(key, tables, params) {
registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, tables, params?.frameLen ?? 2048), {
type: 'wavetable',
tables,
...params,
});
registerSound(
key,
(t, hapValue, onended, cps) => {
return onTriggerSynth(t, hapValue, onended, tables, cps, params?.frameLen ?? 2048);
},
{
type: 'wavetable',
tables,
...params,
},
);
}
/**
@@ -214,13 +220,13 @@ export const tables = async (url, frameLen, json, options = {}) => {
});
};
export async function onTriggerSynth(t, value, onended, tables, frameLen) {
const { s, n = 0, duration } = value;
export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) {
const { s, n = 0, duration, wtenv } = value;
const ac = getAudioContext();
const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]);
let { wtWarpMode } = value;
if (typeof wtWarpMode === 'string') {
wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE;
let { warpmode } = value;
if (typeof warpmode === 'string') {
warpmode = Warpmode[warpmode.toUpperCase()] ?? Warpmode.NONE;
}
const frequency = getFrequencyFromValue(value);
const { url, label } = getCommonSampleInfo(value, tables);
@@ -236,12 +242,12 @@ export async function onTriggerSynth(t, value, onended, tables, frameLen) {
end: envEnd,
frequency,
detune: value.detune,
position: value.wtPos,
warp: value.wtWarp,
warpMode: wtWarpMode,
position: value.wt,
warp: value.warp,
warpMode: warpmode,
voices: value.unison,
spread: value.spread,
phaserand: value.wtPhaseRand,
phaserand: (value.wtphaserand ?? value.unison > 1) ? 1 : 0,
},
{ outputChannelCount: [2] },
);
@@ -250,36 +256,52 @@ export async function onTriggerSynth(t, value, onended, tables, frameLen) {
logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight');
return;
}
const posADSRParams = [value.wtPosAttack, value.wtPosDecay, value.wtPosSustain, value.wtPosRelease];
const warpADSRParams = [value.wtPosAttack, value.wtPosDecay, value.wtPosSustain, value.wtPosRelease];
const posADSRParams = [value.wtattack, value.wtdecay, value.wtsustain, value.wtrelease];
const warpADSRParams = [value.warpattack, value.warpdecay, value.warpsustain, value.warprelease];
const wtParams = source.parameters;
const positionParam = wtParams.get('position');
const warpParam = wtParams.get('warp');
let posLFO;
if (posADSRParams.some((p) => p !== undefined)) {
const [pAttack, pDecay, pSustain, pRelease] = getADSRValues(posADSRParams);
getParamADSR(positionParam, pAttack, pDecay, pSustain, pRelease, 0, 1, t, holdEnd, 'linear');
} else {
if ([wtenv, ...posADSRParams].some((p) => p !== undefined)) {
const [pAttack, pDecay, pSustain, pRelease] = getADSRValues(posADSRParams, 'linear', [0, 0.5, 0, 0.1]);
const min = value.wt ?? 0;
const max = (wtenv ?? 0.5) + min;
getParamADSR(positionParam, pAttack, pDecay, pSustain, pRelease, min, max, t, holdEnd, 'linear');
}
let wtrate = value.wtrate;
if (value.wtsync != null) {
wtrate = wtrate = cps * value.wtsync;
}
if ([wtrate, value.wtdepth, value.wtshape, value.wtskew, value.wtdc].some((p) => p != null)) {
const posLFO = getLfo(ac, t, endWithRelease, {
frequency: value.wtPosRate,
depth: value.wtPosDepth,
shape: value.wtPosShape,
skew: value.wtPosSkew,
dcoffset: value.wtPosDCOffset ?? 0,
frequency: wtrate,
depth: value.wtdepth ?? 0.5,
shape: value.wtshape,
skew: value.wtskew,
dcoffset: value.wtdc ?? 0,
});
posLFO.connect(positionParam);
}
let warpLFO;
if (posADSRParams.some((p) => p !== undefined)) {
const [wAttack, wDecay, wSustain, wRelease] = getADSRValues(warpADSRParams);
getParamADSR(warpParam, wAttack, wDecay, wSustain, wRelease, 0, 1, t, holdEnd, 'linear');
} else {
const min = value.warp ?? 0;
const max = (value.warpenv ?? 0.5) + min;
getParamADSR(warpParam, wAttack, wDecay, wSustain, wRelease, min, max, t, holdEnd, 'linear', [0, 0.5, 0, 0.1]);
}
let warprate = value.warprate;
if (value.warpsync != null) {
console.info(value.warpsync);
warprate = warprate = cps * value.warpsync;
}
if ([warprate, value.warpdepth, value.warpshape, value.warpskew, value.warpdc].some((p) => p != null)) {
const warpLFO = getLfo(ac, t, endWithRelease, {
frequency: value.wtWarpRate,
depth: value.wtWarpDepth,
shape: value.wtWarpShape,
skew: value.wtWarpSkew,
dcoffset: value.wtWarpDCOffset ?? 0,
frequency: warprate,
depth: value.warpdepth ?? 0.5,
shape: value.warpshape,
skew: value.warpskew,
dcoffset: value.warpdc ?? 0,
});
warpLFO.connect(warpParam);
}