Skip to content

Decode audio data asynchronously, in the browser using Base​Audio​Context​.decode​Audio​Data(), as fast as possible.

License

Notifications You must be signed in to change notification settings

soundcut/decode-audio-data-fast

Repository files navigation

decode-audio-data-fast

Decode audio file data in the browser from a File/Blob into a AudioBuffer using AudioContext.decodeAudioData().

This package was originally created and is used in soundcut.

Why decoding audio file data ?

In the current state of Web Audio API, there is a variety of use-cases where one might need to decode a file (Blob, or ArrayBuffer) audio data (AudioBuffer) (though the current APIs are arguably quite inneficient at this, decoding the whole file upfront), including but not limited to:

Why use this over native AudioContext.decodeAudioData() ?

AudioContext.decodeAudioData() is slow and does not work for large files.

By splitting the source into chunks and decoding these in concurrently, decode-audio-data-fast works around the native API's limitations.

Usage

npm i --save @soundcut/decode-audio-data-fast

ESM

import { getFileAudioBuffer } from '@soundcut/decode-audio-data-fast';

function decodeFileAudioData(file) {
  const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  return getFileAudioBuffer(file, audioCtx);
}

CJS

const { getFileAudioBuffer } = require('@soundcut/decode-audio-data-fast');

function decodeFileAudioData(file) {
  const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  return getFileAudioBuffer(file, audioCtx);
}

UMD

<script src="{YOUR_HOST}/decode-audio-data-fast.standalone.umd.min.js"></script>
<script>
  function decodeFileAudioData(file) {
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    return window.DADF.getFileAudioBuffer(file, audioCtx);
  }
</script>

CDN (unpkg)

https://unpkg.com/@soundcut/decode-audio-data-fast

See all files published in ./dist directory.

Are there other alternatives ?

Yes. However, it appears decode-audio-data-fast is twice as fast.

Supported formats

At the moment, decode-audio-data-fast only supports mp3 files that can be read through mp3-parser.

Benchmarks

See ./benchmark directory.

Visit decodeAudioData / decode-audio-data-fast benchmark page (open your browser console, wait a reasonably long time for all the benchmarks to run).

Benchmark of decodeAudioData vs decode-audio-data-fast in Firefox

Benchmark of decodeAudioData vs decode-audio-data-fast in Firefox

Benchmark of decodeAudioData vs decode-audio-data-fast in Chromium

Benchmark of decodeAudioData vs decode-audio-data-fast in Chromium

Test file is a 13MB 320kbps CBR MP3 export of https://www.youtube.com/watch?v=BigolJfoANw

Options

The last argument of getFileAudioBuffer is an optional options: { concurrency: number } object:

getFileAudioBuffer(file, audioCtx, { concurrency: 4 })

When omitted, getFileAudioBuffer will use "automatic concurrency mode", relying on navigator.hardwareConcurrency:

const DEFAULT_CONCURRENCY = 4;
const CONCURRENCY =
  ((typeof navigator !== 'undefined' && navigator.hardwareConcurrency) || 1) > 2
    ? navigator.hardwareConcurrency
    : DEFAULT_CONCURRENCY;

See rationale for "automatic concurrency mode" on Twitter.

Browser support

FIXME

This module is intended for ~modern browsers, uses and assumes availability of the following syntax/API, among others:

This module has somewhat been tested on Firefox/Chrome, for desktop and mobile, and currently has known issues with Safari.

About

Decode audio data asynchronously, in the browser using Base​Audio​Context​.decode​Audio​Data(), as fast as possible.

Resources

License

Stars

Watchers

Forks

Packages

No packages published