Merge pull request 'FIX: PWM modulation' (#1467) from pwfix into main

Reviewed-on: https://codeberg.org/uzu/strudel/pulls/1467
This commit is contained in:
daslyfe 2025-07-21 07:16:17 +02:00
commit 004c0baa59
5 changed files with 24 additions and 13 deletions

View file

@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th
*/ */
import createClock from './zyklus.mjs'; import createClock from './zyklus.mjs';
import { logger } from './logger.mjs'; import { errorLogger, logger } from './logger.mjs';
export class Cyclist { export class Cyclist {
constructor({ constructor({
@ -76,7 +76,7 @@ export class Cyclist {
} }
}); });
} catch (e) { } catch (e) {
logger(`[cyclist] error: ${e.message}`); errorLogger(e);
onError?.(e); onError?.(e);
} }
}, },

View file

@ -4,6 +4,12 @@ let debounce = 1000,
lastMessage, lastMessage,
lastTime; lastTime;
export function errorLogger(e, origin = 'cyclist') {
//TODO: add some kind of debug flag that enables this while in dev mode
// console.error(e)
logger(`[${origin}] error: ${e.message}`);
}
export function logger(message, type, data = {}) { export function logger(message, type, data = {}) {
let t = performance.now(); let t = performance.now();
if (lastMessage === message && t - lastTime < debounce) { if (lastMessage === message && t - lastTime < debounce) {

View file

@ -1,7 +1,7 @@
import { NeoCyclist } from './neocyclist.mjs'; import { NeoCyclist } from './neocyclist.mjs';
import { Cyclist } from './cyclist.mjs'; import { Cyclist } from './cyclist.mjs';
import { evaluate as _evaluate } from './evaluate.mjs'; import { evaluate as _evaluate } from './evaluate.mjs';
import { logger } from './logger.mjs'; import { errorLogger, logger } from './logger.mjs';
import { setTime } from './time.mjs'; import { setTime } from './time.mjs';
import { evalScope } from './evaluate.mjs'; import { evalScope } from './evaluate.mjs';
import { register, Pattern, isPattern, silence, stack } from './pattern.mjs'; import { register, Pattern, isPattern, silence, stack } from './pattern.mjs';
@ -256,6 +256,6 @@ export const getTrigger =
await hap.context.onTrigger(hap, getTime(), cps, t); await hap.context.onTrigger(hap, getTime(), cps, t);
} }
} catch (err) { } catch (err) {
logger(`[cyclist] error: ${err.message}`, 'error'); errorLogger(err, 'getTrigger');
} }
}; };

View file

@ -346,21 +346,23 @@ function getDelay(orbit, delaytime, delayfeedback, t, channels) {
export function getLfo(audioContext, begin, end, properties = {}) { export function getLfo(audioContext, begin, end, properties = {}) {
const { shape = 0, ...props } = properties; const { shape = 0, ...props } = properties;
const { dcoffset = -0.5, depth = 1 } = properties; const { dcoffset = -0.5, depth = 1 } = properties;
return getWorklet(audioContext, 'lfo-processor', { const lfoprops = {
frequency: 1, frequency: 1,
depth, depth,
skew: 0, skew: 0.5,
phaseoffset: 0, phaseoffset: 0,
time: begin, time: begin,
begin, begin,
end, end,
shape: getModulationShapeInput(shape), shape: getModulationShapeInput(shape),
dcoffset, dcoffset,
min: dcoffset - depth * 0.5, min: dcoffset * depth,
max: dcoffset + depth * 0.5, max: dcoffset * depth + depth,
curve: 1, curve: 1,
...props, ...props,
}); };
return getWorklet(audioContext, 'lfo-processor', lfoprops);
} }
export function getSyncedLfo(audioContext, time, end, cps, cycle, properties = {}) { export function getSyncedLfo(audioContext, time, end, cps, cycle, properties = {}) {

View file

@ -81,6 +81,7 @@ function getParamValue(block, param) {
} }
return param[0]; return param[0];
} }
const waveShapeNames = Object.keys(waveshapes); const waveShapeNames = Object.keys(waveshapes);
class LFOProcessor extends AudioWorkletProcessor { class LFOProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() { static get parameterDescriptors() {
@ -129,11 +130,12 @@ class LFOProcessor extends AudioWorkletProcessor {
const depth = parameters['depth'][0]; const depth = parameters['depth'][0];
const skew = parameters['skew'][0]; const skew = parameters['skew'][0];
const phaseoffset = parameters['phaseoffset'][0]; const phaseoffset = parameters['phaseoffset'][0];
const min = parameters['min'][0];
const max = parameters['max'][0];
const curve = parameters['curve'][0]; const curve = parameters['curve'][0];
const dcoffset = parameters['dcoffset'][0]; const dcoffset = parameters['dcoffset'][0];
const min = parameters['min'][0];
const max = parameters['max'][0];
const shape = waveShapeNames[parameters['shape'][0]]; const shape = waveShapeNames[parameters['shape'][0]];
const blockSize = output[0].length ?? 0; const blockSize = output[0].length ?? 0;
@ -145,8 +147,9 @@ class LFOProcessor extends AudioWorkletProcessor {
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 < output.length; i++) { for (let i = 0; i < output.length; i++) {
const modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth; let modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth;
output[i][n] = clamp(Math.pow(modval, curve), min, max); modval = Math.pow(modval, curve);
output[i][n] = clamp(modval, min, max);
} }
this.incrementPhase(dt); this.incrementPhase(dt);
} }