From 0e1bff82597355e68f08257c79f792116e722677 Mon Sep 17 00:00:00 2001 From: jawhinge Date: Mon, 29 Dec 2025 13:05:39 +0200 Subject: [PATCH] change to fat synth, finetune parameters --- src/lib/audio/instruments/noiseSynth.ts | 2 +- src/lib/audio/instruments/padSynth.ts | 14 ++++---- .../air-quality/AirQualityGen.svelte | 2 +- src/lib/generators/weather/WeatherGen.svelte | 32 +++++++++---------- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/lib/audio/instruments/noiseSynth.ts b/src/lib/audio/instruments/noiseSynth.ts index 3326f68..cfbf60c 100644 --- a/src/lib/audio/instruments/noiseSynth.ts +++ b/src/lib/audio/instruments/noiseSynth.ts @@ -9,7 +9,7 @@ export function createNoiseSynth(volume: number): Tone.NoiseSynth { attack: 0.005, decay: 0.1, sustain: 0, - release: 0.1 + release: 0.3 }, volume: volume }); diff --git a/src/lib/audio/instruments/padSynth.ts b/src/lib/audio/instruments/padSynth.ts index 38a5060..ca4d3f4 100644 --- a/src/lib/audio/instruments/padSynth.ts +++ b/src/lib/audio/instruments/padSynth.ts @@ -3,14 +3,16 @@ import * as Tone from 'tone'; export function createPadSynth(isDay: boolean): Tone.PolySynth { return new Tone.PolySynth(Tone.Synth, { oscillator: { - type: isDay ? 'triangle' : 'sine' + type: 'fatsine', // Fat oscillator creates multiple detuned voices for lush sound + count: 3, // Number of detuned oscillators + spread: 30 // Amount of detune in cents for width and movement }, envelope: { - attack: 1.5, - decay: 1, - sustain: 0.7, - release: 1.0 + attack: isDay ? 2.0 : 3.0, // Longer, smoother attack + decay: 1.5, + sustain: 0.85, // Higher sustain for consistent pad presence + release: isDay ? 2.5 : 4.0 // Longer release for smooth tail-off }, - volume: -20 + volume: -24 // Quieter to sit back in the mix and reduce mid heaviness }); } diff --git a/src/lib/generators/air-quality/AirQualityGen.svelte b/src/lib/generators/air-quality/AirQualityGen.svelte index a8aeb9c..8d1925f 100644 --- a/src/lib/generators/air-quality/AirQualityGen.svelte +++ b/src/lib/generators/air-quality/AirQualityGen.svelte @@ -217,7 +217,7 @@ onclick={togglePlayback} disabled={!isInitialized} > - {isPlaying ? 'Stop' : 'Start'} Air Quality Monitor + {isPlaying ? 'Stop' : 'Start'} Air Quality Noise {#if isPlaying} diff --git a/src/lib/generators/weather/WeatherGen.svelte b/src/lib/generators/weather/WeatherGen.svelte index 1df1555..f572ed4 100644 --- a/src/lib/generators/weather/WeatherGen.svelte +++ b/src/lib/generators/weather/WeatherGen.svelte @@ -42,7 +42,6 @@ let reverb: Tone.Reverb | null = null; let delay: Tone.FeedbackDelay | null = null; let filter: Tone.Filter | null = null; - let phaser: Tone.Phaser | null = null; let sequence: Tone.Sequence | null = null; let gain: Tone.Gain | null = null; let analyser: Tone.Analyser | null = null; @@ -62,11 +61,9 @@ // Derived reactive values using runes with safe fallbacks const bpm = $derived.by(() => { const temp = temperature2m ?? 20; - // BPM starts at 10 for 0°C and increases with temperature - // Day: more energetic (2x scaling), Night: calmer (1x scaling) - const tempAboveZero = Math.max(0, temp); - const scaledBpm = isDay ? 10 + tempAboveZero * 2 : 10 + tempAboveZero; - return Math.max(10, Math.min(200, scaledBpm)); + // BPM: 5 at 0°C or below, 30 at 30°C or above + const normalizedTemp = Math.max(0, Math.min(30, temp)); + return 5 + (normalizedTemp / 30) * 25; }); const reverbWet = $derived.by(() => { @@ -88,11 +85,12 @@ return Math.max(0.2, Math.min(0.7, (speed / 20) * 0.5 + 0.2)); }); - // Filter cutoff: more clouds = darker/lower frequency + // Filter cutoff: colder = darker/lower frequency, warmer = brighter/higher frequency const filterCutoff = $derived.by(() => { - const cover = cloudCover ?? 30; - // Map cloud cover: 0% clouds = 8000Hz (bright), 100% clouds = 400Hz (dark) - return Math.max(400, Math.min(8000, 8000 - (cover / 100) * 7600)); + const temp = temperature2m ?? 20; + // Map temperature: 0°C = 400Hz (dark), 30°C = 8000Hz (bright) + const normalizedTemp = Math.max(0, Math.min(30, temp)); + return 400 + (normalizedTemp / 30) * 7600; }); // Filter resonance: more wind = more resonant @@ -167,9 +165,11 @@ analyser = createAnalyser(); // Connect audio chain using .chain() for clarity + // Synth gets filtered based on temperature synth.chain(filter, delay, reverb, gain, analyser, Tone.Destination); - arpSynth.chain(filter, delay, reverb, gain); - pingSynth.chain(filter, delay, reverb, gain); + // Arpeggios bypass filter - only delay and reverb + arpSynth.chain(delay, reverb, gain); + pingSynth.chain(delay, reverb, gain); bassSynth.chain(delay, reverb, gain); // Generate reverb impulse @@ -432,10 +432,10 @@ }); -
+