diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 12bcc3565..a0f5d10e3 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -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("").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("").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'); /** diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 43e1f508e..6864301db 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -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('')}`); } -} \ No newline at end of file +} diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 5e696c85f..aeaa6418e 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -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'); diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 79c1ff117..ccb69cceb 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -45,8 +45,6 @@ export function setGainCurve(newGainCurveFunc) { gainCurveFunc = newGainCurveFunc; } - - function aliasBankMap(aliasMap) { // Make all bank keys lower case for case insensitivity for (const key in aliasMap) { @@ -328,22 +326,26 @@ function getDelay(orbit, delaytime, delayfeedback, t, channels) { } export function getLfo(audioContext, begin, end, properties = {}) { + const { dcoffset = -0.5, depth = 1 } = properties; return getWorklet(audioContext, 'lfo-processor', { frequency: 1, - depth: 1, + depth, skew: 0, phaseoffset: 0, time: begin, begin, end, shape: 1, - dcoffset: -0.5, + dcoffset, + min: dcoffset - depth * 0.5, + max: dcoffset + depth * 0.5, + curve: 1, ...properties, }); } export function getSyncedLfo(audioContext, time, end, cps, cycle, properties = {}) { - const frequency = cycle/cps + const frequency = cycle / cps; return getWorklet(audioContext, 'lfo-processor', { frequency, @@ -499,10 +501,11 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { // destructure let { am, + amsync, amdepth = 1, - amskew = 0.5, + amskew = 1, amphase = 0, - amshape = 1, + amshape = 0, s = getDefaultValue('s'), bank, source, @@ -512,6 +515,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { // filters fanchor = getDefaultValue('fanchor'), drive = 0.69, + release = 0, // low pass cutoff, lpenv, @@ -587,8 +591,11 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { distortvol = applyGainCurve(distortvol); delay = applyGainCurve(delay); velocity = applyGainCurve(velocity); + amdepth = applyGainCurve(amdepth); gain *= velocity; // velocity currently only multiplies with gain. it might do other things in the future + const end = t + hapDuration; + const endWithRelease = end + release; const chainID = Math.round(Math.random() * 1000000); // oldest audio nodes will be destroyed if maximum polyphony is exceeded @@ -663,7 +670,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { lprelease, lpenv, t, - t + hapDuration, + end, fanchor, ftype, drive, @@ -687,7 +694,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { hprelease, hpenv, t, - t + hapDuration, + end, fanchor, ); chain.push(hp()); @@ -698,20 +705,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { if (bandf !== undefined) { let bp = () => - createFilter( - ac, - 'bandpass', - bandf, - bandq, - bpattack, - bpdecay, - bpsustain, - bprelease, - bpenv, - t, - t + hapDuration, - fanchor, - ); + createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, bpenv, t, end, fanchor); chain.push(bp()); if (ftype === '24db') { chain.push(bp()); @@ -727,45 +721,32 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { coarse !== undefined && chain.push(getWorklet(ac, 'coarse-processor', { coarse })); crush !== undefined && chain.push(getWorklet(ac, 'crush-processor', { crush })); shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol })); - // distort !== undefined && chain.push(getWorklet(ac, 'distort-processor', { distort, postgain: distortvol })); - // am !== undefined && - // chain.push( - // getWorklet(ac, 'am-processor', { - // speed: am, - // begin: t, - // depth: amdepth, - // skew: amskew, - // phaseoffset: amphase, - // // shape: amshape, - - // cps, - // cycle, - // }), - // ); + distort !== undefined && chain.push(getWorklet(ac, 'distort-processor', { distort, postgain: distortvol })); + if (amsync != null) { + am = cps / amsync; + } if (am !== undefined) { - const amGain = new GainNode(ac, { gain: 1 }); - const frequency = cps / am - const phaseoffset = cycleToSeconds(amphase, cps) + // Allow clipping of modulator for more dynamic possiblities, and to prevent speaker overload + // EX: a triangle waveform will clip like this /-\ when the depth is above 1 + const gain = Math.max(1 - amdepth, 0); + const amGain = new GainNode(ac, { gain }); - - const time = cycle / cps - - // console.info(cycle, time, frequency) - - - - const lfo = getLfo(ac, t, t + hapDuration, { - skew: amskew, - frequency, + const time = cycle / cps; + const lfo = getLfo(ac, t, endWithRelease, { + skew: amskew, + frequency: am, depth: amdepth, time, - // dcoffset: 0, - shape: amshape, - phaseoffset - }) - lfo.connect(amGain.gain) - chain.push(amGain) + dcoffset: 0, + shape: amshape, + phaseoffset: amphase, + min: 0, + max: 1, + curve: 1.5, + }); + lfo.connect(amGain.gain); + chain.push(amGain); } compressorThreshold !== undefined && @@ -781,7 +762,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle) => { } // phaser if (phaser !== undefined && phaserdepth > 0) { - const phaserFX = getPhaser(t, t + hapDuration, phaser, phaserdepth, phasercenter, phasersweep); + const phaserFX = getPhaser(t, endWithRelease, phaser, phaserdepth, phasercenter, phasersweep); chain.push(phaserFX); } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 366be8a5e..466be558a 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -93,7 +93,10 @@ class LFOProcessor extends AudioWorkletProcessor { { name: 'depth', defaultValue: 1 }, { name: 'phaseoffset', defaultValue: 0 }, { name: 'shape', defaultValue: 0 }, + { name: 'curve', defaultValue: 1 }, { name: 'dcoffset', defaultValue: 0 }, + { name: 'min', defaultValue: 0 }, + { name: 'max', defaultValue: 1 }, ]; } @@ -110,7 +113,7 @@ class LFOProcessor extends AudioWorkletProcessor { } process(inputs, outputs, parameters) { - const begin = parameters['begin'][0] + const begin = parameters['begin'][0]; // eslint-disable-next-line no-undef if (currentTime >= parameters.end[0]) { return false; @@ -126,6 +129,9 @@ class LFOProcessor extends AudioWorkletProcessor { const depth = parameters['depth'][0]; const skew = parameters['skew'][0]; const phaseoffset = parameters['phaseoffset'][0]; + const min = parameters['min'][0]; + const max = parameters['max'][0]; + const curve = parameters['curve'][0]; const dcoffset = parameters['dcoffset'][0]; const shape = waveShapeNames[parameters['shape'][0]]; @@ -140,7 +146,7 @@ class LFOProcessor extends AudioWorkletProcessor { for (let n = 0; n < blockSize; n++) { for (let i = 0; i < output.length; i++) { const modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth; - output[i][n] = modval; + output[i][n] = clamp(Math.pow(modval, curve), min, max); } this.incrementPhase(dt); } @@ -164,8 +170,6 @@ class CoarseProcessor extends AudioWorkletProcessor { const input = inputs[0]; const output = outputs[0]; - - const hasInput = !(input[0] === undefined); if (this.started && !hasInput) { return false; @@ -901,70 +905,3 @@ class ByteBeatProcessor extends AudioWorkletProcessor { } registerProcessor('byte-beat-processor', ByteBeatProcessor); - - -class AMProcessor extends AudioWorkletProcessor { - static get parameterDescriptors() { - return [ - { name: 'begin', defaultValue: 0 }, - { name: 'cps', defaultValue: 0.5 }, - { name: 'speed', defaultValue: 0.5 }, - { name: 'cycle', defaultValue: 0 }, - { name: 'skew', defaultValue: 0.5 }, - { name: 'depth', defaultValue: 1 }, - { name: 'phaseoffset', defaultValue: 0 }, - ]; - } - - constructor() { - super(); - this.phase; - this.started = false; - } - - incrementPhase(dt) { - this.phase += dt; - if (this.phase > 1.0) { - this.phase = this.phase - 1; - } - } - - process(inputs, outputs, parameters) { - const input = inputs[0]; - const output = outputs[0]; - const hasInput = !(input[0] === undefined); - - - if (this.started && !hasInput) { - return false; - } - this.started = hasInput; - if (currentTime <= parameters.begin[0]) { - return true; - } - - const speed = parameters['speed'][0]; - const cps = parameters['cps'][0]; - const cycle = parameters['cycle'][0]; - const depth = parameters['depth'][0]; - const skew = parameters['skew'][0]; - const phaseoffset = parameters['phaseoffset'][0]; - - const frequency = cps / speed - if (this.phase == null) { - const secondsPassed = cycle / cps; - this.phase = _mod(secondsPassed * frequency + phaseoffset, 1); - } - // eslint-disable-next-line no-undef - const dt = frequency / sampleRate; - for (let n = 0; n < blockSize; n++) { - for (let i = 0; i < input.length; i++) { - const modval = clamp(waveshapes.tri(this.phase, skew) * depth + (1 - depth), 0, 1); - output[i][n] = input[i][n] * modval; - } - this.incrementPhase(dt); - } - return true; - } -} -registerProcessor('am-processor', AMProcessor); diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 78441ee55..1e8455b3f 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -17,12 +17,15 @@ const hap2value = (hap) => { // uses more precise, absolute t if available, see https://github.com/tidalcycles/strudel/pull/1004 // TODO: refactor output callbacks to eliminate deadline -export const webaudioOutput = (hap, deadline, hapDuration, cps, t, cycle) => { - - return superdough(hap2value(hap), t, hapDuration, cps, - hap.whole.begin.valueOf() - // cycle -); +export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { + return superdough( + hap2value(hap), + t, + hapDuration, + cps, + hap.whole.begin.valueOf(), + // cycle + ); }; export function webaudioRepl(options = {}) { diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 4ddf79eff..50d4f2095 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -860,70 +860,70 @@ exports[`runs examples > example "amp" example index 0 1`] = ` exports[`runs examples > example "amphase" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | note:f am:4 amphase:0 ]", - "[ 1/16 → 1/8 | note:a am:4 amphase:0 ]", - "[ 1/8 → 3/16 | note:c am:4 amphase:0 ]", - "[ 3/16 → 1/4 | note:e am:4 amphase:0 ]", - "[ 1/4 → 5/16 | note:f am:4 amphase:0 ]", - "[ 5/16 → 3/8 | note:a am:4 amphase:0 ]", - "[ 3/8 → 7/16 | note:c am:4 amphase:0 ]", - "[ 7/16 → 1/2 | note:e am:4 amphase:0 ]", - "[ 1/2 → 9/16 | note:f am:4 amphase:0 ]", - "[ 9/16 → 5/8 | note:a am:4 amphase:0 ]", - "[ 5/8 → 11/16 | note:c am:4 amphase:0 ]", - "[ 11/16 → 3/4 | note:e am:4 amphase:0 ]", - "[ 3/4 → 13/16 | note:f am:4 amphase:0 ]", - "[ 13/16 → 7/8 | note:a am:4 amphase:0 ]", - "[ 7/8 → 15/16 | note:c am:4 amphase:0 ]", - "[ 15/16 → 1/1 | note:e am:4 amphase:0 ]", - "[ 1/1 → 17/16 | note:f am:4 amphase:0.25 ]", - "[ 17/16 → 9/8 | note:a am:4 amphase:0.25 ]", - "[ 9/8 → 19/16 | note:c am:4 amphase:0.25 ]", - "[ 19/16 → 5/4 | note:e am:4 amphase:0.25 ]", - "[ 5/4 → 21/16 | note:f am:4 amphase:0.25 ]", - "[ 21/16 → 11/8 | note:a am:4 amphase:0.25 ]", - "[ 11/8 → 23/16 | note:c am:4 amphase:0.25 ]", - "[ 23/16 → 3/2 | note:e am:4 amphase:0.25 ]", - "[ 3/2 → 25/16 | note:f am:4 amphase:0.25 ]", - "[ 25/16 → 13/8 | note:a am:4 amphase:0.25 ]", - "[ 13/8 → 27/16 | note:c am:4 amphase:0.25 ]", - "[ 27/16 → 7/4 | note:e am:4 amphase:0.25 ]", - "[ 7/4 → 29/16 | note:f am:4 amphase:0.25 ]", - "[ 29/16 → 15/8 | note:a am:4 amphase:0.25 ]", - "[ 15/8 → 31/16 | note:c am:4 amphase:0.25 ]", - "[ 31/16 → 2/1 | note:e am:4 amphase:0.25 ]", - "[ 2/1 → 33/16 | note:f am:4 amphase:0.66 ]", - "[ 33/16 → 17/8 | note:a am:4 amphase:0.66 ]", - "[ 17/8 → 35/16 | note:c am:4 amphase:0.66 ]", - "[ 35/16 → 9/4 | note:e am:4 amphase:0.66 ]", - "[ 9/4 → 37/16 | note:f am:4 amphase:0.66 ]", - "[ 37/16 → 19/8 | note:a am:4 amphase:0.66 ]", - "[ 19/8 → 39/16 | note:c am:4 amphase:0.66 ]", - "[ 39/16 → 5/2 | note:e am:4 amphase:0.66 ]", - "[ 5/2 → 41/16 | note:f am:4 amphase:0.66 ]", - "[ 41/16 → 21/8 | note:a am:4 amphase:0.66 ]", - "[ 21/8 → 43/16 | note:c am:4 amphase:0.66 ]", - "[ 43/16 → 11/4 | note:e am:4 amphase:0.66 ]", - "[ 11/4 → 45/16 | note:f am:4 amphase:0.66 ]", - "[ 45/16 → 23/8 | note:a am:4 amphase:0.66 ]", - "[ 23/8 → 47/16 | note:c am:4 amphase:0.66 ]", - "[ 47/16 → 3/1 | note:e am:4 amphase:0.66 ]", - "[ 3/1 → 49/16 | note:f am:4 amphase:0 ]", - "[ 49/16 → 25/8 | note:a am:4 amphase:0 ]", - "[ 25/8 → 51/16 | note:c am:4 amphase:0 ]", - "[ 51/16 → 13/4 | note:e am:4 amphase:0 ]", - "[ 13/4 → 53/16 | note:f am:4 amphase:0 ]", - "[ 53/16 → 27/8 | note:a am:4 amphase:0 ]", - "[ 27/8 → 55/16 | note:c am:4 amphase:0 ]", - "[ 55/16 → 7/2 | note:e am:4 amphase:0 ]", - "[ 7/2 → 57/16 | note:f am:4 amphase:0 ]", - "[ 57/16 → 29/8 | note:a am:4 amphase:0 ]", - "[ 29/8 → 59/16 | note:c am:4 amphase:0 ]", - "[ 59/16 → 15/4 | note:e am:4 amphase:0 ]", - "[ 15/4 → 61/16 | note:f am:4 amphase:0 ]", - "[ 61/16 → 31/8 | note:a am:4 amphase:0 ]", - "[ 31/8 → 63/16 | note:c am:4 amphase:0 ]", - "[ 63/16 → 4/1 | note:e am:4 amphase:0 ]", + "[ 0/1 → 1/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 1/16 → 1/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 1/8 → 3/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 3/16 → 1/4 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 1/4 → 5/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 5/16 → 3/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 3/8 → 7/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 7/16 → 1/2 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 1/2 → 9/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 9/16 → 5/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 5/8 → 11/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 11/16 → 3/4 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 3/4 → 13/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 13/16 → 7/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 7/8 → 15/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 15/16 → 1/1 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 1/1 → 17/16 | note:f s:sawtooth am:4 amphase:0.25 ]", + "[ 17/16 → 9/8 | note:a s:sawtooth am:4 amphase:0.25 ]", + "[ 9/8 → 19/16 | note:c s:sawtooth am:4 amphase:0.25 ]", + "[ 19/16 → 5/4 | note:e s:sawtooth am:4 amphase:0.25 ]", + "[ 5/4 → 21/16 | note:f s:sawtooth am:4 amphase:0.25 ]", + "[ 21/16 → 11/8 | note:a s:sawtooth am:4 amphase:0.25 ]", + "[ 11/8 → 23/16 | note:c s:sawtooth am:4 amphase:0.25 ]", + "[ 23/16 → 3/2 | note:e s:sawtooth am:4 amphase:0.25 ]", + "[ 3/2 → 25/16 | note:f s:sawtooth am:4 amphase:0.25 ]", + "[ 25/16 → 13/8 | note:a s:sawtooth am:4 amphase:0.25 ]", + "[ 13/8 → 27/16 | note:c s:sawtooth am:4 amphase:0.25 ]", + "[ 27/16 → 7/4 | note:e s:sawtooth am:4 amphase:0.25 ]", + "[ 7/4 → 29/16 | note:f s:sawtooth am:4 amphase:0.25 ]", + "[ 29/16 → 15/8 | note:a s:sawtooth am:4 amphase:0.25 ]", + "[ 15/8 → 31/16 | note:c s:sawtooth am:4 amphase:0.25 ]", + "[ 31/16 → 2/1 | note:e s:sawtooth am:4 amphase:0.25 ]", + "[ 2/1 → 33/16 | note:f s:sawtooth am:4 amphase:0.66 ]", + "[ 33/16 → 17/8 | note:a s:sawtooth am:4 amphase:0.66 ]", + "[ 17/8 → 35/16 | note:c s:sawtooth am:4 amphase:0.66 ]", + "[ 35/16 → 9/4 | note:e s:sawtooth am:4 amphase:0.66 ]", + "[ 9/4 → 37/16 | note:f s:sawtooth am:4 amphase:0.66 ]", + "[ 37/16 → 19/8 | note:a s:sawtooth am:4 amphase:0.66 ]", + "[ 19/8 → 39/16 | note:c s:sawtooth am:4 amphase:0.66 ]", + "[ 39/16 → 5/2 | note:e s:sawtooth am:4 amphase:0.66 ]", + "[ 5/2 → 41/16 | note:f s:sawtooth am:4 amphase:0.66 ]", + "[ 41/16 → 21/8 | note:a s:sawtooth am:4 amphase:0.66 ]", + "[ 21/8 → 43/16 | note:c s:sawtooth am:4 amphase:0.66 ]", + "[ 43/16 → 11/4 | note:e s:sawtooth am:4 amphase:0.66 ]", + "[ 11/4 → 45/16 | note:f s:sawtooth am:4 amphase:0.66 ]", + "[ 45/16 → 23/8 | note:a s:sawtooth am:4 amphase:0.66 ]", + "[ 23/8 → 47/16 | note:c s:sawtooth am:4 amphase:0.66 ]", + "[ 47/16 → 3/1 | note:e s:sawtooth am:4 amphase:0.66 ]", + "[ 3/1 → 49/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 49/16 → 25/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 25/8 → 51/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 51/16 → 13/4 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 13/4 → 53/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 53/16 → 27/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 27/8 → 55/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 55/16 → 7/2 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 7/2 → 57/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 57/16 → 29/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 29/8 → 59/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 59/16 → 15/4 | note:e s:sawtooth am:4 amphase:0 ]", + "[ 15/4 → 61/16 | note:f s:sawtooth am:4 amphase:0 ]", + "[ 61/16 → 31/8 | note:a s:sawtooth am:4 amphase:0 ]", + "[ 31/8 → 63/16 | note:c s:sawtooth am:4 amphase:0 ]", + "[ 63/16 → 4/1 | note:e s:sawtooth am:4 amphase:0 ]", ] `; @@ -998,70 +998,79 @@ exports[`runs examples > example "amshape" example index 0 1`] = ` exports[`runs examples > example "amskew" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | note:f am:4 amskew:0.5 ]", - "[ 1/16 → 1/8 | note:a am:4 amskew:0.5 ]", - "[ 1/8 → 3/16 | note:c am:4 amskew:0.5 ]", - "[ 3/16 → 1/4 | note:e am:4 amskew:0.5 ]", - "[ 1/4 → 5/16 | note:f am:4 amskew:0.5 ]", - "[ 5/16 → 3/8 | note:a am:4 amskew:0.5 ]", - "[ 3/8 → 7/16 | note:c am:4 amskew:0.5 ]", - "[ 7/16 → 1/2 | note:e am:4 amskew:0.5 ]", - "[ 1/2 → 9/16 | note:f am:4 amskew:0.5 ]", - "[ 9/16 → 5/8 | note:a am:4 amskew:0.5 ]", - "[ 5/8 → 11/16 | note:c am:4 amskew:0.5 ]", - "[ 11/16 → 3/4 | note:e am:4 amskew:0.5 ]", - "[ 3/4 → 13/16 | note:f am:4 amskew:0.5 ]", - "[ 13/16 → 7/8 | note:a am:4 amskew:0.5 ]", - "[ 7/8 → 15/16 | note:c am:4 amskew:0.5 ]", - "[ 15/16 → 1/1 | note:e am:4 amskew:0.5 ]", - "[ 1/1 → 17/16 | note:f am:4 amskew:0 ]", - "[ 17/16 → 9/8 | note:a am:4 amskew:0 ]", - "[ 9/8 → 19/16 | note:c am:4 amskew:0 ]", - "[ 19/16 → 5/4 | note:e am:4 amskew:0 ]", - "[ 5/4 → 21/16 | note:f am:4 amskew:0 ]", - "[ 21/16 → 11/8 | note:a am:4 amskew:0 ]", - "[ 11/8 → 23/16 | note:c am:4 amskew:0 ]", - "[ 23/16 → 3/2 | note:e am:4 amskew:0 ]", - "[ 3/2 → 25/16 | note:f am:4 amskew:0 ]", - "[ 25/16 → 13/8 | note:a am:4 amskew:0 ]", - "[ 13/8 → 27/16 | note:c am:4 amskew:0 ]", - "[ 27/16 → 7/4 | note:e am:4 amskew:0 ]", - "[ 7/4 → 29/16 | note:f am:4 amskew:0 ]", - "[ 29/16 → 15/8 | note:a am:4 amskew:0 ]", - "[ 15/8 → 31/16 | note:c am:4 amskew:0 ]", - "[ 31/16 → 2/1 | note:e am:4 amskew:0 ]", - "[ 2/1 → 33/16 | note:f am:4 amskew:1 ]", - "[ 33/16 → 17/8 | note:a am:4 amskew:1 ]", - "[ 17/8 → 35/16 | note:c am:4 amskew:1 ]", - "[ 35/16 → 9/4 | note:e am:4 amskew:1 ]", - "[ 9/4 → 37/16 | note:f am:4 amskew:1 ]", - "[ 37/16 → 19/8 | note:a am:4 amskew:1 ]", - "[ 19/8 → 39/16 | note:c am:4 amskew:1 ]", - "[ 39/16 → 5/2 | note:e am:4 amskew:1 ]", - "[ 5/2 → 41/16 | note:f am:4 amskew:1 ]", - "[ 41/16 → 21/8 | note:a am:4 amskew:1 ]", - "[ 21/8 → 43/16 | note:c am:4 amskew:1 ]", - "[ 43/16 → 11/4 | note:e am:4 amskew:1 ]", - "[ 11/4 → 45/16 | note:f am:4 amskew:1 ]", - "[ 45/16 → 23/8 | note:a am:4 amskew:1 ]", - "[ 23/8 → 47/16 | note:c am:4 amskew:1 ]", - "[ 47/16 → 3/1 | note:e am:4 amskew:1 ]", - "[ 3/1 → 49/16 | note:f am:4 amskew:0.5 ]", - "[ 49/16 → 25/8 | note:a am:4 amskew:0.5 ]", - "[ 25/8 → 51/16 | note:c am:4 amskew:0.5 ]", - "[ 51/16 → 13/4 | note:e am:4 amskew:0.5 ]", - "[ 13/4 → 53/16 | note:f am:4 amskew:0.5 ]", - "[ 53/16 → 27/8 | note:a am:4 amskew:0.5 ]", - "[ 27/8 → 55/16 | note:c am:4 amskew:0.5 ]", - "[ 55/16 → 7/2 | note:e am:4 amskew:0.5 ]", - "[ 7/2 → 57/16 | note:f am:4 amskew:0.5 ]", - "[ 57/16 → 29/8 | note:a am:4 amskew:0.5 ]", - "[ 29/8 → 59/16 | note:c am:4 amskew:0.5 ]", - "[ 59/16 → 15/4 | note:e am:4 amskew:0.5 ]", - "[ 15/4 → 61/16 | note:f am:4 amskew:0.5 ]", - "[ 61/16 → 31/8 | note:a am:4 amskew:0.5 ]", - "[ 31/8 → 63/16 | note:c am:4 amskew:0.5 ]", - "[ 63/16 → 4/1 | note:e am:4 amskew:0.5 ]", + "[ 0/1 → 1/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 1/16 → 1/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 1/8 → 3/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 3/16 → 1/4 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 1/4 → 5/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 5/16 → 3/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 3/8 → 7/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 7/16 → 1/2 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 1/2 → 9/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 9/16 → 5/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 5/8 → 11/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 11/16 → 3/4 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 3/4 → 13/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 13/16 → 7/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 7/8 → 15/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 15/16 → 1/1 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 1/1 → 17/16 | note:f am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 17/16 → 9/8 | note:a am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 9/8 → 19/16 | note:c am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 19/16 → 5/4 | note:e am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 5/4 → 21/16 | note:f am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 21/16 → 11/8 | note:a am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 11/8 → 23/16 | note:c am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 23/16 → 3/2 | note:e am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 3/2 → 25/16 | note:f am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 25/16 → 13/8 | note:a am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 13/8 → 27/16 | note:c am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 27/16 → 7/4 | note:e am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 7/4 → 29/16 | note:f am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 29/16 → 15/8 | note:a am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 15/8 → 31/16 | note:c am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 31/16 → 2/1 | note:e am:5 amskew:0.5 amdepth:0.5 attack:0.01 release:0.03 ]", + "[ 2/1 → 33/16 | note:f am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 33/16 → 17/8 | note:a am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 17/8 → 35/16 | note:c am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 35/16 → 9/4 | note:e am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 9/4 → 37/16 | note:f am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 37/16 → 19/8 | note:a am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 19/8 → 39/16 | note:c am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 39/16 → 5/2 | note:e am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 5/2 → 41/16 | note:f am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 41/16 → 21/8 | note:a am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 21/8 → 43/16 | note:c am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 43/16 → 11/4 | note:e am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 11/4 → 45/16 | note:f am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 45/16 → 23/8 | note:a am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 23/8 → 47/16 | note:c am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 47/16 → 3/1 | note:e am:5 amskew:0.5 amdepth:2 attack:0.01 release:0.03 ]", + "[ 3/1 → 49/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 49/16 → 25/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 25/8 → 51/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 51/16 → 13/4 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 13/4 → 53/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 53/16 → 27/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 27/8 → 55/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 55/16 → 7/2 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 7/2 → 57/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 57/16 → 29/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 29/8 → 59/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 59/16 → 15/4 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 15/4 → 61/16 | note:f am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 61/16 → 31/8 | note:a am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 31/8 → 63/16 | note:c am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", + "[ 63/16 → 4/1 | note:e am:5 amskew:0.5 amdepth:1 attack:0.01 release:0.03 ]", +] +`; + +exports[`runs examples > example "amsync" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | s:supersaw amsync:0.25 amskew:0 amdepth:2 ]", + "[ 1/1 → 2/1 | s:supersaw amsync:0.25 amskew:0.5 amdepth:2 ]", + "[ 2/1 → 3/1 | s:supersaw amsync:0.25 amskew:1 amdepth:2 ]", + "[ 3/1 → 4/1 | s:supersaw amsync:0.25 amskew:0 amdepth:2 ]", ] `; @@ -7076,8 +7085,6 @@ exports[`runs examples > example "ply" example index 0 1`] = ` ] `; -<<<<<<< HEAD -======= exports[`runs examples > example "polymeter" example index 0 1`] = ` [ "[ 0/1 → 1/6 | note:c ]", @@ -7131,7 +7138,6 @@ exports[`runs examples > example "polymeter" example index 0 1`] = ` ] `; ->>>>>>> main exports[`runs examples > example "postgain" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", @@ -9785,30 +9791,6 @@ exports[`runs examples > example "stack" example index 1 1`] = ` ] `; -<<<<<<< HEAD -exports[`runs examples > example "stack" example index 0 2`] = ` -[ - "[ 0/1 → 1/2 | note:e4 ]", - "[ 0/1 → 1/1 | note:g3 ]", - "[ 0/1 → 1/1 | note:b3 ]", - "[ 1/2 → 1/1 | note:d4 ]", - "[ 1/1 → 3/2 | note:e4 ]", - "[ 1/1 → 2/1 | note:g3 ]", - "[ 1/1 → 2/1 | note:b3 ]", - "[ 3/2 → 2/1 | note:d4 ]", - "[ 2/1 → 5/2 | note:e4 ]", - "[ 2/1 → 3/1 | note:g3 ]", - "[ 2/1 → 3/1 | note:b3 ]", - "[ 5/2 → 3/1 | note:d4 ]", - "[ 3/1 → 7/2 | note:e4 ]", - "[ 3/1 → 4/1 | note:g3 ]", - "[ 3/1 → 4/1 | note:b3 ]", - "[ 7/2 → 4/1 | note:d4 ]", -] -`; - -exports[`runs examples > example "steps" example index 0 1`] = ` -======= exports[`runs examples > example "stepalt" example index 0 1`] = ` [ "[ 0/1 → 1/5 | s:bd ]", @@ -9835,7 +9817,6 @@ exports[`runs examples > example "stepalt" example index 0 1`] = ` `; exports[`runs examples > example "stepcat" example index 0 1`] = ` ->>>>>>> main [ "[ 0/1 → 3/4 | note:e3 ]", "[ 3/4 → 1/1 | note:g3 ]", @@ -10182,8 +10163,6 @@ exports[`runs examples > example "swingBy" example index 0 1`] = ` ] `; -<<<<<<< HEAD -======= exports[`runs examples > example "sysex" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:c4 sysexid:119 sysexdata:[1 2 3 4] midichan:1 ]", @@ -10323,7 +10302,6 @@ exports[`runs examples > example "tour" example index 0 1`] = ` ] `; ->>>>>>> main exports[`runs examples > example "transpose" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:C2 ]",