fully implemented

This commit is contained in:
Jade (Rose) Rowland 2025-07-08 00:26:15 -04:00
parent d9e44dcda6
commit ce5f425142
7 changed files with 227 additions and 306 deletions

View file

@ -448,12 +448,13 @@ export const { coarse } = registerControl('coarse');
* modulate the amplitude of a sound with a continuous waveform
*
* @name am
* @synonym tremolo
* @param {number | Pattern} speed modulation speed in HZ
* @example
* s("triangle").am("2").amshape("<tri saw ramp square>").amdepth(.5)
*
*/
export const { am, } = registerControl(['am', 'amdepth', 'amskew', 'amphase'],);
export const { am, tremolo } = registerControl(['am', 'amdepth', 'amskew', 'amphase'], 'tremolo');
/**
* modulate the amplitude of a sound with a continuous waveform
@ -461,7 +462,7 @@ export const { am, } = registerControl(['am', 'amdepth', 'amskew', 'amphase'],);
* @name amsync
* @param {number | Pattern} cycles modulation speed in cycles
* @example
* s("triangle").am("2").amshape("<tri saw ramp square>").amdepth(.5)
* s("supersaw").amsync(1/4).amskew("<0 .5 1>").amdepth(2)
*
*/
export const { amsync } = registerControl(['amsync', 'amdepth', 'amskew', 'amphase']);
@ -482,7 +483,7 @@ export const { amdepth } = registerControl('amdepth');
* @name amskew
* @param {number | Pattern} amount between 0 & 1, the shape of the waveform
* @example
* note("{f a c e}%16").am(4).amskew("<.5 0 1>")
* note("{f a c e}%16").am(5).amskew(.5).amdepth("<1 0.5 2>").att(.01).rel(.03)
*
*/
export const { amskew } = registerControl('amskew');
@ -493,7 +494,7 @@ export const { amskew } = registerControl('amskew');
* @name amphase
* @param {number | Pattern} offset the offset in cycles of the modulation
* @example
* note("{f a c e}%16").am(4).amphase("<0 .25 .66>")
* note("{f a c e}%16").s("sawtooth").am(4).amphase("<0 .25 .66>")
*
*/
export const { amphase } = registerControl('amphase');
@ -517,6 +518,30 @@ export const { amshape } = registerControl('amshape');
* note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>")
*
*/
// TODO: SUPRADOUGH implement post orbit "pump" sidechain effect
// /**
// * modulate the amplitude of an orbit to create a "sidechain" like effect
// *
// * @name pump
// * @param {number | Pattern} speed modulation speed in cycles
// * @example
// * note("{f g c d}%16").s("sawtooth").pump(".25:.75")
// *
// */
// export const { pump } = registerControl(['pump', 'pumpdepth']);
// /**
// * modulate the amplitude of an orbit to create a "sidechain" like effect
// *
// * @name pumpdepth
// * @param {number | Pattern} depth depth of modulation from 0 to 1
// * @example
// * note("{f g c d}%16").s("sawtooth").pump(".25").depth("<.25 .5 .75 1>")
// *
// */
// export const { pumpdepth } = registerControl('pumpdepth');
export const { drive } = registerControl('drive');
/**

View file

@ -38,16 +38,13 @@ export class Cyclist {
const end = begin + eventLength;
this.cycle = begin + secondsSinceLastTick * this.cps;
//account for latency and tick duration when using cycle calculations for audio downstream
const cycle_gap = (this.latency - duration) * this.cps;
const haps = this.pattern.queryArc(begin, end, { _cps: this.cps });
haps.forEach((hap) => {
if (hap.hasOnset()) {
let targetTime = (hap.whole.begin - this.num_cycles_at_cps_change) / this.cps;
targetTime = targetTime + this.latency + tickdeadline + time - num_seconds_since_cps_change;
const duration = hap.duration / this.cps;
onTrigger?.(hap, tickdeadline, duration, this.cps, targetTime, this.cycle - cycle_gap);
onTrigger?.(hap, tickdeadline, duration, this.cps, targetTime);
}
});
this.time_at_last_tick_message = time;
@ -119,4 +116,4 @@ export class Cyclist {
const onsets = haps.filter((h) => h.hasOnset());
console.log(`${begin.toFixed(4)} - ${end.toFixed(4)} ${Array(onsets.length).fill('I').join('')}`);
}
}
}

View file

@ -244,16 +244,16 @@ export function repl({
export const getTrigger =
({ getTime, defaultOutput }) =>
async (hap, deadline, duration, cps, t, cycle = 0) => {
async (hap, deadline, duration, cps, t) => {
// ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger)
// TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004
try {
if (!hap.context.onTrigger || !hap.context.dominantTrigger) {
await defaultOutput(hap, deadline, duration, cps, t, cycle);
await defaultOutput(hap, deadline, duration, cps, t);
}
if (hap.context.onTrigger) {
// call signature of output / onTrigger is different...
await hap.context.onTrigger(hap, getTime(), cps, t, cycle);
await hap.context.onTrigger(hap, getTime(), cps, t);
}
} catch (err) {
logger(`[cyclist] error: ${err.message}`, 'error');