clean interface

This commit is contained in:
2025-10-12 11:32:36 +02:00
parent 6c11c5756a
commit fcb784d403
13 changed files with 536 additions and 118 deletions

View File

@ -1,4 +1,4 @@
import type { SynthEngine } from './SynthEngine';
import type { SynthEngine, PitchLock } from './SynthEngine';
type HarmonicMode =
| 'single' // Just fundamental
@ -323,7 +323,7 @@ export class KarplusStrong implements SynthEngine<KarplusStrongParams> {
}
}
randomParams(): KarplusStrongParams {
randomParams(pitchLock?: PitchLock): KarplusStrongParams {
// Musical frequencies (notes from E2 to E5)
const frequencies = [
82.41, 87.31, 92.50, 98.00, 103.83, 110.00, 116.54, 123.47, 130.81, 138.59,
@ -333,6 +333,10 @@ export class KarplusStrong implements SynthEngine<KarplusStrongParams> {
830.61, 880.00, 932.33, 987.77, 1046.50, 1108.73, 1174.66, 1244.51, 1318.51
];
const frequency = pitchLock?.enabled
? pitchLock.frequency
: frequencies[Math.floor(Math.random() * frequencies.length)];
// Randomly choose harmonic mode
// Weighted selection: favor more consonant intervals
const modes: HarmonicMode[] = [
@ -362,7 +366,7 @@ export class KarplusStrong implements SynthEngine<KarplusStrongParams> {
];
return {
frequency: frequencies[Math.floor(Math.random() * frequencies.length)],
frequency,
damping: 0.7 + Math.random() * 0.29, // 0.7 to 0.99
brightness: Math.random(), // 0 to 1
decayCharacter: (Math.random() * 2 - 1) * 0.8, // -0.8 to 0.8 (mostly natural darkening)
@ -378,15 +382,17 @@ export class KarplusStrong implements SynthEngine<KarplusStrongParams> {
};
}
mutateParams(params: KarplusStrongParams, mutationAmount: number = 0.15): KarplusStrongParams {
mutateParams(params: KarplusStrongParams, mutationAmount: number = 0.15, pitchLock?: PitchLock): KarplusStrongParams {
const mutate = (value: number, range: number, min: number, max: number) => {
const delta = (Math.random() * 2 - 1) * range * mutationAmount;
return Math.max(min, Math.min(max, value + delta));
};
// Occasionally jump to harmonic/subharmonic
let newFreq = params.frequency;
if (Math.random() < 0.15) {
// Occasionally jump to harmonic/subharmonic (unless pitch locked)
let newFreq: number;
if (pitchLock?.enabled) {
newFreq = pitchLock.frequency;
} else if (Math.random() < 0.15) {
const multipliers = [0.5, 2, 1.5, 3];
newFreq = params.frequency * multipliers[Math.floor(Math.random() * multipliers.length)];
newFreq = Math.max(50, Math.min(2000, newFreq));