Skip to main content

getSoundState

Get a snapshot of everything a player UI needs about one sound: whether it plays, where it is, how long it runs, and its volume and pan. It is cheap enough to call every animation frame.

getSoundState(id: string): SoundStateInfo;

Parameters​

ParameterTypeDefaultDescription
idstringrequiredID of the sound, stream or overlapping instance.

Returns​

SoundStateInfo, an object with these fields:

FieldTypeDescription
stateSoundState'playing', 'paused' or 'stopped'.
progressnumberPosition in the file as a ratio from 0 to 1, rounded to 4 decimals.
currentTimenumberPosition in the file in seconds, whatever the playback rate.
elapsedTimenumberSame as currentTime.
adjustedElapsedTimenumberThe time it took to hear that far: elapsedTime divided by the playback rate.
durationnumberLength of the file in seconds.
rawDurationnumber | nullLength of the file in seconds.
startTimenumberWhile playing, the AudioContext time at which the file would have been at 0. For a stream, its startTime option.
playbackRatenumber | nullCurrent playback rate.
volumenumberVolume from 0 to 1.
pannumberStereo pan from -1 (left) to 1 (right).
panSpatialPosition{ x: number; y: number; z: number }Position in 3D space.

For an id that is not loaded you get a neutral stopped state: zeros for the times and progress, the configured default volume and playback rate, pan 0 and position 0, 0, 0.

Example​

import { SoundHub } from 'soundhub';

const soundHub = new SoundHub();
await soundHub.loadSound('music', '/audio/theme.mp3');

soundHub.play('music', { loop: true });

function render() {
const { state, currentTime, duration, progress } = soundHub.getSoundState('music');
label.textContent = `${state}: ${currentTime.toFixed(1)} / ${duration.toFixed(1)}s`;
seekBar.value = progress;
requestAnimationFrame(render);
}
render();

Try it​

Try it

Ask a sound where it is

Idle
isPlaying()false
isPaused()false
isStopped()true

Exactly one of the three is true at any moment. The values are read five times a second.

Code
Your clicks show up here as soundhub calls

Good to know​

  • A looping sound reports its position inside the file, so currentTime and progress wrap back to 0 on every loop.
  • Every time is in the file's own seconds, for buffered sounds and streams alike. Before 6.4.0 a buffered sound divided currentTime, elapsedTime and duration by the playback rate. For a stream, rawDuration is null when the length is not known, as for a live stream.
  • An unknown id does not throw, but the error is logged, stored for getLastError and dispatched as an error event.
  • The progress event from startProgressTracking carries this same object as event.state, so a listener does not have to poll.

See also​