fixed tri shape

This commit is contained in:
Jade (Rose) Rowland 2024-05-09 00:21:21 -04:00
parent 16472b59dd
commit 6c05a4eb7b
4 changed files with 46 additions and 14 deletions

View file

@ -439,7 +439,7 @@ export const { coarse } = registerControl('coarse');
* s("triangle").am("2").amshape("<tri saw ramp square>").amdepth(.5) * s("triangle").am("2").amshape("<tri saw ramp square>").amdepth(.5)
* *
*/ */
export const { am } = registerControl(['am', 'amdepth', 'amshape']); export const { am } = registerControl(['am', 'amdepth', 'amskew', 'amphase']);
/** /**
* depth of amplitude modulation * depth of amplitude modulation
@ -451,6 +451,27 @@ export const { am } = registerControl(['am', 'amdepth', 'amshape']);
* *
*/ */
export const { amdepth } = registerControl('amdepth'); export const { amdepth } = registerControl('amdepth');
/**
* alter the shape of the modulation waveform
*
* @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>")
*
*/
export const { amskew } = registerControl('amskew');
/**
* alter the phase of the modulation waveform
*
* @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>")
*
*/
export const { amphase } = registerControl('amskew');
/** /**
* shape of amplitude modulation * shape of amplitude modulation

View file

@ -34,13 +34,16 @@ export class Cyclist {
try { try {
const begin = this.lastEnd; const begin = this.lastEnd;
const cycle = this.now();
this.lastBegin = begin; this.lastBegin = begin;
const end = this.num_cycles_at_cps_change + num_cycles_since_cps_change; const end = this.num_cycles_at_cps_change + num_cycles_since_cps_change;
this.lastEnd = end; this.lastEnd = end;
this.lastTick = phase; this.lastTick = phase;
const cycle = this.now();
if (phase < t) { if (phase < t) {
// avoid querying haps that are in the past anyway // avoid querying haps that are in the past anyway
console.log(`skip query: too late`); console.log(`skip query: too late`);

View file

@ -281,8 +281,10 @@ export const superdough = async (value, t, hapDuration, cps, cycle) => {
} }
// destructure // destructure
let { let {
am,
amdepth = 1, amdepth = 1,
amshape = 'tri', amskew = 0.5,
amphase = 0,
s = 'triangle', s = 'triangle',
bank, bank,
source, source,
@ -324,7 +326,7 @@ export const superdough = async (value, t, hapDuration, cps, cycle) => {
phasercenter, phasercenter,
// //
coarse, coarse,
am,
crush, crush,
shape, shape,
@ -479,6 +481,8 @@ export const superdough = async (value, t, hapDuration, cps, cycle) => {
getWorklet(ac, 'am-processor', { getWorklet(ac, 'am-processor', {
speed: am, speed: am,
depth: amdepth, depth: amdepth,
skew: amskew,
phaseoffset: amphase,
// shape: amshape, // shape: amshape,
cps, cps,

View file

@ -1,7 +1,7 @@
// coarse, crush, and shape processors adapted from dktr0's webdirt: https://github.com/dktr0/WebDirt/blob/5ce3d698362c54d6e1b68acc47eb2955ac62c793/dist/AudioWorklets.js // coarse, crush, and shape processors adapted from dktr0's webdirt: https://github.com/dktr0/WebDirt/blob/5ce3d698362c54d6e1b68acc47eb2955ac62c793/dist/AudioWorklets.js
// LICENSE GNU General Public License v3.0 see https://github.com/dktr0/WebDirt/blob/main/LICENSE // LICENSE GNU General Public License v3.0 see https://github.com/dktr0/WebDirt/blob/main/LICENSE
import { clamp, _mod } from './util.mjs';
const clamp = (num, min, max) => Math.min(Math.max(num, min), max); // const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
const blockSize = 128; const blockSize = 128;
// adjust waveshape to remove frequencies above nyquist to prevent aliasing // adjust waveshape to remove frequencies above nyquist to prevent aliasing
// referenced from https://www.kvraudio.com/forum/viewtopic.php?t=375517 // referenced from https://www.kvraudio.com/forum/viewtopic.php?t=375517
@ -55,16 +55,17 @@ const waveshapes = {
return 1 - phase; return 1 - phase;
}, },
tri(phase, skew = 0.5) { tri(phase, skew = 0.5) {
const x = 1 - skew;
if (phase >= skew) { if (phase >= skew) {
return 1 - ((phase / (1 - skew)) % 1); return 1 / x - phase / x;
} }
return (phase / skew) % 1; return phase / skew;
}, },
square(phase, skew = 0.5) { square(phase, skew = 0.5) {
if (phase >= skew) { if (phase >= skew) {
return 1; return 0;
} }
return 0; return 1;
}, },
}; };
@ -74,8 +75,9 @@ class AMProcessor extends AudioWorkletProcessor {
{ name: 'cps', defaultValue: 0.5 }, { name: 'cps', defaultValue: 0.5 },
{ name: 'speed', defaultValue: 0.5 }, { name: 'speed', defaultValue: 0.5 },
{ name: 'cycle', defaultValue: 0 }, { name: 'cycle', defaultValue: 0 },
// { name: 'shape', defaultValue: 'tri' }, { name: 'skew', defaultValue: 0.5 },
{ name: 'depth', defaultValue: 1 }, { name: 'depth', defaultValue: 1 },
{ name: 'phaseoffset', defaultValue: 0 },
]; ];
} }
@ -104,18 +106,20 @@ class AMProcessor extends AudioWorkletProcessor {
const speed = parameters['speed'][0]; const speed = parameters['speed'][0];
const cps = parameters['cps'][0]; const cps = parameters['cps'][0];
const cycle = parameters['cycle'][0]; const cycle = parameters['cycle'][0];
const depth = clamp(parameters['depth'][0], 0, 1); const depth = parameters['depth'][0];
const skew = parameters['skew'][0];
const phaseoffset = parameters['phaseoffset'][0];
const blockSize = 128; const blockSize = 128;
const frequency = speed * cps; const frequency = speed * cps;
if (this.phase == null) { if (this.phase == null) {
const secondsPassed = cycle / cps; const secondsPassed = cycle / cps;
this.phase = Math.max(0, (secondsPassed * frequency) % 1); this.phase = _mod(secondsPassed * frequency + phaseoffset, 1);
} }
const dt = frequency / sampleRate; const dt = frequency / sampleRate;
for (let n = 0; n < blockSize; n++) { for (let n = 0; n < blockSize; n++) {
for (let i = 0; i < input.length; i++) { for (let i = 0; i < input.length; i++) {
const modval = waveshapes.tri(this.phase, 0.99) * depth + (1 - depth); const modval = clamp(waveshapes.tri(this.phase, skew) * depth + (1 - depth), 0, 1);
output[i][n] = input[i][n] * modval; output[i][n] = input[i][n] * modval;
} }