An open API service indexing awesome lists of open source software.

https://github.com/audiojs/audio-buffer-utils

Utils for audio buffers
https://github.com/audiojs/audio-buffer-utils

Last synced: 8 months ago
JSON representation

Utils for audio buffers

Awesome Lists containing this project

README

          

# audio-buffer-utils [![Build Status](https://travis-ci.org/audiojs/audio-buffer-utils.svg?branch=master)](https://travis-ci.org/audiojs/audio-buffer-utils) [![unstable](https://img.shields.io/badge/stability-unstable-green.svg)](http://github.com/badges/stability-badges) [![Greenkeeper badge](https://badges.greenkeeper.io/audiojs/audio-buffer-utils.svg)](https://greenkeeper.io/)

Utility functions for [_AudioBuffers_](https://github.com/audiojs/audio-buffer) in web-audio and node. Optimized for performance.

* [util.create(src, ch|opts?)](https://github.com/audiojs/audio-buffer-utils#utilcreatedatalength-optionschannels1-samplerate44100)
* [util.shallow(buf)](#utilshallowbuffer)
* [util.clone(buf)](#utilclonebuffer)
* [util.copy(buf, dst, start?)](#utilcopyfrombuffer-tobuffer-offset0)
* [util.slice(buf, start?, end?)](#utilslicebuffer-start0-end-0)
* [util.subbuffer(buf, start?, end?, ch?)](#utilsubbufferbuffer-start0-end-0-channels)
* [util.concat(a, b, ...)](#utilconcatbuffer1-buffer2-buffer3-buffern-)
* [util.repeat(buf, n)](#utilrepeatbuffer-times)
* [util.reverse(src, dst?, start?, end?)](#utilreversebuffer-target-start0-end-0)
* [util.invert(src, dst?, start?, end?)](#utilinvertbuffer-target-start0-end-0)
* [util.zero(buf)](#utilzerobuffer)
* [util.noise(buf)](#utilnoisebuffer)
* [util.equal(a, b, ...)](#utilequalbuffera-bufferb-)
* [util.fill(buf, dst?, val, start?, end?)](#utilfillbuffer-target-valuevalue-i-channelvalue-start0-end-0)
* [util.resize(buf, len)](#utilresizebuffer-length)
* [util.pad(buf, len, val?)](#utilpadbufferlength-lengthbuffer-value0)
* [util.shift(buf, off)](#utilshiftbuffer-offset)
* [util.rotate(buf, off)](#utilrotatebuffer-offset)
* [util.normalize(buf, dst?, start?, end?)](#utilnormalizebuffer-target-start0-end-0)
* [util.removeStatic(buf, dst?, start?, end?)](#utilremovestaticbuffer-target-start0-end-0)
* [util.trim(buf, lvl)](#utiltrimbuffer-threshold0)
* [util.mix(a, b, amt?, off?)](#utilmixbuffera-bufferb-ratiovala-valb-i-channelval-offset0)
* [util.size(buf)](#utilsizebuffer)
* [util.data(buf, dst?)](#utildatabuffer-data)

## Usage

[![npm install audio-buffer-utils](https://nodei.co/npm/audio-buffer-utils.png?mini=true)](https://npmjs.org/package/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](https://github.com/audiojs/audio-buffer-from) module.

```js
//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.

```js
//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.

```js
//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](https://github.com/audiojs/audio-buffer-remix).

```js
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.

```js
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.

```js
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`.

```js
//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.

```js
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](https://github.com/dy/array-noramalize).
Places data to `target` buffer, if any, otherwise modifies `buffer` in-place.

```js
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.

```js
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](https://npmjs.org/package/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.

```js
let a = util.create(3, 2)

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

## Related

> [audio-buffer](https://github.com/audiojs/audio-buffer) — audio data container, both for node/browser.

> [audio-buffer-list](https://github.com/audiojs/audio-buffer-list) — linked audio buffers sequence structure

> [audio](https://github.com/audiojs/audio) — class for high-level audio manipulations, comprising the functionality of above mentioned.
> [ciseaux](https://github.com/mohayonao/ciseaux)

## Credits

Thanks to [**@jaz303**](https://github.com/jaz303/) for [the initial idea](https://github.com/jaz303/audio-buffer-utils) and collaboration.