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 🙏

© 2026 – Pkg Stats / Ryan Hefner

audio-buffer

v7.3.1

Published

AudioBuffer ponyfill with operations toolkit

Readme

audio-buffer test stable

Audio data container with planar float32 layout.

Web Audio API AudioBuffer ponyfill for node, bun and other envs.

Comes with optional utils.

import AudioBuffer from 'audio-buffer'
import { from, trim, normalize } from 'audio-buffer/util'

let buf = from([0, 0, 0.5, 0.8, 0.3, 0, 0])
buf = normalize(trim(buf))

API

Constructor

new AudioBuffer({ length: 1024, sampleRate: 44100, numberOfChannels: 2 })
new AudioBuffer(2, 1024, 44100) // positional form

Properties

All read-only.

  • length — samples per channel
  • sampleRate — Hz
  • duration — seconds
  • numberOfChannels

Iterable over channels: for (let ch of buf), let [L, R] = buf.

Methods

buf.getChannelData(0)                           // Float32Array for channel 0
buf.copyFromChannel(dest, 0, 100)               // copy channel 0 from sample 100 into dest
buf.copyToChannel(src, 1)                       // write src into channel 1

Utils

import { from, slice, concat, set } from 'audio-buffer/util'

Same-size ops mutate and return the buffer. Size-changing ops return a new buffer.

isAudioBuffer(buf) → boolean

Check if object is an AudioBuffer instance or duck-typed compatible.

isAudioBuffer(buf)                               // true

from(source, fill?, options?) → AudioBuffer

Create buffer from anything — number, Float32Array, Array, AudioBuffer, ArrayBuffer. Optional second arg fills samples — a number for constant value, or fn(sample, index, channel, channelData) to map (like Array.from).

from([0.1, -0.3, 0.5])                       // array of samples → mono
from([left, right], { sampleRate: 48000 })   // Float32Array[] → stereo
from(existingBuffer)                         // clone
from(1024, 0.5)                              // 1024 samples buffer filled with 0.5
from(1024, (s, i) => Math.sin(i * 0.1))      // generate sine wave
from(buf, v => v * 0.5)                      // clone with half volume
from(buf, 0)                                 // same shape, zeroed (like)
from({ length: 1024, numberOfChannels: 2 })  // from options

slice(buffer, start?, end?) → newBuffer

Extract sample range into new buffer.

slice(buf, 100, 200)                           // samples 100–199
slice(buf, -50)                                // last 50 samples

concat(...buffers) → newBuffer

Join buffers (same sampleRate and channels).

concat(a, b)                                   // a + b end-to-end
concat(a, b, c, d)                             // join many

set(buffer, other, offset?) → buffer

Overwrite samples from another buffer.

set(buf, patch, 1000)                          // write patch at sample 1000

fill(buffer, value, start?, end?) → buffer

Fill with constant or per-sample function.

fill(buf, 0)                                   // silence
fill(buf, (s, i, ch) => Math.sin(i * 0.1))     // sine wave
fill(buf, () => Math.random() * 2 - 1)         // white noise
fill(buf, v => -v)                             // phase-invert

normalize(buffer, start?, end?) → buffer

Peak-normalize to 1.0, preserving inter-channel balance.

normalize(buf)                                 // quiet recording → full scale

trim(buffer, threshold?) → newBuffer

Remove silence from both ends.

trim(buf)                                      // remove exact zeros
trim(buf, 0.01)                                // remove near-silence

reverse(buffer, start?, end?) → buffer

Reverse samples.

reverse(buf)                                   // full reverse
reverse(buf, 0, 100)                           // reverse first 100 samples

mix(a, b, ratio?, offset?) → a

Blend b into a. Ratio 0 = keep a, 1 = replace with b.

mix(track, reverb, 0.3)                        // 70% dry, 30% wet
mix(a, b, (sa, sb) => Math.max(sa, sb))       // custom blend function
mix(a, b, 0.5, 1000)                           // mix starting at sample 1000

remix(buffer, channels, interpretation?) → newBuffer

Upmix/downmix channels per Web Audio spec speaker rules.

remix(stereo, 1)                               // stereo → mono
remix(mono, 2)                                 // mono → stereo
remix(buf, 6)                                  // → 5.1 surround
remix(buf, 4, 'discrete')                      // copy channels, silence rest

pad(buffer, length, value?, side?) → newBuffer

Pad to target length.

pad(buf, 44100)                                // zero-pad to 1 second
pad(buf, 44100, 0, 'start')                    // pad at start

repeat(buffer, times) → newBuffer

Repeat N times.

repeat(buf, 4)                                 // loop 4x

rotate(buffer, offset) → buffer

Circular shift. Positive = right.

rotate(buf, 100)                               // shift right 100 samples
rotate(buf, -50)                               // shift left 50

removeDC(buffer, start?, end?) → buffer

Remove DC offset (subtract mean per channel).

removeDC(buf)                                  // center waveform at zero

isEqual(a, b) → boolean

Deep equality — same shape, same samples.

isEqual(buf, clone)                            // true if identical

Play

import play from 'audio-buffer/play'

let ctrl = await play(buf, { volume: 0.8, loop: true })
ctrl.pause()
ctrl.play()
ctrl.stop()
ctrl.currentTime  // seconds
ctrl.playing      // boolean

Options: { volume, loop, start, end, autoplay, onended }.

Uses Web Audio API in browsers. In Node.js, install audio-speaker: npm i audio-speaker.

stop() resets to start. play() restarts from beginning.

Replaces