mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-21 20:55:12 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d7438b939 | |||
| 52de58ef1f |
@@ -139,6 +139,8 @@ const generic_params = [
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
[['fmi', 'fmh'], 'fm'],
|
[['fmi', 'fmh'], 'fm'],
|
||||||
|
['amh'],
|
||||||
|
['ami'],
|
||||||
// fm envelope
|
// fm envelope
|
||||||
/**
|
/**
|
||||||
* Ramp type of fm envelope. Exp might be a bit broken..
|
* Ramp type of fm envelope. Exp might be a bit broken..
|
||||||
|
|||||||
@@ -78,6 +78,19 @@ export const getParamADSR = (param, attack, decay, sustain, release, min, max, b
|
|||||||
param.linearRampToValueAtTime(min, end + Math.max(release, 0.1));
|
param.linearRampToValueAtTime(min, end + Math.max(release, 0.1));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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; */
|
||||||
|
};
|
||||||
export function createFilter(
|
export function createFilter(
|
||||||
context,
|
context,
|
||||||
type,
|
type,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
import './feedbackdelay.mjs';
|
import './feedbackdelay.mjs';
|
||||||
import './reverb.mjs';
|
import './reverb.mjs';
|
||||||
import './vowel.mjs';
|
import './vowel.mjs';
|
||||||
import { clamp } from './util.mjs';
|
import { clamp, getFrequency } from './util.mjs';
|
||||||
import workletsUrl from './worklets.mjs?url';
|
import workletsUrl from './worklets.mjs?url';
|
||||||
import { createFilter, gainNode } from './helpers.mjs';
|
import { createFilter, gainNode } from './helpers.mjs';
|
||||||
import { map } from 'nanostores';
|
import { map } from 'nanostores';
|
||||||
@@ -217,6 +217,8 @@ export const superdough = async (value, deadline, hapDuration) => {
|
|||||||
room,
|
room,
|
||||||
size = 2,
|
size = 2,
|
||||||
velocity = 1,
|
velocity = 1,
|
||||||
|
amh, // amplitude modulation harmonicity
|
||||||
|
ami = 4, // amplitude modulation index
|
||||||
analyze, // analyser wet
|
analyze, // analyser wet
|
||||||
fft = 8, // fftSize 0 - 10
|
fft = 8, // fftSize 0 - 10
|
||||||
} = value;
|
} = value;
|
||||||
@@ -257,6 +259,9 @@ export const superdough = async (value, deadline, hapDuration) => {
|
|||||||
// gain stage
|
// gain stage
|
||||||
chain.push(gainNode(gain));
|
chain.push(gainNode(gain));
|
||||||
|
|
||||||
|
amh !== undefined && chain.push(getAM(getFrequency(value), amh, ami));
|
||||||
|
|
||||||
|
// filters
|
||||||
if (cutoff !== undefined) {
|
if (cutoff !== undefined) {
|
||||||
let lp = () =>
|
let lp = () =>
|
||||||
createFilter(
|
createFilter(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { midiToFreq, noteToMidi } from './util.mjs';
|
|||||||
import { registerSound, getAudioContext } from './superdough.mjs';
|
import { registerSound, getAudioContext } from './superdough.mjs';
|
||||||
import { gainNode, getEnvelope, getExpEnvelope } from './helpers.mjs';
|
import { gainNode, getEnvelope, getExpEnvelope } from './helpers.mjs';
|
||||||
|
|
||||||
const mod = (freq, range = 1, type = 'sine') => {
|
export const mod = (freq, range = 1, type = 'sine') => {
|
||||||
const ctx = getAudioContext();
|
const ctx = getAudioContext();
|
||||||
const osc = ctx.createOscillator();
|
const osc = ctx.createOscillator();
|
||||||
osc.type = type;
|
osc.type = type;
|
||||||
|
|||||||
@@ -51,3 +51,21 @@ export const valueToMidi = (value, fallbackValue) => {
|
|||||||
}
|
}
|
||||||
return 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