or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-picovoice--pvrecorder-node

Cross-platform audio recorder library for real-time speech processing in Node.js applications.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@picovoice/pvrecorder-node@1.2.x

To install, run

npx @tessl/cli install tessl/npm-picovoice--pvrecorder-node@1.2.0

index.mddocs/

PvRecorder Node

PvRecorder is a cross-platform audio recorder library designed for real-time speech audio processing in Node.js applications. It provides frame-based audio capture with configurable buffer sizes, supporting multiple platforms including Linux, macOS, Windows, and Raspberry Pi. The library offers both synchronous and asynchronous APIs for reading audio frames, automatic device enumeration and selection capabilities, and proper resource management.

Package Information

  • Package Name: @picovoice/pvrecorder-node
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @picovoice/pvrecorder-node

Core Imports

import { PvRecorder } from "@picovoice/pvrecorder-node";

For CommonJS:

const { PvRecorder } = require("@picovoice/pvrecorder-node");

Basic Usage

import { PvRecorder } from "@picovoice/pvrecorder-node";

// Initialize recorder with frame length (required) and optional device index
const recorder = new PvRecorder(512); // 512 samples per frame
// or with specific device: new PvRecorder(512, deviceIndex);

// Start recording
recorder.start();

// Read audio frames
while (recorder.isRecording) {
  // Asynchronous read
  const frame = await recorder.read();
  console.log(`Received ${frame.length} audio samples`);
  
  // Or synchronous read
  // const frame = recorder.readSync();
  
  // Process frame (Int16Array with frameLength samples)
  // ... your audio processing logic
}

// Stop recording
recorder.stop();

// Clean up resources
recorder.release();

Architecture

PvRecorder is built around several key components:

  • Native Audio Interface: Cross-platform native modules for audio device access using platform-specific libraries
  • Frame-based Processing: Fixed-size audio frames (Int16Array) for consistent real-time processing
  • Device Management: Automatic device enumeration and selection with platform-specific optimizations
  • Resource Management: Explicit lifecycle management with start/stop/release methods
  • Dual APIs: Both synchronous and asynchronous reading patterns for different use cases
  • Platform Abstraction: Automatic runtime platform detection (Linux, macOS, Windows, Raspberry Pi) and dynamic native library loading based on architecture and OS
  • Error Handling: Comprehensive status code mapping from native library to JavaScript errors with descriptive messages

Capabilities

Audio Recording

Core audio recording functionality providing frame-based audio capture from system audio devices.

/**
 * PvRecorder constructor
 * @param frameLength - Length of audio frames to receive per read call
 * @param deviceIndex - Audio device index (-1 for default device, defaults to -1)
 * @param bufferedFramesCount - Number of frames buffered internally (defaults to 50)
 */
constructor(
  frameLength: number,
  deviceIndex: number = -1,
  bufferedFramesCount: number = 50
);

/** Start recording audio */
start(): void;

/** Stop recording audio */
stop(): void;

/** Asynchronously read a frame of audio data */
read(): Promise<Int16Array>;

/** Synchronously read a frame of audio data */
readSync(): Int16Array;

/** Release resources acquired by PvRecorder */
release(): void;

Device Management

Audio device enumeration and selection capabilities for choosing specific recording devices.

/** 
 * Get list of available audio device names 
 * @throws {Error} When failed to retrieve audio devices
 */
static getAvailableDevices(): string[];

/** 
 * Get name of the currently selected audio device 
 * @throws {Error} When failed to get selected device information
 */
getSelectedDevice(): string;

Configuration and Monitoring

Configuration options and runtime monitoring capabilities for optimal recording performance.

/** Enable or disable debug logging for buffer overflows and silence detection */
setDebugLogging(isDebugLoggingEnabled: boolean): void;

/** Get length of audio frames per read call */
get frameLength(): number;

/** Get audio sample rate used by PvRecorder */
get sampleRate(): number;

/** Get version of the PvRecorder library */
get version(): string;

/** Check if PvRecorder is currently recording */
get isRecording(): boolean;

Error Handling

PvRecorder operations can throw errors for various failure conditions. All errors are thrown as standard JavaScript Error objects with descriptive messages:

  • Invalid constructor parameters (device index, frame length, buffer size)
  • Audio backend/driver failures
  • Device initialization problems
  • Input/output operation failures
  • Memory allocation issues
try {
  const recorder = new PvRecorder(512, invalidDeviceIndex);
  recorder.start();
  const frame = await recorder.read();
} catch (error) {
  console.error("PvRecorder operation failed:", error.message);
  // Handle error appropriately for your use case
}

Platform Support

  • Node.js: 18.0.0 or higher (as specified in package.json engines field)
  • Platforms: Linux (x86_64), macOS (x86_64, arm64), Windows (x86_64, arm64)
  • Raspberry Pi: Models 3, 4, 5 with ARM Cortex-A53, A72, A76 processors
  • Architectures: Automatic platform detection and native library loading

Advanced Usage Examples

Device Selection

import { PvRecorder } from "@picovoice/pvrecorder-node";

// List available audio devices
const devices = PvRecorder.getAvailableDevices();
console.log("Available devices:", devices);

// Select specific device by index
const recorder = new PvRecorder(512, 0); // Use first device
console.log("Selected device:", recorder.getSelectedDevice());

Streaming Audio Processing

import { PvRecorder } from "@picovoice/pvrecorder-node";

const recorder = new PvRecorder(512);
recorder.setDebugLogging(true); // Enable debug logging

recorder.start();

// Process audio in streaming fashion
const processAudio = async () => {
  while (recorder.isRecording) {
    try {
      const frame = await recorder.read();
      
      // Example: Calculate RMS (root mean square) for volume detection
      const rms = Math.sqrt(
        frame.reduce((sum, sample) => sum + sample * sample, 0) / frame.length
      );
      
      if (rms > 1000) { // Threshold for voice activity
        console.log("Voice detected, RMS:", rms);
        // Process speech audio...
      }
    } catch (error) {
      console.error("Audio read error:", error);
      break;
    }
  }
};

processAudio();

// Stop after 10 seconds
setTimeout(() => {
  recorder.stop();
  recorder.release();
}, 10000);

Buffered Recording with Custom Buffer Size

import { PvRecorder } from "@picovoice/pvrecorder-node";

// Use larger internal buffer for high-throughput scenarios
const recorder = new PvRecorder(
  1024,  // Larger frame size
  -1,    // Default device
  100    // Larger buffer (100 frames)
);

console.log(`Sample rate: ${recorder.sampleRate} Hz`);
console.log(`Frame length: ${recorder.frameLength} samples`);
console.log(`Library version: ${recorder.version}`);

recorder.start();

// Synchronous reading for low-latency scenarios
const frames = [];
for (let i = 0; i < 100; i++) {
  frames.push(recorder.readSync());
}

recorder.stop();
recorder.release();

console.log(`Recorded ${frames.length} frames of audio`);

Error Handling and Validation

import { PvRecorder } from "@picovoice/pvrecorder-node";

// Test for invalid constructor parameters as shown in test suite
try {
  // Invalid device index (must be >= -1)
  const recorder1 = new PvRecorder(512, -2);
} catch (error) {
  console.error("Invalid device index:", error.message);
}

try {
  // Invalid frame length (must be > 0)
  const recorder2 = new PvRecorder(0, 0);
} catch (error) {
  console.error("Invalid frame length:", error.message);
}

try {
  // Invalid buffered frames count (must be > 0)
  const recorder3 = new PvRecorder(512, 0, 0);
} catch (error) {
  console.error("Invalid buffered frames count:", error.message);
}

// Valid usage with proper error handling
const recorder = new PvRecorder(512, 0);

// Test recorder state management
console.log("Before start:", recorder.isRecording); // false
recorder.start();
console.log("After start:", recorder.isRecording);  // true

recorder.stop();
console.log("After stop:", recorder.isRecording);   // false

recorder.release();