npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@l8b/audio

v1.0.11

Published

**LootiScript API Binding** - Audio playback for sound effects, music, and synthesized beeps.

Readme

@l8b/audio

LootiScript API Binding - Audio playback for sound effects, music, and synthesized beeps.

Note: This package is used as an API binding for LootiScript in the l8b engine.

API Reference

Audio.playSound()

Play a sound effect with optional parameters.

Signature:

Audio.playSound(sound: string, volume?: number, pitch?: number, pan?: number, loop?: boolean): number

Parameters:

  • sound (string) - Sound file name (relative to assets/ directory)
  • volume (number, optional) - Volume level 0.0-1.0, default: 1.0
  • pitch (number, optional) - Pitch 0.5-2.0, default: 1.0
  • pan (number, optional) - Stereo pan -1.0 (left) to 1.0 (right), default: 0
  • loop (boolean, optional) - Loop the sound, default: false

Returns: Sound ID (number) - Control object with methods:

  • stop() - Stop the sound
  • setVolume(v: number) - Set volume (0.0-1.0)
  • setPitch(p: number) - Set pitch (0.5-2.0)
  • setPan(p: number) - Set pan (-1.0 to 1.0)
  • getDuration() - Get sound duration in seconds
  • finished (boolean) - Whether sound has finished playing

Examples:

// Basic usage
Audio.playSound("jump.wav")

// With volume (0.0 to 1.0)
Audio.playSound("explosion.wav", 0.8)

// With volume and pitch (0.5 to 2.0)
Audio.playSound("coin.wav", 1.0, 1.5)

// With volume, pitch, and pan (-1.0 to 1.0)
Audio.playSound("footstep.wav", 0.7, 1.0, -0.5)

// With all parameters including loop
local soundId = Audio.playSound("engine.wav", 0.9, 1.0, 0, true)

// Control playback
local sound = Audio.playSound("laser.wav")
sound.setVolume(0.5)
sound.setPitch(1.2)
sound.stop()

Sound Control Example:

local engineSound = nil

function startEngine()
  engineSound = Audio.playSound("engine.wav", 0.8, 1.0, 0, true)
end

function stopEngine()
  if engineSound then
    engineSound.stop()
    engineSound = nil
  end
end

function update()
  if keyboard.press.SPACE == 1 then
    if engineSound then
      stopEngine()
    else
      startEngine()
    end
  end
end

Audio.playMusic()

Play background music with optional looping.

Signature:

Audio.playMusic(music: string, volume?: number, loop?: boolean): number

Parameters:

  • music (string) - Music file name (relative to assets/ directory)
  • volume (number, optional) - Volume level 0.0-1.0, default: 1.0
  • loop (boolean, optional) - Loop the music, default: false

Returns: Music ID (number) - Control object with methods:

  • play() - Resume playback
  • stop() - Stop the music
  • setVolume(v: number) - Set volume (0.0-1.0)
  • getPosition() - Get current playback position in seconds
  • getDuration() - Get total duration in seconds
  • setPosition(pos: number) - Seek to position in seconds

Examples:

// Basic usage
Audio.playMusic("theme.mp3")

// With volume
Audio.playMusic("battle.mp3", 0.6)

// With volume and loop
local musicId = Audio.playMusic("menu.mp3", 0.8, true)

// Control playback
local music = Audio.playMusic("credits.mp3", 1.0, false)
music.setVolume(0.5)
music.setPosition(30)  // Jump to 30 seconds
music.stop()

Music Control Example:

local currentMusic = nil

function playMenuMusic()
  if currentMusic then
    currentMusic.stop()
  end
  currentMusic = Audio.playMusic("menu.mp3", 0.7, true)
end

function playGameMusic()
  if currentMusic then
    currentMusic.stop()
  end
  currentMusic = Audio.playMusic("game.mp3", 0.6, true)
end

function fadeOutMusic()
  if currentMusic then
    local volume = 0.7
    local fadeInterval = setInterval(function()
      volume = volume - 0.05
      if volume <= 0 then
        currentMusic.stop()
        currentMusic = nil
        clearInterval(fadeInterval)
      else
        currentMusic.setVolume(volume)
      end
    end, 100)
  end
end

Audio.beep()

Play synthesized beep sequences.

Signature:

Audio.beep(sequence: string): void

Parameters:

  • sequence (string) - Beep sequence string with notes and commands

Returns: void

Note Format:

  • Note names: C, D, E, F, G, A, B
  • Octaves: 0-8 (e.g., C4, A3)
  • Sharps: # (e.g., C#4, F#3)
  • Flats: b (e.g., Db4, Eb3)
  • Duration: Optional number after note (in seconds)
  • Separator: Space or comma
  • Commands:
    • tempo <number> - Set tempo (BPM)
    • duration <number> - Set default duration in seconds
    • volume <number> - Set volume (0.0-1.0)
    • span <number> - Set span
    • square, sine, saw, noise - Set waveform
    • loop - Loop the sequence
    • to <note> - Jump to note

Examples:

// Single note
Audio.beep("C4")

// Multiple notes
Audio.beep("C4 E4 G4")

// With duration (in seconds)
Audio.beep("A3 0.1, B3 0.1, C4 0.2")

// Complex melody
Audio.beep("C4 0.25, D4 0.25, E4 0.25, F4 0.5")

// With tempo
Audio.beep("tempo 120 C4 D4 E4 F4 G4")

// With waveform
Audio.beep("square C4 E4 G4")
Audio.beep("sine A3 B3 C4")

// Full sequence with commands
Audio.beep("tempo 100 volume 0.8 square C4 0.2 D4 0.2 E4 0.4")

// Loop sequence
Audio.beep("loop C4 E4 G4 C5")

Advanced Beep Examples:

// Play a scale
Audio.beep("C4 D4 E4 F4 G4 A4 B4 C5")

// Play a chord
Audio.beep("C4 E4 G4")

// Play with different waveforms
Audio.beep("square C4")  // Square wave
Audio.beep("sine C4")    // Sine wave
Audio.beep("saw C4")     // Sawtooth wave
Audio.beep("noise")      // White noise

// Control tempo and volume
Audio.beep("tempo 60 volume 0.5 C4 D4 E4")

Audio.cancelBeeps()

Stop all currently playing beeps and sounds.

Signature:

Audio.cancelBeeps(): void

Parameters: None

Returns: void

Examples:

// Stop everything
Audio.cancelBeeps()

// Stop beeps when game pauses
function pauseGame()
  Audio.cancelBeeps()
  paused = true
end

Sound File Formats

Supported audio formats:

  • .wav - Uncompressed audio (best quality, larger file size)
  • .mp3 - Compressed audio (good compatibility)
  • .ogg - Compressed audio (recommended for web, good compression)

Recommendations:

  • Use .ogg for web games (best compression, good quality)
  • Use .wav for short sound effects (no compression artifacts)
  • Use .mp3 for music (good balance of quality and file size)

File Paths

All audio paths are relative to the assets/ directory:

// Loads from: assets/sounds/jump.wav
Audio.playSound("sounds/jump.wav")

// Loads from: assets/music/theme.mp3
Audio.playMusic("music/theme.mp3")

// Supports subdirectories
Audio.playSound("sfx/player/jump.wav")
Audio.playMusic("bgm/menu.mp3")

Volume Control

Volume values range from 0.0 (silent) to 1.0 (full volume):

Audio.playSound("quiet.wav", 0.3)   // 30% volume
Audio.playSound("normal.wav", 0.7)  // 70% volume
Audio.playSound("loud.wav", 1.0)    // 100% volume

// Dynamic volume control
local sound = Audio.playSound("ambient.wav", 1.0)
sound.setVolume(0.5)  // Reduce to 50%

Pitch Control

Pitch values range from 0.5 (half speed, lower pitch) to 2.0 (double speed, higher pitch):

Audio.playSound("voice.wav", 1.0, 0.5)  // Lower pitch (slow)
Audio.playSound("voice.wav", 1.0, 1.0)  // Normal pitch
Audio.playSound("voice.wav", 1.0, 2.0)  // Higher pitch (fast)

// Dynamic pitch control
local sound = Audio.playSound("effect.wav", 1.0, 1.0)
sound.setPitch(1.5)  // Increase pitch

Use Cases:

  • Lower pitch (0.5-0.8): Deep voices, slow motion effects
  • Normal pitch (1.0): Standard playback
  • Higher pitch (1.2-2.0): Fast-forward effects, chipmunk voices

Pan Control

Pan values range from -1.0 (left) to 1.0 (right):

Audio.playSound("left.wav", 1.0, 1.0, -1.0)   // Left speaker only
Audio.playSound("center.wav", 1.0, 1.0, 0.0)  // Center (both speakers)
Audio.playSound("right.wav", 1.0, 1.0, 1.0)   // Right speaker only

// Dynamic pan control
local sound = Audio.playSound("footstep.wav", 1.0, 1.0, 0.0)
sound.setPan(-0.5)  // Slightly left

Use Cases:

  • Positional audio (left/right based on game object position)
  • Stereo effects
  • 3D audio simulation

Audio Context and Autoplay Policy

The audio system automatically handles browser autoplay policies:

  • Audio context is created lazily on first use
  • If the context is suspended (due to autoplay policy), it will automatically resume on user interaction
  • No manual intervention needed - the system handles this transparently

Note: Some browsers require user interaction before audio can play. The first audio call may be delayed until the user interacts with the page.


Complete Example

// Game audio manager
local sounds = {}
local music = nil

function init()
  // Pre-load sounds (optional)
  Audio.playSound("jump.wav", 0, 1.0, 0, false)  // Silent preload
end

function playJumpSound()
  Audio.playSound("jump.wav", 0.8, 1.0, 0, false)
end

function playCoinSound()
  Audio.playSound("coin.wav", 0.6, 1.2, 0, false)
end

function playExplosionSound()
  Audio.playSound("explosion.wav", 1.0, 0.9, 0, false)
end

function startBackgroundMusic()
  if music then
    music.stop()
  end
  music = Audio.playMusic("theme.mp3", 0.6, true)
end

function stopBackgroundMusic()
  if music then
    music.stop()
    music = nil
  end
end

function playVictoryBeep()
  Audio.beep("tempo 120 volume 0.8 C4 E4 G4 C5")
end

function update()
  if keyboard.press.SPACE == 1 then
    playJumpSound()
  end
  
  if keyboard.press.ENTER == 1 then
    if music then
      stopBackgroundMusic()
    else
      startBackgroundMusic()
    end
  end
  
  if keyboard.press.B == 1 then
    playVictoryBeep()
  end
end

function cleanup()
  Audio.cancelBeeps()
  if music then
    music.stop()
  end
end

Performance Tips

  1. Preload sounds: Play sounds at volume 0 to preload them
  2. Reuse sound objects: Store sound control objects for frequently used sounds
  3. Limit concurrent sounds: Too many simultaneous sounds can cause performance issues
  4. Use appropriate formats: .ogg for web, .wav for short effects
  5. Control loop count: Limit the number of looping sounds

Error Handling

Audio errors are automatically handled:

  • Missing files are reported but don't crash the game
  • Invalid parameters are clamped to valid ranges
  • Browser compatibility issues are handled gracefully