ALSA bindings for Node.js
You must have a system on which ALSA is supported with the
libasound2-dev package installed:
$ sudo apt-get install libasound2-dev
You'll also probably want to have an audio device for either playback or capture.
Install with npm:
$ npm install alsa
or via git:
$ npm install git+https://github.com/xdissent/node-alsa.git
alsa module exports 2 high-level classes for playback and recording.
var alsa =// The following variables represent the defaults for the Playback and Capture constructors.device = 'default' // ALSA default devicechannels = 2 // Stereorate = 44100 // Sample rateformat = alsaFORMAT_S16_LE // PCM format (signed 16 bit LE int)access = alsaACCESS_RW_INTERLEAVED // Access modelatency = 500; // Desired latency in milliseconds// The Capture class is a stream.Readable subclass.var capture = device channels rate format access latency;capture; // Treat it like any other readable stream.// The Playback class is a stream.Writable subclass.var playback = device channels rate format access latency;processstdin; // Treat it like any other writable stream.// Want to do both at the same time? Not a problem:capture; // Of course, your sound hardware might say otherwise.
Downsample audio captured from an ALSA device to a sample rate of 11025, in mono, encoded to 32 bit float PCM data and output to stdout:
alsa = require 'alsa'stream = require 'stream': -> streamTransformcall this# Naively drop 3 out of 4 samples, combine the interleaved left and right into# a single sample, then convert to 32 bit float PCM data.:# This is the naive part. Should be checking for partial samples.floats = chunklength / 4f = 0for i in 0...chunklengthby 16 # 4 bytes per frame downsampled by 4.l16 = chunkreadInt16LE i # Read left channel sample.r16 = chunkreadInt16LE i + 2 # Read right channel sample.# Sum samples and normalize as a floatfloatswriteFloatLE l16 + r16 / 65536ff += 4 # Skip ahead 4 bytes in buffer (32 bit float).@push floats # Write transformed samples to stream...callback # And we're done.# Create a Capture and a Downer and chain them to stdout.capture =downer =capturepipedownerpipeprocessstdout