Skip to content

analyticsinmotion/decibri-web

Repository files navigation

decibri-web

Cross-browser microphone capture for the web.

Zero dependencies.

Meta npm version  Apache 2.0 License  decibri.com  Analytics in Motion

The decibri platform

Package Environment Backend
decibri Node.js Native C++ (PortAudio)
decibri-web Browser Web Audio API

Same API. Different runtimes. Capture audio anywhere JavaScript runs.

Quick Start

npm install decibri-web
import { Decibri } from 'decibri-web';

const mic = new Decibri({ sampleRate: 16000 });

mic.on('data', (chunk) => {
  // chunk is an Int16Array of PCM samples — ready to use
  console.log(`Received ${chunk.length} samples`);
});

// Must be called from a user gesture (click/tap) in Safari
await mic.start();

// Stop when done
mic.stop();

API Reference

new Decibri(options?)

Creates a new microphone capture instance. Does not start capture — call start().

Option Type Default Description
sampleRate number 16000 Target sample rate in Hz
channels number 1 Number of channels (browsers reliably support 1)
framesPerBuffer number 1600 Frames per chunk (1600 at 16kHz = 100ms)
device string system default deviceId from Decibri.devices()
format 'int16' | 'float32' 'int16' Sample encoding format
vad boolean false Enable voice activity detection
vadThreshold number 0.01 RMS energy threshold for speech (0–1)
vadHoldoff number 300 Ms of silence before 'silence' event
echoCancellation boolean true Browser echo cancellation. Set false for music/tuner apps.
noiseSuppression boolean true Browser noise suppression. Set false for music/tuner apps.
workletUrl string (inline) URL for the AudioWorklet processor. Override if CSP blocks blob: URLs.

Methods

Method Returns Description
start() Promise<void> Request mic permission and begin capture. No-op if already started.
stop() void Stop capture and release all resources. Safe to call anytime.
isOpen boolean true while actively capturing.

Static Methods

Method Returns Description
Decibri.devices() Promise<DeviceInfo[]> List audio input devices. Labels may be empty before permission is granted.
Decibri.version() VersionInfo Package version info.

Events

Event Payload Description
data Int16Array or Float32Array Audio chunk (format depends on format option)
error Error Permission denied, worklet load failure, etc.
end Emitted after stop()
close Emitted after stop(), after end
speech VAD: RMS energy crossed threshold (requires vad: true)
silence VAD: sub-threshold audio for vadHoldoff ms (requires vad: true)

Browser Support

Browser Minimum Version
Chrome 66+
Firefox 76+
Safari 14.1+ (requires user gesture for start())
Edge 79+
iOS Safari 14.5+
Android Chrome 66+

Requires HTTPS (or localhost) for microphone access.

Differences from decibri (Node.js)

Feature Node.js decibri decibri-web
Constructor Sync, capture starts on read Sync, requires await start()
data payload Buffer Int16Array / Float32Array
devices() Sync Async (returns Promise)
device option Number index or name substring String deviceId only
version() { decibri, portaudio } { decibriWeb }
echoCancellation N/A boolean (default true)
noiseSuppression N/A boolean (default true)
backpressure event Available Not available
pipe() / streams Full Readable stream Not available

WebSocket Streaming Example

import { Decibri } from 'decibri-web';

const ws = new WebSocket('wss://your-server.com/audio');
const mic = new Decibri({ sampleRate: 16000, format: 'int16' });

mic.on('data', (chunk) => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(chunk.buffer);
  }
});

mic.on('error', (err) => console.error(err));

// Start on button click
document.getElementById('start')!.addEventListener('click', () => mic.start());
document.getElementById('stop')!.addEventListener('click', () => mic.stop());

CDN / Script Tag Usage

<script src="https://unpkg.com/decibri-web/dist/index.global.js"></script>
<script>
  const mic = new DecibriWeb.Decibri({ sampleRate: 16000 });
  mic.on('data', (chunk) => console.log(chunk.length, 'samples'));
  document.getElementById('start').onclick = () => mic.start();
</script>

Device Selection

// Call start() first to get permission, then enumerate devices with full labels
await mic.start();
const devices = await Decibri.devices();
console.log(devices);
// [{ deviceId: 'abc123', label: 'Built-in Microphone', groupId: 'g1' }, ...]

// Use a specific device
const usbMic = new Decibri({ device: devices[1].deviceId });
await usbMic.start();

CSP-Restricted Environments

If your Content Security Policy blocks blob: URLs, serve the worklet file yourself:

import { Decibri } from 'decibri-web';

const mic = new Decibri({
  workletUrl: '/static/decibri-worklet.js', // serve dist/worklet.js at this path
});

Copy node_modules/decibri-web/dist/worklet.js to your static assets directory and pass the URL.

License

Apache-2.0Analytics in Motion