
Threejs Impl Audio
- 18 installs
- 11 repo stars
- Updated July 8, 2026
- openaec-foundation/three.js-claude-skill-package
Helps with ai & agent building tasks.
About
threejs-impl-audio is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- threejs-impl-audio
- AI & Agent Building
- AI-coding skill
Threejs Impl Audio by the numbers
- 18 all-time installs (skills.sh)
- +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #10,710 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/three.js-claude-skill-package --skill threejs-impl-audioAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 18 |
|---|---|
| repo stars | ★ 11 |
| Last updated | July 8, 2026 |
| Repository | openaec-foundation/three.js-claude-skill-package ↗ |
What it does
Helps with ai & agent building tasks.
Files
threejs-impl-audio
Quick Reference
Class Hierarchy
EventDispatcher
└── Object3D
├── AudioListener (receiver — attach to camera)
├── Audio (non-positional — background music, UI sounds)
└── PositionalAudio (3D spatial — attached to scene objects)Supporting classes:
AudioLoader— loads audio files intoAudioBufferAudioAnalyser— real-time frequency analysis for visualization
Architecture Overview
| Component | Role | Attach To |
|---|---|---|
AudioListener | Virtual ear (Web Audio API destination) | Camera (ALWAYS) |
Audio | Non-positional sound (same volume everywhere) | Any Object3D or scene |
PositionalAudio | 3D spatial sound (volume depends on distance) | Mesh or Object3D in scene |
AudioLoader | Async audio file loader | N/A (utility) |
AudioAnalyser | FFT frequency data extractor | Wraps an Audio instance |
Critical Warnings
NEVER call sound.play() without first ensuring the AudioContext is resumed after user interaction. Modern browsers ALWAYS suspend the AudioContext until a user gesture (click, tap, keypress) occurs.
NEVER create more than one AudioListener per scene. Multiple listeners produce undefined spatialization behavior.
NEVER set autoplay = true and expect playback without user interaction. The browser WILL block it silently.
ALWAYS attach the AudioListener to the camera. If attached to another object, spatial audio calculations use the wrong reference position.
ALWAYS call listener.context.resume() inside a user interaction handler before playing any audio.
NEVER forget to handle the onError callback in AudioLoader.load(). Missing audio files fail silently without error handling.
---
AudioListener Setup
The AudioListener is the scene's virtual microphone. It wraps the Web Audio API's AudioContext and AudioDestinationNode.
import * as THREE from 'three';
const listener = new THREE.AudioListener();
camera.add( listener ); // ALWAYS add to cameraMaster Volume Control
listener.setMasterVolume( 0.8 ); // range [0, 1]
const vol = listener.getMasterVolume(); // returns 0.8Global Audio Filter
const filter = listener.context.createBiquadFilter();
filter.type = 'lowpass';
filter.frequency.value = 1000;
listener.setFilter( filter );
// Later: listener.removeFilter();---
Audio (Non-Positional)
Use Audio for background music, ambient soundscapes, and UI feedback sounds. Volume is identical regardless of listener position.
Loading and Playing
const sound = new THREE.Audio( listener );
const audioLoader = new THREE.AudioLoader();
audioLoader.load( 'music.mp3', ( buffer ) => {
sound.setBuffer( buffer );
sound.setLoop( true );
sound.setVolume( 0.5 );
// Do NOT call sound.play() here — wait for user interaction
});Autoplay Policy Compliance (MANDATORY)
document.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
if ( !sound.isPlaying ) {
sound.play();
}
}, { once: true } );Playback Control
sound.play(); // start playback
sound.pause(); // pause (resume with play())
sound.stop(); // stop and reset to beginning
sound.setPlaybackRate( 1.5 ); // 1.5x speed
sound.setDetune( -100 ); // pitch down 1 semitone (100 cents)Alternative Sources
// HTML5 media element (for streaming large files)
const audioEl = new Audio( 'long-track.mp3' );
sound.setMediaElementSource( audioEl );
// Microphone input
navigator.mediaDevices.getUserMedia( { audio: true } ).then( ( stream ) => {
sound.setMediaStreamSource( stream );
});---
PositionalAudio (3D Spatial)
Use PositionalAudio for sounds that exist at a location in the scene. Volume and stereo panning change based on the listener's distance and orientation.
Basic Setup
const positionalSound = new THREE.PositionalAudio( listener );
audioLoader.load( 'engine.ogg', ( buffer ) => {
positionalSound.setBuffer( buffer );
positionalSound.setRefDistance( 20 );
positionalSound.setRolloffFactor( 1 );
positionalSound.setDistanceModel( 'inverse' );
positionalSound.setLoop( true );
positionalSound.setVolume( 0.5 );
});
mesh.add( positionalSound ); // sound position follows the meshDistance Model Decision Tree
| Model | When to Use | Behavior |
|---|---|---|
'inverse' (default) | Realistic environments | Gradual rolloff; NEVER reaches zero |
'linear' | Controlled radius (e.g., room-based) | Volume drops to zero at maxDistance |
'exponential' | Dramatic close/far contrast | Steep falloff curve |
Choosing parameters:
- `refDistance` — Distance at which volume is 100%. Set to the "comfortable listening range" in scene units. Typical:
1to20. - `maxDistance` — ONLY matters for
'linear'model. Ignored by'inverse'and'exponential'. - `rolloffFactor` — Speed of volume decrease. For
'inverse':1= realistic. For'linear':1= full range. Higher values = faster rolloff.
Directional Audio Cone
positionalSound.setDirectionalCone( 180, 360, 0.1 );
// coneInnerAngle: 180° — full volume zone
// coneOuterAngle: 360° — transition zone
// coneOuterGain: 0.1 — volume outside outer cone (10%)---
AudioLoader
ALWAYS use AudioLoader to load audio files. It returns an AudioBuffer via callback.
const loader = new THREE.AudioLoader();
loader.load(
'sound.ogg',
( buffer ) => { sound.setBuffer( buffer ); }, // onLoad
( xhr ) => { console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); }, // onProgress
( err ) => { console.error( 'Audio load failed:', err ); } // onError — ALWAYS handle
);Supported formats: MP3, OGG, WAV, AAC. OGG has the best compression-to-quality ratio but is NOT supported in Safari. ALWAYS provide MP3 as a fallback for cross-browser compatibility.
---
AudioAnalyser
Wraps the Web Audio API's AnalyserNode for real-time frequency visualization.
const analyser = new THREE.AudioAnalyser( sound, 256 );
// fftSize MUST be a power of 2: 32, 64, 128, 256, 512, 1024, 2048
function animate() {
requestAnimationFrame( animate );
const data = analyser.getFrequencyData(); // Uint8Array, length = fftSize / 2
const avg = analyser.getAverageFrequency(); // number (0-255)
// Drive visuals from audio data
mesh.scale.y = 1 + avg / 128;
renderer.render( scene, camera );
}Frequency Data Details
getFrequencyData()returns aUint8ArraywithfftSize / 2elements- Each element ranges from
0to255(decibel magnitude) - Index
0= lowest frequency, last index = highest frequency getAverageFrequency()returns the arithmetic mean of all bins
---
Integration Checklist
1. Create ONE AudioListener and add it to the camera 2. Create Audio or PositionalAudio with the listener 3. Load audio with AudioLoader 4. Set buffer, volume, loop, and distance properties 5. Add user interaction handler to resume AudioContext 6. Call play() ONLY after user interaction 7. For spatial audio: add PositionalAudio as child of the target mesh
---
Reference Links
- references/methods.md -- Complete API signatures for AudioListener, Audio, PositionalAudio, AudioLoader, AudioAnalyser
- references/examples.md -- Working code examples for common audio scenarios
- references/anti-patterns.md -- What NOT to do with Three.js audio
Official Sources
- https://threejs.org/docs/#api/en/audio/AudioListener
- https://threejs.org/docs/#api/en/audio/Audio
- https://threejs.org/docs/#api/en/audio/PositionalAudio
- https://threejs.org/docs/#api/en/audio/AudioAnalyser
- https://threejs.org/docs/#api/en/loaders/AudioLoader
threejs-impl-audio — Anti-Patterns
What NOT to do with Three.js audio. Each anti-pattern includes the mistake, why it fails, and the correct approach.
---
AP-1: Playing Audio Without User Interaction
Wrong
const sound = new THREE.Audio( listener );
audioLoader.load( 'music.mp3', ( buffer ) => {
sound.setBuffer( buffer );
sound.play(); // FAILS silently — AudioContext is suspended
});Why It Fails
Modern browsers (Chrome, Firefox, Safari) enforce autoplay policies. The AudioContext starts in a 'suspended' state and WILL NOT process audio until a user gesture (click, tap, keypress) activates it. Calling play() on a suspended context does nothing — no error is thrown, audio simply does not play.
Correct
audioLoader.load( 'music.mp3', ( buffer ) => {
sound.setBuffer( buffer );
});
document.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
if ( !sound.isPlaying ) {
sound.play();
}
}, { once: true } );---
AP-2: Forgetting to Attach AudioListener to Camera
Wrong
const listener = new THREE.AudioListener();
// listener is never added to the scene graph
const positionalSound = new THREE.PositionalAudio( listener );
mesh.add( positionalSound );Why It Fails
The AudioListener derives its world position and orientation from its parent in the scene graph. Without being attached to the camera (or any Object3D in the scene), the listener stays at the origin with no orientation updates. Spatial audio panning and distance calculations produce incorrect results — sounds do not respond to camera movement.
Correct
const listener = new THREE.AudioListener();
camera.add( listener ); // ALWAYS add to camera---
AP-3: Creating Multiple AudioListeners
Wrong
const listener1 = new THREE.AudioListener();
const listener2 = new THREE.AudioListener();
camera.add( listener1 );
camera.add( listener2 );
const music = new THREE.Audio( listener1 );
const sfx = new THREE.Audio( listener2 );Why It Fails
Each AudioListener creates its own AudioContext. The Web Audio API uses a single audio destination per context. Multiple listeners mean multiple independent audio graphs with separate timing, volume, and spatial processing. This wastes resources and produces unpredictable behavior — particularly for spatial audio where only ONE listener position makes physical sense.
Correct
const listener = new THREE.AudioListener();
camera.add( listener );
const music = new THREE.Audio( listener ); // shares same listener
const sfx = new THREE.Audio( listener ); // shares same listener
const spatial = new THREE.PositionalAudio( listener ); // shares same listener---
AP-4: Using autoplay Without Interaction Handler
Wrong
const sound = new THREE.Audio( listener );
sound.autoplay = true; // will be blocked by browser
audioLoader.load( 'music.mp3', ( buffer ) => {
sound.setBuffer( buffer ); // autoplay triggers here — but AudioContext is suspended
});Why It Fails
Setting autoplay = true causes play() to be called automatically when setBuffer() is invoked. However, if the AudioContext is still suspended (no user interaction has occurred), the play request is silently ignored. The autoplay property does NOT bypass browser autoplay policies.
Correct
const sound = new THREE.Audio( listener );
// Do NOT use autoplay — explicitly play after user interaction
audioLoader.load( 'music.mp3', ( buffer ) => {
sound.setBuffer( buffer );
sound.setLoop( true );
});
document.addEventListener( 'click', () => {
listener.context.resume().then( () => {
sound.play();
});
}, { once: true } );---
AP-5: Wrong Distance Model for the Use Case
Wrong
const sound = new THREE.PositionalAudio( listener );
sound.setDistanceModel( 'inverse' );
sound.setMaxDistance( 50 ); // maxDistance has NO effect with 'inverse' modelWhy It Fails
The maxDistance parameter is ONLY used by the 'linear' distance model. For 'inverse' and 'exponential' models, sound attenuates based on refDistance and rolloffFactor but NEVER reaches zero — maxDistance is completely ignored. Developers who set maxDistance expecting a cutoff radius with the 'inverse' model will hear sound at arbitrary distances.
Correct
// Option A: Use 'linear' if you need a hard cutoff
sound.setDistanceModel( 'linear' );
sound.setRefDistance( 1 );
sound.setMaxDistance( 50 ); // sound reaches zero at 50 units
sound.setRolloffFactor( 1 );
// Option B: Use 'inverse' with appropriate rolloffFactor for natural falloff
sound.setDistanceModel( 'inverse' );
sound.setRefDistance( 5 ); // full volume within 5 units
sound.setRolloffFactor( 2 ); // higher = faster falloff (but never zero)---
AP-6: Not Handling Audio Load Errors
Wrong
audioLoader.load( 'sound.ogg', ( buffer ) => {
sound.setBuffer( buffer );
sound.play();
});
// No error callback — if file is missing, fails silentlyWhy It Fails
AudioLoader.load() fails silently when the file is missing, the URL is wrong, or the server returns an error. Without an onError callback, the application has no way to detect the failure, display a fallback, or inform the user. The sound.buffer remains null, and calling play() on a sound with no buffer throws a runtime error.
Correct
audioLoader.load(
'sound.ogg',
( buffer ) => {
sound.setBuffer( buffer );
},
undefined, // onProgress (optional)
( err ) => {
console.error( 'Failed to load audio:', err );
// Fallback: try alternative format, show UI message, etc.
}
);---
AP-7: Calling play() on an Already Playing Sound
Wrong
document.addEventListener( 'click', () => {
sound.play(); // Called on EVERY click — error on second click
});Why It Fails
Calling play() on an Audio instance that is already playing throws an error or causes the sound to restart abruptly. Three.js creates a new AudioBufferSourceNode on each play() call, and attempting to start a new source while the previous one is active produces undefined behavior.
Correct
document.addEventListener( 'click', () => {
if ( !sound.isPlaying ) {
sound.play();
}
});---
AP-8: Using setMediaElementSource and Then Calling sound.play()
Wrong
const audioEl = document.createElement( 'audio' );
audioEl.src = 'podcast.mp3';
const sound = new THREE.Audio( listener );
sound.setMediaElementSource( audioEl );
sound.play(); // Does NOT work as expectedWhy It Fails
When using setMediaElementSource(), the Three.js Audio object wraps an HTML5 media element — it does NOT create an AudioBufferSourceNode. Playback MUST be controlled through the HTML element (audioEl.play(), audioEl.pause()), not through sound.play(). The sound.play() method attempts to create and start a buffer source node, which conflicts with the media element source.
Correct
const audioEl = document.createElement( 'audio' );
audioEl.src = 'podcast.mp3';
audioEl.crossOrigin = 'anonymous';
const sound = new THREE.Audio( listener );
sound.setMediaElementSource( audioEl );
sound.setVolume( 0.5 ); // volume control works through Three.js
// Control playback via the HTML element
document.addEventListener( 'click', () => {
listener.context.resume();
audioEl.play(); // use the HTML element's play()
}, { once: true } );threejs-impl-audio — Examples
Working code examples for Three.js audio (r160+). All examples use ES module imports.
---
Example 1: Background Music with Autoplay Policy
Non-positional audio that loops background music, correctly handling the browser autoplay policy.
import * as THREE from 'three';
// Scene setup (assumes scene, camera, renderer exist)
const listener = new THREE.AudioListener();
camera.add( listener );
const backgroundMusic = new THREE.Audio( listener );
const audioLoader = new THREE.AudioLoader();
audioLoader.load( 'assets/music.mp3', ( buffer ) => {
backgroundMusic.setBuffer( buffer );
backgroundMusic.setLoop( true );
backgroundMusic.setVolume( 0.3 );
});
// MANDATORY: Resume AudioContext on user interaction
const startButton = document.getElementById( 'start' );
startButton.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
if ( !backgroundMusic.isPlaying ) {
backgroundMusic.play();
}
startButton.style.display = 'none';
}, { once: true } );---
Example 2: 3D Positional Audio on a Mesh
A sound source attached to a mesh. Volume and panning change as the camera moves.
import * as THREE from 'three';
const listener = new THREE.AudioListener();
camera.add( listener );
const audioLoader = new THREE.AudioLoader();
// Create a visible object with a sound
const geometry = new THREE.SphereGeometry( 1, 32, 32 );
const material = new THREE.MeshStandardMaterial( { color: 0xff6600 } );
const speaker = new THREE.Mesh( geometry, material );
speaker.position.set( 10, 2, 0 );
scene.add( speaker );
// Attach positional audio to the mesh
const engineSound = new THREE.PositionalAudio( listener );
audioLoader.load( 'assets/engine.ogg', ( buffer ) => {
engineSound.setBuffer( buffer );
engineSound.setRefDistance( 5 );
engineSound.setMaxDistance( 100 );
engineSound.setRolloffFactor( 1 );
engineSound.setDistanceModel( 'inverse' );
engineSound.setLoop( true );
engineSound.setVolume( 0.8 );
});
speaker.add( engineSound ); // sound position = mesh position
// Resume context on interaction
document.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
if ( !engineSound.isPlaying ) {
engineSound.play();
}
}, { once: true } );---
Example 3: Audio Visualization with AudioAnalyser
Drive visual elements from real-time audio frequency data.
import * as THREE from 'three';
const listener = new THREE.AudioListener();
camera.add( listener );
const sound = new THREE.Audio( listener );
const audioLoader = new THREE.AudioLoader();
const analyser = new THREE.AudioAnalyser( sound, 256 );
audioLoader.load( 'assets/beat.mp3', ( buffer ) => {
sound.setBuffer( buffer );
sound.setLoop( true );
});
// Create bar visualization (128 bars = fftSize / 2)
const bars = [];
const barCount = 128;
const barGeometry = new THREE.BoxGeometry( 0.1, 1, 0.1 );
const barMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff88 } );
for ( let i = 0; i < barCount; i++ ) {
const bar = new THREE.Mesh( barGeometry, barMaterial );
bar.position.x = ( i - barCount / 2 ) * 0.15;
scene.add( bar );
bars.push( bar );
}
// Start audio on user interaction
document.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
if ( !sound.isPlaying ) {
sound.play();
}
}, { once: true } );
// Animation loop — update bars from frequency data
function animate() {
requestAnimationFrame( animate );
const data = analyser.getFrequencyData();
for ( let i = 0; i < barCount; i++ ) {
const value = data[ i ] / 255; // normalize to [0, 1]
bars[ i ].scale.y = 0.1 + value * 5; // minimum height + scaled
bars[ i ].position.y = bars[ i ].scale.y / 2; // keep bottom at y=0
}
renderer.render( scene, camera );
}
animate();---
Example 4: Multiple Sound Sources with Shared Listener
A scene with background music and multiple positional sounds.
import * as THREE from 'three';
const listener = new THREE.AudioListener();
camera.add( listener );
const audioLoader = new THREE.AudioLoader();
// Background music (non-positional)
const bgMusic = new THREE.Audio( listener );
audioLoader.load( 'assets/ambient.mp3', ( buffer ) => {
bgMusic.setBuffer( buffer );
bgMusic.setLoop( true );
bgMusic.setVolume( 0.2 );
});
// Waterfall sound (positional)
const waterfallSound = new THREE.PositionalAudio( listener );
audioLoader.load( 'assets/waterfall.ogg', ( buffer ) => {
waterfallSound.setBuffer( buffer );
waterfallSound.setRefDistance( 10 );
waterfallSound.setRolloffFactor( 1.5 );
waterfallSound.setDistanceModel( 'inverse' );
waterfallSound.setLoop( true );
waterfallSound.setVolume( 0.7 );
});
waterfallMesh.add( waterfallSound );
// Bird sound (positional, directional cone)
const birdSound = new THREE.PositionalAudio( listener );
audioLoader.load( 'assets/birdsong.ogg', ( buffer ) => {
birdSound.setBuffer( buffer );
birdSound.setRefDistance( 5 );
birdSound.setRolloffFactor( 2 );
birdSound.setDistanceModel( 'exponential' );
birdSound.setDirectionalCone( 120, 230, 0.2 );
birdSound.setLoop( true );
birdSound.setVolume( 0.5 );
});
birdMesh.add( birdSound );
// Single interaction handler for all sounds
document.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
if ( !bgMusic.isPlaying ) bgMusic.play();
if ( !waterfallSound.isPlaying ) waterfallSound.play();
if ( !birdSound.isPlaying ) birdSound.play();
}, { once: true } );---
Example 5: HTML5 Media Element Source (Streaming)
Use an HTML5 <audio> element for large files that should stream rather than fully preload.
import * as THREE from 'three';
const listener = new THREE.AudioListener();
camera.add( listener );
// Create HTML5 audio element
const audioElement = document.createElement( 'audio' );
audioElement.src = 'assets/long-podcast.mp3';
audioElement.crossOrigin = 'anonymous'; // REQUIRED for cross-origin audio
// Wrap in Three.js Audio
const sound = new THREE.Audio( listener );
sound.setMediaElementSource( audioElement );
sound.setVolume( 0.6 );
// Play on user interaction
document.addEventListener( 'click', () => {
if ( listener.context.state === 'suspended' ) {
listener.context.resume();
}
audioElement.play(); // use the HTML element's play() for media element sources
}, { once: true } );Key difference: When using setMediaElementSource(), control playback via the HTML element (audioElement.play(), audioElement.pause()), NOT via sound.play(). The Three.js Audio object acts as a pass-through for volume and filters only.
threejs-impl-audio — Method Reference
Complete API signatures for Three.js audio classes (r160+).
---
AudioListener
Extends Object3D. The scene's virtual ear — wraps the Web Audio API AudioContext.
Constructor
new AudioListener()Creates a new listener with its own AudioContext.
Properties
| Property | Type | Access | Description |
|---|---|---|---|
.context | AudioContext | readonly | The native Web Audio API context |
.gain | GainNode | readonly | Master volume control node |
.filter | `AudioNode \ | null` | read/write |
.timeDelta | number | readonly | Time delta for audio operations |
Methods
| Method | Returns | Description |
|---|---|---|
.getMasterVolume() | number | Returns current master volume |
.setMasterVolume( value: number ) | AudioListener | Sets master volume; range [0, 1] |
.getFilter() | AudioNode | Returns current filter node |
.setFilter( filter: AudioNode ) | AudioListener | Applies a global audio filter |
.removeFilter() | AudioListener | Removes the current filter |
.getInput() | GainNode | Returns the listener's input gain node |
---
Audio
Extends Object3D. Non-positional audio source — volume is constant regardless of listener position.
Constructor
new Audio( listener: AudioListener )| Parameter | Type | Required | Description |
|---|---|---|---|
listener | AudioListener | YES | The scene's audio listener |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
.buffer | `AudioBuffer \ | null` | null |
.context | AudioContext | — | Web Audio context (readonly) |
.gain | GainNode | — | Volume control node (readonly) |
.isPlaying | boolean | false | Current playback state (readonly) |
.source | `AudioBufferSourceNode \ | null` | null |
.autoplay | boolean | false | Auto-play when buffer is set |
.loop | boolean | false | Loop playback |
.loopStart | number | 0 | Loop region start (seconds) |
.loopEnd | number | 0 | Loop region end (seconds); 0 = end of buffer |
.offset | number | 0 | Playback start offset (seconds) |
.playbackRate | number | 1 | Speed multiplier |
.detune | number | 0 | Pitch shift in cents (100 cents = 1 semitone) |
.duration | `number \ | undefined` | — |
.filters | AudioNode[] | [] | Applied audio filter chain |
Methods
| Method | Returns | Description |
|---|---|---|
.play( delay?: number ) | Audio | Start playback; optional delay in seconds |
.pause() | Audio | Pause playback (resume with .play()) |
.stop() | Audio | Stop and reset to beginning |
.setBuffer( buffer: AudioBuffer ) | Audio | Set audio data from AudioLoader |
.setMediaElementSource( el: HTMLMediaElement ) | Audio | Use HTML5 <audio> or <video> element as source |
.setMediaStreamSource( stream: MediaStream ) | Audio | Use live media stream (microphone) as source |
.setNodeSource( node: AudioScheduledSourceNode ) | Audio | Use custom Web Audio source node |
.setVolume( value: number ) | Audio | Set volume; range [0, 1] |
.getVolume() | number | Get current volume |
.setPlaybackRate( value: number ) | Audio | Set playback speed multiplier |
.getPlaybackRate() | number | Get current playback speed |
.setDetune( value: number ) | Audio | Set pitch shift in cents |
.getDetune() | number | Get current pitch shift |
.setLoop( value: boolean ) | Audio | Enable or disable looping |
.getLoop() | boolean | Get current loop state |
.setLoopStart( value: number ) | Audio | Set loop start point (seconds) |
.setLoopEnd( value: number ) | Audio | Set loop end point (seconds) |
.setFilters( filters: AudioNode[] ) | Audio | Apply a chain of audio filters |
.getFilters() | AudioNode[] | Get the current filter chain |
.setFilter( filter: AudioNode ) | Audio | Set a single filter (shorthand) |
.getFilter() | AudioNode | Get the first filter |
.getOutput() | GainNode | Get the output gain node |
.connect() | Audio | Connect to audio destination |
.disconnect() | Audio | Disconnect from audio destination |
---
PositionalAudio
Extends Audio. 3D spatial audio — volume and panning depend on listener distance and orientation.
Constructor
new PositionalAudio( listener: AudioListener )| Parameter | Type | Required | Description |
|---|---|---|---|
listener | AudioListener | YES | The scene's audio listener |
Properties
| Property | Type | Description |
|---|---|---|
.panner | PannerNode | The Web Audio PannerNode controlling 3D spatialization (readonly) |
Inherits ALL properties from Audio.
Methods (Own)
| Method | Returns | Description |
|---|---|---|
.getDistanceModel() | string | Returns 'linear', 'inverse', or 'exponential' |
.setDistanceModel( model: string ) | PositionalAudio | Set distance attenuation algorithm |
.getRefDistance() | number | Get reference distance |
.setRefDistance( value: number ) | PositionalAudio | Set reference distance (where volume = 100%) |
.getMaxDistance() | number | Get maximum distance |
.setMaxDistance( value: number ) | PositionalAudio | Set max distance (only affects 'linear' model) |
.getRolloffFactor() | number | Get rolloff factor |
.setRolloffFactor( value: number ) | PositionalAudio | Set rate of volume decrease with distance |
.setDirectionalCone( coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number ) | PositionalAudio | Define directional audio cone |
.getOutput() | PannerNode | Returns the PannerNode (overrides Audio.getOutput) |
Distance Model Formulas
| Model | Formula | Notes |
|---|---|---|
'inverse' | refDistance / (refDistance + rolloffFactor * (distance - refDistance)) | Default; NEVER reaches zero |
'linear' | 1 - rolloffFactor * (distance - refDistance) / (maxDistance - refDistance) | Reaches zero at maxDistance |
'exponential' | (distance / refDistance) ^ -rolloffFactor | Steep falloff |
---
AudioLoader
Extends Loader. Loads audio files into AudioBuffer objects.
Constructor
new AudioLoader( manager?: LoadingManager )| Parameter | Type | Required | Description |
|---|---|---|---|
manager | LoadingManager | NO | Optional loading manager |
Methods
| Method | Returns | Description |
|---|---|---|
.load( url: string, onLoad?: ( buffer: AudioBuffer ) => void, onProgress?: ( event: ProgressEvent ) => void, onError?: ( err: Error ) => void ) | void | Load audio file asynchronously |
.loadAsync( url: string, onProgress?: ( event: ProgressEvent ) => void ) | Promise<AudioBuffer> | Promise-based load |
---
AudioAnalyser
Wraps AnalyserNode for real-time frequency analysis.
Constructor
new AudioAnalyser( audio: Audio, fftSize?: number )| Parameter | Type | Default | Description |
|---|---|---|---|
audio | Audio | — | The Audio or PositionalAudio to analyze (REQUIRED) |
fftSize | number | 2048 | FFT window size; MUST be power of 2 |
Properties
| Property | Type | Description |
|---|---|---|
.analyser | AnalyserNode | The underlying Web Audio AnalyserNode |
.data | Uint8Array | Reusable buffer for frequency data |
Methods
| Method | Returns | Description |
|---|---|---|
.getFrequencyData() | Uint8Array | Frequency domain data (0-255 per bin); length = fftSize / 2 |
.getAverageFrequency() | number | Arithmetic mean of all frequency bins |