A browser-based white noise generator and Fourier-style sine wave composer, built with pure HTML, CSS, and JavaScript. Designed to be wrapped as a standalone iOS/iPadOS app using Capacitor.
- White noise — flat spectral density, classic sleep/focus sound
- Brown noise — deeper, rumbling tone with rolled-off highs
- Play/pause and volume controls
- Runs on an
AudioWorkletProcessorfor glitch-free, off-main-thread audio - Uses cached media loops on iPhone/iPad for best-effort background and screen-off playback
- Lock Screen and Control Center play/pause controls where supported by iOS
- Up to 16 independent sine wave oscillators
- Per-oscillator frequency (20–4000 Hz) and amplitude sliders
- Real-time audio output while adjusting parameters
- Two visualization modes:
- Composite waveform — mathematically computed sum of all active sines
- FFT bar chart — live frequency-domain analysis via
AnalyserNode
- Full-screen digital clock overlay
- Adjustable brightness via CSS custom property
- Optional white, light pink, light purple, and light blue display colors
- Audio continues playing in the background
- Tap or press Escape to exit
| Layer | Technology |
|---|---|
| Audio | Web Audio API plus iOS HTMLAudioElement/Media Session fallback |
| Visuals | HTML5 Canvas (HiDPI-aware) |
| UI | Vanilla HTML/CSS/JS with ES modules |
| Dependencies | None — zero npm packages |
noisy/
├── assets/
│ └── audio/ ← Cached loopable white/brown noise for iOS
├── index.html ← App shell with tab navigation
├── package.json ← Dependency-free asset and test scripts
├── scripts/
│ └── generate-noise-assets.mjs ← Reproducible PCM WAV generator
├── css/
│ └── styles.css ← Dark theme, responsive layout, clock overlay
├── js/
│ ├── main.js ← Entry point, bootstraps all modules
│ ├── audio/
│ │ ├── audioEngine.js ← AudioContext singleton, master gain
│ │ ├── noiseGen.js ← Platform-aware noise playback controller
│ │ ├── noisePlatform.js ← iPhone/iPad backend selection
│ │ └── sineComposer.js ← 16 oscillators → AnalyserNode → master
│ ├── viz/
│ │ ├── waveform.js ← Computed composite sine waveform
│ │ └── fftBars.js ← Live FFT frequency bar chart
│ └── ui/
│ ├── noiseControls.js ← Noise play/pause, volume, type selector
│ ├── clockMode.js ← Night-mode clock with brightness
│ └── composerControls.js ← Sine slider grid, viz toggle
└── worklets/
└── noise-processor.js ← AudioWorkletProcessor (white + brown)
The app uses ES modules and AudioWorklet, which require a local HTTP server:
# Python
python -m http.server 8000
# or Node.js
npx serve .Then open http://localhost:8000.
Run the dependency-free test suite with:
npm testThe committed iOS noise loops can be regenerated deterministically:
npm run generate:noiseNoisy remains a website/PWA; it does not require TestFlight, Developer Mode, a Mac, or a paid Apple Developer account.
- Open the site in Safari and start noise with the Play button.
- To install it, tap Share → Add to Home Screen.
- When supported by the installed iOS version, noise continues after switching apps or locking the screen, with play/pause controls on the Lock Screen and in Control Center.
On iPhone/iPad, Noisy uses cached loopable media files instead of Web Audio because iOS gives normal media playback a better chance of continuing in the background. Apple does not guarantee background playback for websites or Home Screen PWAs, so iOS may still pause it. If standalone playback is interrupted, try running Noisy directly in Safari.
iOS does not allow websites to set media output volume programmatically. In the iPhone/iPad playback mode, use the device volume buttons or Control Center instead of the in-app volume slider.
- Pink noise — 1/f spectral slope, popular for masking
- Preset system — save and recall composer configurations (localStorage)
- Mix mode — play noise and sine composer simultaneously with independent volumes
- Timer / auto-stop — set a duration for noise playback (e.g., 30 min, 1 hr)
- Keyboard shortcuts — spacebar for play/pause, arrow keys for volume
- Additional waveform types — square, sawtooth, and triangle oscillators in the composer
- Envelope controls — attack/decay/sustain/release per oscillator for shaping tones
- Export audio — record the composed signal to WAV/MP3 via
MediaRecorder - Import/export presets — share composer configurations as JSON files
- Responsive canvas — debounced resize observer for smoother layout transitions
- Accessibility — ARIA labels, screen reader announcements, high-contrast theme
- Capacitor integration — wrap as a native app (
npx cap init→npx cap add ios) - Best-effort PWA background audio — cached media playback with Media Session controls
- Guaranteed native background audio — configure
UIBackgroundModesin a future Capacitor app - Haptic feedback — subtle haptics on button presses via Capacitor Haptics plugin
- App icon and splash screen — branded assets for the App Store
- Binaural beats — stereo oscillators with configurable frequency offset per ear
- Spatial audio — pan individual oscillators in the stereo field
- Microphone input — visualize live audio from the mic on the FFT display
- MIDI control — map MIDI CC knobs to oscillator parameters
- Shareable URLs — encode composer state in URL hash for instant sharing
This is a personal project, but issues and PRs are welcome. Keep it dependency-free — the goal is a single static site that runs anywhere.
MIT