fixed tri shape
This commit is contained in:
parent
16472b59dd
commit
6c05a4eb7b
4 changed files with 46 additions and 14 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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`);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue