176 lines
7.2 KiB
Markdown
176 lines
7.2 KiB
Markdown
# hear-on-out
|
|
|
|
A generative ambient music application that transforms real-time weather and air quality data into dynamic soundscapes.
|
|
|
|
## Overview
|
|
|
|
hear-on-out uses your geolocation to fetch current weather and air quality data, then generates unique ambient music that responds to environmental conditions in real-time. Every parameter of the audio - from tempo to reverb to note patterns - is affected by the weather around you.
|
|
|
|
## Features
|
|
|
|
### Weather-Reactive Generative Music
|
|
|
|
**Chord Progressions**
|
|
- 6 distinct mood-based progressions (bright, dreamy, melancholic, tense, warm, ethereal)
|
|
- Intelligent selection based on weather comfort scoring
|
|
- Smooth transitions between progressions
|
|
|
|
**Instruments**
|
|
- **Ambient Pad**: Lush detuned fat oscillator (3 voices, 30 cent spread) with day/night reactive envelopes for rich, warm soundscapes
|
|
- **Main Arpeggio**: Temperature-reactive note patterns with variable speed (1n → 8n) and volume, bypasses filter for clarity
|
|
- **Ping Arpeggio**: High-pitched reverse arpeggios that intensify with weather extremity, speed scales with temperature (1n → 16n)
|
|
- **Bass Synth**: Root note foundation with randomized release times for subtle variation
|
|
|
|
**Dynamic Audio Parameters**
|
|
- **BPM**: Scales linearly with temperature (5 BPM at 0°C → 30 BPM at 30°C)
|
|
- **Reverb**: Wet signal responds to humidity (more humid = more reverb)
|
|
- **Delay**: Time and feedback react to wind speed (faster wind = shorter delay, more feedback)
|
|
- **Filter**: Applied only to ambient pad, cutoff frequency brightens with temperature (0°C = 400Hz dark, 30°C = 8000Hz bright)
|
|
- **Resonance**: Increases with wind speed for sharper filtering
|
|
|
|
### Air Quality Monitor
|
|
|
|
- Geiger-counter style noise bursts that trigger based on pollution levels
|
|
- Higher pollution = more frequent bursts (6s intervals for clean air → 0.3s for heavy pollution)
|
|
- Spacious reverb (30s decay) for atmospheric depth
|
|
- Monitors PM2.5, PM10, and dust particles
|
|
|
|
### Audio Visualization
|
|
|
|
- Real-time particle system using p5.js
|
|
- **Desktop**: 40 particles at 30fps with connection lines
|
|
- **Mobile**: 15 particles at 20fps, no connections (performance optimized)
|
|
- FFT analysis for bass, mid, and treble frequency detection
|
|
- Particles react to audio levels with dynamic size and movement
|
|
- Adaptive sizing: 400x400px (desktop) or 280x280px (mobile)
|
|
- Automatic pause during scrolling to prevent audio interference on mobile
|
|
|
|
## Technologies
|
|
|
|
- **SvelteKit** - Web framework with Svelte 5 runes
|
|
- **Tone.js** - Web Audio API wrapper for synthesis and effects
|
|
- **p5.js** - Creative coding for visualizations
|
|
- **Tailwind CSS v4** - Styling with black/white monochrome theme
|
|
- **Open-Meteo API** - Weather and air quality data
|
|
|
|
## Performance Optimizations
|
|
|
|
The application includes several optimizations for smooth performance:
|
|
|
|
**Desktop Optimizations:**
|
|
- 40 particles with 30fps rendering
|
|
- Audio-reactive displacement updates every 3rd frame
|
|
- Particle connections drawn every other frame with limited neighbor checking
|
|
- Tab visibility detection: Visualization pauses when tab is not focused
|
|
- Efficient audio routing: Arpeggios bypass filter for cleaner CPU usage
|
|
|
|
**Mobile-Specific Optimizations:**
|
|
- **Reduced particle count**: 15 particles (vs 40 on desktop)
|
|
- **Lower framerate**: 20fps (vs 30fps on desktop)
|
|
- **Disabled connection lines**: Removes expensive O(n²) calculations
|
|
- **Smaller canvas**: 280x280px visualizations (vs 400x400px on desktop)
|
|
- **Scroll handling**: Visualization pauses during scrolling to prevent audio stuttering
|
|
- **Less frequent updates**: Displacement updates every 5th frame (vs 3rd on desktop)
|
|
- **Screen sleep recovery**: Audio context automatically resumes after device wakes up
|
|
- **Visibility API**: Properly handles audio context suspension/resumption
|
|
|
|
**Mobile Performance Note:**
|
|
Running both generators simultaneously on mobile devices may cause performance issues. For optimal experience on mobile, consider running one generator at a time.
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Run development server
|
|
npm run dev
|
|
|
|
# Build for production
|
|
npm run build
|
|
```
|
|
|
|
## How It Works
|
|
|
|
1. **Location Input**: User can either:
|
|
- Grant browser geolocation permissions (automatic location detection)
|
|
- Manually enter latitude/longitude coordinates
|
|
2. **Data Fetch**: Current weather and air quality data retrieved from Open-Meteo API
|
|
3. **Weather Comfort Scoring**: Algorithm calculates comfort based on temperature, humidity, cloud cover, wind, and precipitation
|
|
4. **Progression Selection**: Chooses appropriate chord progression based on weather mood
|
|
5. **Audio Generation**: All instruments and effects dynamically adjust to conditions
|
|
6. **Real-time Updates**: Audio parameters smoothly transition as weather changes
|
|
|
|
## Geolocation & Browser Compatibility
|
|
|
|
The app supports two methods for location input:
|
|
|
|
**Automatic Geolocation:**
|
|
- Requires HTTPS in production (localhost works without HTTPS)
|
|
- User must grant browser permission when prompted
|
|
- May not work on some mobile browsers or restrictive browser settings
|
|
|
|
**Manual Coordinate Entry:**
|
|
- Fallback option for when geolocation is unavailable
|
|
- Accepts latitude (-90 to 90) and longitude (-180 to 180)
|
|
- Works on all devices and browsers
|
|
- Useful for exploring weather from different locations
|
|
|
|
**Production Requirements:**
|
|
- Must be served over HTTPS for geolocation to work
|
|
- Development server uses `@vitejs/plugin-basic-ssl` for local HTTPS
|
|
|
|
## Mobile Experience
|
|
|
|
The application is optimized for mobile devices with several performance enhancements:
|
|
|
|
**Audio Playback:**
|
|
- Automatic audio context recovery after screen sleep/wake
|
|
- Handles browser audio suspension gracefully
|
|
- Transport automatically restarts when app becomes visible
|
|
|
|
**Visual Performance:**
|
|
- Adaptive particle count and framerate based on device
|
|
- Visualization pauses during scrolling to prevent stuttering
|
|
- Smaller canvas size for reduced GPU load
|
|
|
|
**Known Limitations:**
|
|
- Running both generators simultaneously may impact performance on lower-end devices
|
|
- Some mobile browsers may require user interaction to start audio playback
|
|
- Audio may briefly pause during heavy scrolling or multitasking
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
src/
|
|
├── lib/
|
|
│ ├── audio/
|
|
│ │ ├── instruments/ # Modular synth instruments
|
|
│ │ ├── audio-effects.ts # Shared audio effects
|
|
│ │ ├── chord-progressions.ts
|
|
│ │ └── weather-mood.ts # Comfort scoring & progression selection
|
|
│ ├── components/
|
|
│ │ └── AudioVisualization.svelte
|
|
│ └── generators/
|
|
│ ├── weather/WeatherGen.svelte
|
|
│ └── air-quality/AirQualityGen.svelte
|
|
└── routes/
|
|
├── +page.svelte # Geolocation entry point
|
|
└── on-out/+page.svelte # Audio generators
|
|
```
|
|
|
|
## Weather Mood Mapping
|
|
|
|
| Conditions | Progression | Characteristics |
|
|
|------------|-------------|-----------------|
|
|
| Stormy/Extreme | Tense | Dissonant, unsettling |
|
|
| Very Hot (30°C+) | Warm | Energetic, bright |
|
|
| Cold/Rainy | Melancholic | Somber, introspective |
|
|
| Foggy/Misty | Ethereal | Spacious, mysterious |
|
|
| Pleasant Day | Bright | Uplifting, major tonality |
|
|
| Pleasant Night | Dreamy | Calm, flowing |
|
|
|
|
## License
|
|
|
|
MIT
|