-
Notifications
You must be signed in to change notification settings - Fork 3
Recording & Playback
import * as fs from 'fs';
import * as wav from 'wav';
import { PulseAudio, PA_SAMPLE_FORMAT, sampleSize } from '@janakj/pulseaudio.js';
const pa = new PulseAudio();
await pa.connect();
Recording audio with pulseaudio.js is straightforward. Create a new record stream with the method createRecordStream
, pipe the stream to a wav write, and pipe the wav writer to a file. When you are done recording, unpipe the streams and destroy the record stream.
// Configure the sample format: 44.1 kHz, stereo, 16 bits per sample
const rate = 44100, channels = 2, format = PA_SAMPLE_FORMAT.S16LE;
// Create a new record stream with the given sample format connected
// to the default source (sound card)
const stream = await pa.createRecordStream({
sampleSpec : { rate, format, channels }
});
// Create a new wav file writer with the above sample format
const writer = new wav.Writer({
sampleRate : rate,
channels,
bitDepth : sampleSize[format] * 8
});
// Write the recorded audio to file audio.wav
const file = fs.createWriteStream('audio.wav');
// Pipe the record stream to the write and the writer to the
// filesystem stream
stream.pipe(writer);
writer.pipe(file);
// Keep recording for 10 seconds. Once the time is up, unpipe
// the streams and destroy the record the stream
setTimeout(() => {
stream.unpipe();
writer.unpipe();
stream.destroy();
}, 10000);
It is also possible the specify the maximum length of the recording in bytes by passing a maximumLength
property to createRecordStream
. In that case, the record stream will end automatically upon recording the given number of bytes, without the need to set a timer.
The basic playback routine might look as follows. We first create a read stream for a wav file and pipe the stream to a wav reader object. Once the 'format' event has been emitted, we know the sample format of the wav file. We create a new playback stream using createPlaybackStream
and pipe the wav reader stream into it. Once the end of the wav file has been reached, the playback stream will be automatically destroyed.
// Create a read stream for the wav file
const file = fs.createReadStream('audio.wav');
const reader = new wav.Reader();
// wait for the wav reader to emit the 'format' event
reader.once('format', async ({ bitDepth, channels, sampleRate: rate }) => {
// Create a new playback stream using the given parameters
const output = await pa.createPlaybackStream({
sampleSpec: {
format : bitDepth === 16 ? PA_SAMPLE_FORMAT.S16LE : PA_SAMPLE_FORMAT.U8,
rate,
channels
}
});
// Pipe the rest of the file into the playback stream
reader.pipe(output);
});
// Pipe the file stream into the wav reader to get playback started
file.pipe(reader);