Options
All
  • Public
  • Public/Protected
  • All
Menu

A helper class to provide common functionality for working with the Web Audio API. https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API A singleton instance of this class is available as game#audio.

see

Game#audio

Hierarchy

  • AudioHelper

Index

Constructors

Properties

context: AudioContext

The primary Audio Context used to play client-facing sounds. The context is undefined until the user's first gesture is observed.

buffers: Map<string, { buffer: AudioBuffer; lastAccessed: number; playing: boolean; size: number }>

The set of AudioBuffer objects which are cached for different audio paths

sounds: Map<string, Sound>

The set of singleton Sound instances which are cached for different audio paths

playing: Map<number, Sound>

Get a map of the Sound objects which are currently playing.

pending: Function[]

A user gesture must be registered before audio can be played. This Array contains the Sound instances which are requested for playback prior to a gesture. Once a gesture is observed, we begin playing all elements of this Array.

see

Sound

locked: boolean

A flag for whether video playback is currently locked by awaiting a user gesture

unlock: Promise<AudioContext>

A Promise which resolves once the game audio API is unlocked and ready to use.

#cacheSize: number = 0

An internal tracker for the total size of the buffers cache.

levelAnalyserNativeInterval: number = 50

The Native interval for the AudioHelper to analyse audio levels from streams Any interval passed to startLevelReports() would need to be a multiple of this value.

THRESHOLD_CACHE_SIZE_BYTES: number = ...

The cache size threshold after which audio buffers will be expired from the cache to make more room. 1 gigabyte, by default.

Methods

  • create(options?: { src: string; singleton: boolean; preload: boolean; autoplay: boolean; autoplayOptions: any }): Sound
  • Create a Sound instance for a given audio source URL

    Parameters

    • options: { src: string; singleton: boolean; preload: boolean; autoplay: boolean; autoplayOptions: any } = {}

      Audio creation options

      • src: string

        The source URL for the audio file

      • singleton: boolean
      • preload: boolean
      • autoplay: boolean
      • autoplayOptions: any

    Returns Sound

  • play(src: string, options: any): Promise<Sound>
  • Play a single Sound by providing its source.

    Parameters

    • src: string

      The file path to the audio source being played

    • options: any

    Returns Promise<Sound>

    The created Sound which is now playing

  • awaitFirstGesture(): Promise<AudioContext>
  • Register an event listener to await the first mousemove gesture and begin playback once observed.

    Returns Promise<AudioContext>

    The unlocked audio context

  • preload(src: string): Promise<Sound>
  • Request that other connected clients begin preloading a certain sound path.

    Parameters

    • src: string

      The source file path requested for preload

    Returns Promise<Sound>

    A Promise which resolves once the preload is complete

  • getCache(src: string): AudioBuffer
  • Retrieve an AudioBuffer from the buffers cache, if it is available

    Parameters

    • src: string

      The buffer audio source path

    Returns AudioBuffer

    The AudioBuffer instance if cached, otherwise undefined

  • updateCache(src: string, playing?: boolean): void
  • Update the last accessed time and playing status of a cached buffer.

    Parameters

    • src: string

      The buffer audio source path

    • playing: boolean = false

      Is the buffer currently playing?

    Returns void

  • setCache(src: string, buffer: AudioBuffer): number
  • getAudioContext(): AudioContext
  • Returns a singleton AudioContext if one can be created. An audio context may not be available due to limited resources or browser compatibility in which case null will be returned

    Returns AudioContext

    A singleton AudioContext or null if one is not available

  • startLevelReports(id: string, stream: MediaStream, callback: Function, interval?: number, smoothing?: number): boolean
  • Registers a stream for periodic reports of audio levels. Once added, the callback will be called with the maximum decibel level of the audio tracks in that stream since the last time the event was fired. The interval needs to be a multiple of AudioHelper.levelAnalyserNativeInterval which defaults at 50ms

    Parameters

    • id: string

      An id to assign to this report. Can be used to stop reports

    • stream: MediaStream

      The MediaStream instance to report activity on.

    • callback: Function

      The callback function to call with the decibel level. callback(dbLevel)

    • interval: number = 50

      (optional) The interval at which to produce reports.

    • smoothing: number = 0.1

      (optional) The smoothingTimeConstant to set on the audio analyser. Refer to AudioAnalyser API docs.

    Returns boolean

    Returns whether or not listening to the stream was successful

  • stopLevelReports(id: string): void
  • Stop sending audio level reports This stops listening to a stream and stops sending reports. If we aren't listening to any more streams, cancel the global analyser timer.

    Parameters

    • id: string

      The id of the reports that passed to startLevelReports.

    Returns void

  • #expireCache(): void
  • Expire buffers from the cache when the total cache size exceeds a specified threshold. Buffers which were least recently accessed are removed first, provided they are not currently playing.

    Returns void

  • _ensureAnalyserTimer(): void
  • Ensures the global analyser timer is started

    We create only one timer that runs every 50ms and only create it if needed, this is meant to optimize things and avoid having multiple timers running if we want to analyse multiple streams at the same time. I don't know if it actually helps much with performance but it's expected that limiting the number of timers running at the same time is good practice and with JS itself, there's a potential for a timer congestion phenomenon if too many are created.

    Returns void

  • _cancelAnalyserTimer(): void
  • Cancel the global analyser timer If the timer is running and has become unnecessary, stops it.

    Returns void

  • _emitVolumes(): void
  • Capture audio level for all speakers and emit a webrtcVolumes custom event with all the volume levels detected since the last emit. The event's detail is in the form of {userId: decibelLevel}

    Returns void

  • _onFirstGesture(event: Event, resolve: Function): any
  • Handle the first observed user gesture

    Parameters

    • event: Event

      The mouse-move event which enables playback

    • resolve: Function

      The Promise resolution function

    Returns any

  • _onChangeGlobalVolume(key: string, volume: number): void
  • Additional standard callback events that occur whenever a global volume slider is adjusted

    Parameters

    • key: string

      The setting key

    • volume: number

      The new volume level

    Returns void

  • registerSettings(): void
  • Register client-level settings for global volume overrides

    Returns void

  • hasAudioExtension(src: string): boolean
  • Test whether a source file has a supported audio extension type

    Parameters

    • src: string

      A requested audio source path

    Returns boolean

    Does the filename end with a valid audio extension?

  • getDefaultSoundName(src: string): string
  • Given an input file path, determine a default name for the sound based on the filename

    Parameters

    • src: string

      An input file path

    Returns string

    A default sound name for the path

  • _activateSocketListeners(socket: any): void
  • Open socket listeners which transact ChatMessage data

    Parameters

    • socket: any

    Returns void

  • play(data: { src: string; volume: number; autoplay: boolean; loop: boolean }, socketOptions: any): Sound
  • Play a one-off sound effect which is not part of a Playlist

    example

    Play the sound of a locked door for all players

    AudioHelper.play({src: "sounds/lock.wav", volume: 0.8, loop: false}, true);
    

    Parameters

    • data: { src: string; volume: number; autoplay: boolean; loop: boolean }

      An object configuring the audio data to play

      • src: string

        The audio source file path, either a public URL or a local path relative to the public directory

      • volume: number

        The volume level at which to play the audio, between 0 and 1.

      • autoplay: boolean

        Begin playback of the audio effect immediately once it is loaded.

      • loop: boolean

        Loop the audio effect and continue playing it until it is manually stopped.

    • socketOptions: any

      Options which only apply when emitting playback over websocket. As a boolean, emits (true) or does not emit (false) playback to all other clients As an object, can configure which recipients should receive the event.

    Returns Sound

    A Sound instance which controls audio playback.

  • preloadSound(src: string): Promise<Sound>
  • Begin loading the sound for a provided source URL adding its

    Parameters

    • src: string

      The audio source path to preload

    Returns Promise<Sound>

    The created and loaded Sound ready for playback

  • inputToVolume(value: string | number, order?: number): number
  • Returns the volume value based on a range input volume control's position. This is using an exponential approximation of the logarithmic nature of audio level perception

    Parameters

    • value: string | number

      Value between [0, 1] of the range input

    • order: number = 1.5

    Returns number

  • volumeToInput(volume: number, order?: number): number
  • Counterpart to inputToVolume() Returns the input range value based on a volume

    Parameters

    • volume: number

      Value between [0, 1] of the volume level

    • order: number = 1.5

    Returns number