Building a Browser-Based Acoustic Vehicle Alerting System (AVAS) with Web Audio and Geolocation APIs
The Engineering Challenge: Silent Mobility
Electric micro-mobility (scooters, e-bikes) suffers from a critical safety flaw: silence. Pedestrians rely on auditory cues to detect approaching vehicles. In the automotive industry, this is solved by an Acoustic Vehicle Alerting System (AVAS)—hardware that emits synthetic engine noise at low speeds.
I sought to replicate this safety feature using only a smartphone and a web browser, avoiding the friction of app store approvals and proprietary hardware.
Technical Implementation
The solution leverages two powerful browser APIs:
- Geolocation API: To derive real-time velocity.
- Web Audio API: To synthesize dynamic audio based on that velocity.
Real-Time Velocity Tracking
The navigator.geolocation.watchPosition() method provides a continuous stream of location data. Crucially, the position.coords.speed attribute returns the device's speed in meters per second, which serves as the primary control signal for our audio synthesis.
navigator.geolocation.watchPosition(
(position) => {
const speedMs = position.coords.speed || 0;
updateAudioEngine(speedMs);
},
(error) => console.error("Geolocation error:", error),
{enableHighAccuracy: true}
);Audio Synthesis Engine
Instead of playing back a static audio file, we synthesize sound in real-time to create a dynamic, responsive experience. The Web Audio API allows us to build an audio graph where nodes (oscillators, gain, filters) are connected to shape the sound.
The Signal Chain
- Source: An
OscillatorNode(sine/square wave) or a generated noise buffer (pink noise). - Filter: A
BiquadFilterNodeto sculpt the frequency content. - Gain: A
GainNodeto control amplitude.
const audioContext = new AudioContext();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);Mapping Speed to Sound
To create a convincing engine sound, we map the input velocity to audio parameters. As speed increases, both pitch ( frequency) and volume (gain) must rise.
Crucially, we use linearRampToValueAtTime to smooth the transitions. Direct parameter updates cause audible clicking artifacts (zipper noise).
const updateAudioEngine = (speed) => {
const newVolume = Math.min(1.0, BASE_VOL + (speed * VOL_SENSITIVITY));
const newFreq = Math.min(MAX_FREQ, BASE_FREQ + (speed * PITCH_SENSITIVITY));
// Smooth transition over 0.1 seconds
gainNode.gain.linearRampToValueAtTime(newVolume, audioContext.currentTime + 0.1);
oscillator.frequency.linearRampToValueAtTime(newFreq, audioContext.currentTime + 0.1);
};Advanced Synthesis: Pink Noise & Filtering
Pure tones are difficult for the human ear to localize. To improve safety, I implemented a Pink Noise generator. Pink noise has equal energy per octave, making it sound more natural and "full" than white noise.
By passing pink noise through a bandpass filter and modulating the filter's frequency based on speed, we achieve a " whooshing" effect similar to modern EVs (like the Porsche Taycan or Audi e-tron).
Deployment & Security
Deploying this as a web app requires handling browser security policies:
- HTTPS: The Geolocation API is restricted to secure contexts.
- Permissions Policy: When embedded in an
iframe, the parent page must explicitly delegate permission.
<iframe src="/html/avas.html" allow="geolocation" ...></iframe>Live Demo
You can test the AVAS system below. Use the "Manual Speed" slider to simulate movement if you are stationary.
Conclusion
This project demonstrates the maturity of modern web APIs. We successfully built a safety-critical, real-time application entirely within the browser, proving that web technologies can bridge the gap between software and the physical world.

