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 🙏

© 2024 – Pkg Stats / Ryan Hefner

audio-buffer-utils

v5.1.2

Published

Utility functions for AudioBuffers

Downloads

8,880

Readme

audio-buffer-utils Build Status unstable Greenkeeper badge

Utility functions for AudioBuffers in web-audio and node. Optimized for performance.

Usage

npm install audio-buffer-utils

util.create(data|length, options|channels=1, sampleRate=44100)

Create a new buffer from any argument. Data can be a length, an array with channels' data, an other buffer or plain array. See audio-buffer-from module.

//mono buffer with 100 samples
let a = util.create(100)

//stereo buffer with predefined channels data
let b = util.create([Array(100).fill(0.5), Array(100).fill(0.4)])

//minimal length buffer (1 sample, 1 channel)
let c = util.create()

//create 2 seconds buffer with reduced sample rate
let rate = 22050
let d = util.create(2 * rate, 2, rate)

util.shallow(buffer)

Create a new buffer with the same characteristics as buffer, contents are undefined.

//create buffer with the same shape as `a`
let b = util.shallow(a)

util.equal(a, b) //false

util.clone(buffer)

Create a new buffer with the same characteristics as buffer, fill it with a copy of buffer's data, and return it.

//clone buffer `a`
let b = util.clone(a)

util.equal(a, b) //true

util.copy(fromBuffer, toBuffer, offset=0)

Copy the data from one buffer to another, with optional offset. If length of fromBuffer exceeds offset + toBuffer.length, an error will be thrown.

util.slice(buffer, start=0, end=-0)

Create a new buffer by slicing the current one.

util.subbuffer(buffer, start=0, end=-0, channels?)

Create a new buffer by subreferencing the current one. The new buffer represents a handle for the source buffer, working on it's data. Note that it is null-context buffer, meaning that it is not bound to web audio API. To convert it to real AudioBuffer, use util.slice or util.create.

channels array may apply channels mapping to pick only indicated channels from the initial buffer. See also audio-buffer-remix.

var a = util.create(100, 2)
var b = util.subbuffer(10, 90)

//b references a
b.getChannelData(0)[0] = 1
a.getChannelData(0)[10] // 1

//convert b to web-audio-api buffer
b = util.slice(b)

//create mono-buffer from a
var c = util.subbuffer(a, [1])

util.concat(buffer1, [buffer2, buffer3], bufferN, ...)

Create a new buffer by concatting buffers or list. Channels are extended to the buffer with maximum number.

util.repeat(buffer, times)

Return a new buffer with contents of the initial one repeated defined number of times.

util.reverse(buffer, target?, start=0, end=-0)

Reverse buffer. Place data to target buffer, if any, otherwise modify buffer in-place.

util.invert(buffer, target?, start=0, end=-0)

Invert buffer. Place data to target buffer, if any, otherwise modify buffer in-place.

util.zero(buffer)

Zero all of buffer's channel data. buffer is modified in-place.

util.noise(buffer)

Fill buffer with random data. buffer is modified in-place.

util.equal(bufferA, bufferB, ...)

Test whether the content of N buffers is the same.

let a = util.create(1024, 2)
util.noise(a)
let b = util.clone(a)
let c = util.shallow(a)
util.copy(a, c)

if (util.equal(a, b, c)) {
	//true
}

util.fill(buffer, target?, value|(value, i, channel)=>value, start=0, end=-0)

Fill buffer with provided function or value. Place data to target buffer, if any, otherwise modify buffer in-place (that covers map functionality). Pass optional start and end indexes.

let frequency = 440, rate = 44100

//create 2 seconds buffer
let a = util.create(2 * rate)

//populate with 440hz sine wave
util.fill(a, (value, i, channel)=>Math.sin(Math.PI * 2 * frequency * i / rate))

util.resize(buffer, length)

Return new buffer based on the passed one, with shortened/extended length. Initial data is whether sliced or filled with zeros. Combines util.pad and util.slice.

//change duration to 2s
let b = util.resize(a, 2 * a.sampleRate)

util.pad(buffer|length, length|buffer, value=0)

util.padLeft(buffer, length, value=0)

util.padRight(buffer, length, value=0)

Right/left-pad buffer to the length, filling with value.

let buf = util.create(3, 1)
util.fill(buf, .2)

util.pad(buf, 5) // [.2,.2,.2, 0,0]
util.pad(5, buf) // [0,0, .2,.2,.2]
util.pad(buf, 5, .1) // [.2,.2,.2, .1,.1]
util.pad(5, buf, .1) // [.1,.1, .2,.2,.2]

util.shift(buffer, offset)

Shift signal in the time domain by offset samples, filling with zeros. Modify buffer in-place.

util.rotate(buffer, offset)

Shift signal in the time domain by offset samples, in circular fashion. Modify buffer in-place.

util.normalize(buffer, target?, start=0, end=-0)

Normalize buffer by the amplitude, bring to -1..+1 range. Channel amplitudes ratio will be preserved. You may want to remove static level beforehead, because normalization preserves zero static level. Note that it is not the same as array-normalize. Places data to target buffer, if any, otherwise modifies buffer in-place.

const AudioBuffer = require('audio-buffer')
const util = require('audio-buffer-utils')

let buf = AudioBuffer(1, [0, 0.2, 0, -0.4]);
util.normalize(buf);
buf.getChannelData(0) // [0, .5, 0, -1]

util.removeStatic(buffer, target?, start=0, end=-0)

Remove DC (Direct Current) offset from the signal, i.e. remove static level, that is bring mean to zero. DC offset will be reduced for every channel independently.

var a = AudioBuffer(2, [.5,.7,.3,.5])

util.removeStatic(a)

a.getChannelData(0) // [-.1, .1]
a.getChannelData(1) // [-.1, .1]

util.trim(buffer, threshold=0)

util.trimLeft(buffer, threshold=0)

util.trimRight(buffer, threshold=0)

Create buffer with trimmed zeros from the start and/or end, by the threshold amplitude.

util.mix(bufferA, bufferB, ratio|(valA, valB, i, channel)=>val?, offset=0)

Mix second buffer into the first one. Pass optional weight value or mixing function.

util.size(buffer)

Return buffer size, in bytes. Use pretty-bytes package to format bytes to a string, if needed.

util.data(buffer, data?)

Get channels' data in array. Pass existing array to transfer the data to it. Useful in audio-workers to transfer buffer to output.

let a = util.create(3, 2)

let audioData = util.data(a) // [[0,0,0], [0,0,0]]

Related

audio-buffer — audio data container, both for node/browser. audio-buffer-list — linked audio buffers sequence structure audio — class for high-level audio manipulations, comprising the functionality of above mentioned. ciseaux

Credits

Thanks to @jaz303 for the initial idea and collaboration.