feat: improve learn experience

This commit is contained in:
Remi
2025-09-19 23:00:58 +02:00
committed by itsrubberduck
parent 4a9fec3ef9
commit 103fdd6bbc
3 changed files with 55 additions and 39 deletions

View File

@@ -65,7 +65,7 @@ function sanitizeConfig(input: Partial<LearnConfig> | undefined): LearnConfig |
}
if (typeof input.audioSpeed === 'number' && Number.isFinite(input.audioSpeed)) {
const rounded = Math.round(input.audioSpeed * 10) / 10
const rounded = Math.round(input.audioSpeed * 20) / 20
config.audioSpeed = Math.min(1.3, Math.max(0.7, rounded))
}

View File

@@ -268,11 +268,16 @@ class TremoloEffect implements EffectNode {
private modulationGain: GainNode
private started = false
private depth: number
private offset?: number
private randomizePhase: boolean
inputNode: AudioNode
outputNode: AudioNode
constructor(context: AudioContext, options: { speed?: number; depth?: number; type?: OscillatorType } = {}) {
constructor(
context: AudioContext,
options: { speed?: number; depth?: number; type?: OscillatorType; offset?: number; randomizePhase?: boolean } = {}
) {
this.context = context
this.input = context.createGain()
this.output = context.createGain()
@@ -286,6 +291,8 @@ class TremoloEffect implements EffectNode {
this.oscillator = context.createOscillator()
this.oscillator.type = options.type ?? 'sine'
this.oscillator.frequency.value = options.speed ?? 5
this.offset = options.offset
this.randomizePhase = options.randomizePhase !== false
this.input.connect(this.output)
this.oscillator.connect(this.modulationGain)
@@ -298,7 +305,12 @@ class TremoloEffect implements EffectNode {
onActivate() {
if (this.started) return
try {
this.oscillator.start()
let offset = this.offset ?? 0
if (this.offset === undefined && this.randomizePhase) {
const frequency = Math.max(0.0001, this.oscillator.frequency.value)
offset = Math.random() * (1 / frequency)
}
this.oscillator.start(0, offset)
this.started = true
} catch {
// oscillator already started

View File

@@ -8,7 +8,7 @@ export type ReadabilityProfile = {
}
presence?: { frequency: number; q: number; gain: number }
distortions: number[]
tremolos?: Array<{ depth: number; speed: number; type?: OscillatorType }>
tremolos?: Array<{ depth: number; speed: number; type?: OscillatorType; offset?: number; randomizePhase?: boolean }>
gain: number
compressor: Partial<{ threshold: number; knee: number; ratio: number; attack: number; release: number }>
noise: { amplitude: number; bandFrequency: number; bandQ: number; crackle?: boolean }
@@ -16,52 +16,56 @@ export type ReadabilityProfile = {
const readabilityProfiles: Record<number, ReadabilityProfile> = {
1: {
eq: { highpass: 520, highpassQ: 1.1, lowpass: 1700, lowpassQ: 0.85, bandpass: { frequency: 1100, q: 2.6 } },
presence: { frequency: 1300, q: 2.1, gain: 4 },
distortions: [420, 260],
eq: { highpass: 540, highpassQ: 1.2, lowpass: 1600, lowpassQ: 0.8, bandpass: { frequency: 1150, q: 2.8 } },
presence: { frequency: 1350, q: 2.4, gain: 5 },
distortions: [360, 240],
tremolos: [
{ depth: 0.92, speed: 7.6, type: 'square' },
{ depth: 0.38, speed: 5.1 }
{ depth: 0.7, speed: 4.9, type: 'sine' },
{ depth: 0.28, speed: 9.4, type: 'triangle' },
{ depth: 0.2, speed: 2.6, type: 'sine' }
],
gain: 0.84,
compressor: { threshold: -32, ratio: 14, attack: 0.004, release: 0.3 },
noise: { amplitude: 0.12, bandFrequency: 1500, bandQ: 1.6, crackle: true }
gain: 0.82,
compressor: { threshold: -33, ratio: 16, attack: 0.004, release: 0.32 },
noise: { amplitude: 0.13, bandFrequency: 1500, bandQ: 1.6, crackle: true }
},
2: {
eq: { highpass: 440, highpassQ: 0.95, lowpass: 2100, lowpassQ: 0.9, bandpass: { frequency: 1650, q: 1.9 } },
presence: { frequency: 1700, q: 1.2, gain: 2.5 },
distortions: [320],
tremolos: [{ depth: 0.24, speed: 5.2 }],
gain: 0.88,
compressor: { threshold: -30, ratio: 13, attack: 0.0035, release: 0.28 },
noise: { amplitude: 0.085, bandFrequency: 1800, bandQ: 1.4, crackle: true }
eq: { highpass: 470, highpassQ: 1, lowpass: 2100, lowpassQ: 0.85, bandpass: { frequency: 1700, q: 2 } },
presence: { frequency: 1750, q: 1.3, gain: 3 },
distortions: [280, 160],
tremolos: [
{ depth: 0.42, speed: 5.6, type: 'sine' },
{ depth: 0.24, speed: 3.3, type: 'triangle' }
],
gain: 0.86,
compressor: { threshold: -30, ratio: 14, attack: 0.0038, release: 0.3 },
noise: { amplitude: 0.09, bandFrequency: 1850, bandQ: 1.35, crackle: true }
},
3: {
eq: { highpass: 360, highpassQ: 0.8, lowpass: 2600, lowpassQ: 0.9, bandpass: { frequency: 1850, q: 1.5 } },
presence: { frequency: 2100, q: 1.3, gain: 1.8 },
distortions: [220],
tremolos: [{ depth: 0.14, speed: 4.5 }],
eq: { highpass: 380, highpassQ: 0.85, lowpass: 2600, lowpassQ: 0.88, bandpass: { frequency: 1900, q: 1.5 } },
presence: { frequency: 2150, q: 1.3, gain: 2 },
distortions: [210],
tremolos: [{ depth: 0.18, speed: 4.2, type: 'sine' }],
gain: 0.9,
compressor: { threshold: -28, ratio: 12, attack: 0.003, release: 0.26 },
noise: { amplitude: 0.055, bandFrequency: 1900, bandQ: 1.2 }
compressor: { threshold: -28, ratio: 12, attack: 0.0032, release: 0.26 },
noise: { amplitude: 0.055, bandFrequency: 1950, bandQ: 1.2 }
},
4: {
eq: { highpass: 310, highpassQ: 0.7, lowpass: 3050, lowpassQ: 0.85, bandpass: { frequency: 2000, q: 1.2 } },
presence: { frequency: 2300, q: 1.4, gain: 1.4 },
distortions: [140],
tremolos: [{ depth: 0.08, speed: 3.6 }],
gain: 0.93,
compressor: { threshold: -27, ratio: 11, attack: 0.0028, release: 0.23 },
noise: { amplitude: 0.035, bandFrequency: 2000, bandQ: 1.1 }
eq: { highpass: 310, highpassQ: 0.7, lowpass: 3150, lowpassQ: 0.82, bandpass: { frequency: 2050, q: 1.2 } },
presence: { frequency: 2350, q: 1.35, gain: 1.5 },
distortions: [130],
tremolos: [{ depth: 0.08, speed: 3.1, type: 'sine' }],
gain: 0.94,
compressor: { threshold: -27, ratio: 11, attack: 0.0028, release: 0.22 },
noise: { amplitude: 0.035, bandFrequency: 2050, bandQ: 1.08 }
},
5: {
eq: { highpass: 280, highpassQ: 0.65, lowpass: 3300, lowpassQ: 0.8, bandpass: { frequency: 2150, q: 1.1 } },
presence: { frequency: 2450, q: 1.5, gain: 1.1 },
distortions: [90],
tremolos: [{ depth: 0.05, speed: 3 }],
gain: 0.96,
compressor: { threshold: -26, ratio: 10, attack: 0.0025, release: 0.2 },
noise: { amplitude: 0.02, bandFrequency: 2100, bandQ: 1 }
eq: { highpass: 260, highpassQ: 0.6, lowpass: 3600, lowpassQ: 0.78, bandpass: { frequency: 2250, q: 1.05 } },
presence: { frequency: 2550, q: 1.5, gain: 1.1 },
distortions: [60],
tremolos: [{ depth: 0.04, speed: 2.4, type: 'sine' }],
gain: 0.98,
compressor: { threshold: -25, ratio: 9.5, attack: 0.0025, release: 0.18 },
noise: { amplitude: 0.016, bandFrequency: 2150, bandQ: 1 }
}
}