mirror of
https://codeberg.org/uzu/strudel
synced 2026-09-05 14:58:03 -04:00
begin am feature
This commit is contained in:
@@ -134,7 +134,8 @@ const generic_params = [
|
||||
*
|
||||
*/
|
||||
[['fmi', 'fmh'], 'fm'],
|
||||
|
||||
['amh'],
|
||||
['ami'],
|
||||
/**
|
||||
* Select the sound bank to use. To be used together with `s`. The bank name (+ "_") will be prepended to the value of `s`.
|
||||
*
|
||||
|
||||
@@ -68,3 +68,17 @@ export const getFilter = (type, frequency, Q) => {
|
||||
filter.Q.value = Q;
|
||||
return filter;
|
||||
};
|
||||
|
||||
export const getAM = (freq, harmonicityRatio, amount, wave = 'sine') => {
|
||||
const carrfreq = freq;
|
||||
const modfreq = carrfreq * harmonicityRatio;
|
||||
const { node: modulator, stop } = mod(modfreq, amount, wave);
|
||||
const g = gainNode(1);
|
||||
modulator.connect(g.gain);
|
||||
return g;/*
|
||||
const c = 1 / 1 ** amount;
|
||||
console.log('c', c);
|
||||
const compensate = gainNode(1/amount);
|
||||
g.connect(compensate);
|
||||
return compensate; */
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
import './feedbackdelay.mjs';
|
||||
import './reverb.mjs';
|
||||
import './vowel.mjs';
|
||||
import { clamp } from './util.mjs';
|
||||
import { clamp, getFrequency } from './util.mjs';
|
||||
import workletsUrl from './worklets.mjs?url';
|
||||
import { getFilter, gainNode } from './helpers.mjs';
|
||||
import { map } from 'nanostores';
|
||||
@@ -167,6 +167,8 @@ export const superdough = async (value, deadline, hapDuration) => {
|
||||
room,
|
||||
size = 2,
|
||||
velocity = 1,
|
||||
amh, // amplitude modulation harmonicity
|
||||
ami = 4, // amplitude modulation index
|
||||
} = value;
|
||||
gain *= velocity; // legacy fix for velocity
|
||||
let toDisconnect = []; // audio nodes that will be disconnected when the source has ended
|
||||
@@ -205,6 +207,7 @@ export const superdough = async (value, deadline, hapDuration) => {
|
||||
// gain stage
|
||||
chain.push(gainNode(gain));
|
||||
|
||||
amh !== undefined && chain.push(getAM(getFrequency(value), amh, ami));
|
||||
// filters
|
||||
cutoff !== undefined && chain.push(getFilter('lowpass', cutoff, resonance));
|
||||
hcutoff !== undefined && chain.push(getFilter('highpass', hcutoff, hresonance));
|
||||
|
||||
@@ -2,7 +2,7 @@ import { midiToFreq, noteToMidi } from './util.mjs';
|
||||
import { registerSound, getAudioContext } from './superdough.mjs';
|
||||
import { getOscillator, gainNode, getEnvelope } from './helpers.mjs';
|
||||
|
||||
const mod = (freq, range = 1, type = 'sine') => {
|
||||
export const mod = (freq, range = 1, type = 'sine') => {
|
||||
const ctx = getAudioContext();
|
||||
const osc = ctx.createOscillator();
|
||||
osc.type = type;
|
||||
|
||||
@@ -51,3 +51,21 @@ export const valueToMidi = (value, fallbackValue) => {
|
||||
}
|
||||
return fallbackValue;
|
||||
};
|
||||
|
||||
export const getFrequency = (value) => {
|
||||
// if value is number => interpret as midi number as long as its not marked as frequency
|
||||
if (typeof value === 'object') {
|
||||
if (value.freq) {
|
||||
return value.freq;
|
||||
}
|
||||
return getFreq(value.note || value.n || value.value || 36);
|
||||
}
|
||||
if (typeof value === 'number' && context.type !== 'frequency') {
|
||||
value = midiToFreq(hap.value);
|
||||
} else if (typeof value === 'string' && isNote(value)) {
|
||||
value = midiToFreq(noteToMidi(hap.value));
|
||||
} else if (typeof value !== 'number') {
|
||||
throw new Error('not a note or frequency: ' + value);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user