{"_id":"@aid-on/vad","_rev":"3-b71abd67b8722a77fea99a71237b5ebc","name":"@aid-on/vad","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.1":{"name":"@aid-on/vad","version":"0.1.1","_id":"@aid-on/vad@0.1.1","maintainers":[{"name":"aid-on","email":"hiromi.motodera@aid-on.org"}],"dist":{"shasum":"c9059800b690534f7fd28b0cc7e89de1fbc3e00c","tarball":"https://registry.npmjs.org/@aid-on/vad/-/vad-0.1.1.tgz","fileCount":5,"integrity":"sha512-lMUsiQ/jDi9oezfMLOIh3z3MTQxnvgvJWjPuhCGs97cJjoxkQlEByyNozCLzSHX667Y0g9I1B43uevD3+rdTTg==","signatures":[{"sig":"MEYCIQCM3B20l634Q2txgofcLrFDNShpUCOoJAu1C0yt5KNEQAIhAOKwAnYgU1vW5AV4tVXSX8Rx/l/J97rCW02U8u9zecbG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23047},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"45f550388ad3243b44a0c55acee0004baad4e91e","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"aid-on","email":"hiromi.motodera@aid-on.org"},"_npmVersion":"10.8.2","description":"Silero VAD wrapper for browser - voice activity detection","directories":{},"_nodeVersion":"20.19.6","dependencies":{"onnxruntime-web":"1.14.0","@ricky0123/vad-web":"0.0.18","@shiguredo/rnnoise-wasm":"^2025.1.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0"},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/vad_0.1.1_1771341160451_0.040373648393942085","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@aid-on/vad","version":"0.1.2","_id":"@aid-on/vad@0.1.2","maintainers":[{"name":"aid-on","email":"hiromi.motodera@aid-on.org"}],"dist":{"shasum":"0f235491b24e064e1aaefc4b8472f8afa910d41a","tarball":"https://registry.npmjs.org/@aid-on/vad/-/vad-0.1.2.tgz","fileCount":9,"integrity":"sha512-y1DAG8B60tgiU4x0FNxZ098C0p7IOkHyujc+bFODM3L4RDxRSTXaG/6SO9paK56gWtu4YihsfgTENjPlBPBO/g==","signatures":[{"sig":"MEQCIE7Hc2pyEc6wkbJl2Esx5NTwkqEgj6gUEpHZtXIQqPDaAiA8++oTcBgIjjPerC+i5X4l7sbanHt7uF7EnKO4W/4peQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20667},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"45f550388ad3243b44a0c55acee0004baad4e91e","scripts":{"test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"aid-on","email":"hiromi.motodera@aid-on.org"},"_npmVersion":"10.8.2","description":"Silero VAD wrapper for browser - voice activity detection","directories":{},"_nodeVersion":"20.19.6","dependencies":{"onnxruntime-web":"1.14.0","@ricky0123/vad-web":"0.0.18","@shiguredo/rnnoise-wasm":"^2025.1.5"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/vad_0.1.2_1771343125768_0.7148258539413186","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@aid-on/vad","version":"0.1.3","description":"Silero VAD wrapper for browser - voice activity detection","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest"},"dependencies":{"@ricky0123/vad-web":"0.0.18","@shiguredo/rnnoise-wasm":"^2025.1.5","onnxruntime-web":"1.14.0"},"devDependencies":{"typescript":"^5.6.0","vitest":"^4.0.18"},"engines":{"node":">=18.0.0"},"_id":"@aid-on/vad@0.1.3","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-5R9Qvv14m3oBu2dsq0mp2V2ZGeLKpqoIakSUKUgrGy3djc4/PqxxcJ4zpMNzeKDqCbIoaPzIxSGHsV0CrwPwSQ==","shasum":"6562d5019bb30054622e1cd3fa66a67d8ff3817c","tarball":"https://registry.npmjs.org/@aid-on/vad/-/vad-0.1.3.tgz","fileCount":11,"unpackedSize":38989,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDUDIWn0jU1TOU5/ahi+CxeVnOUNqHNot9tZ7FIAfPuswIgBix3yRm6OI0ojTB3fMJcWScjxnmuMCFnyYUMVGn3dJ8="}]},"_npmUser":{"name":"aid-on","email":"hiromi.motodera@aid-on.org"},"directories":{},"maintainers":[{"name":"aid-on","email":"hiromi.motodera@aid-on.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vad_0.1.3_1771435136327_0.951857782029135"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-17T15:12:40.353Z","modified":"2026-02-18T17:18:56.583Z","0.1.1":"2026-02-17T15:12:40.611Z","0.1.2":"2026-02-17T15:45:25.919Z","0.1.3":"2026-02-18T17:18:56.471Z"},"description":"Silero VAD wrapper for browser - voice activity detection","maintainers":[{"name":"aid-on","email":"hiromi.motodera@aid-on.org"}],"readme":"# @aid-on/vad\n\n<div align=\"center\">\n\n[![npm version](https://img.shields.io/npm/v/@aid-on/vad.svg?style=flat-square&color=00DC82)](https://www.npmjs.com/package/@aid-on/vad)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n\n<br />\n\n<h3>\n<b>vad</b> - Browser Voice Activity Detection with Noise Suppression\n</h3>\n\n<p align=\"center\">\n<b>Know when your user is speaking.</b><br/>\nSilero VAD with built-in RNNoise suppression, designed for real-time browser audio applications.\n</p>\n\n<br/>\n\n[**日本語**](./README.ja.md) | **English**\n\n<br/>\n\n</div>\n\n## Why @aid-on/vad?\n\nBuilding voice-driven browser applications means solving two hard problems: detecting when the user is actually speaking, and filtering out background noise before processing. This package solves both:\n\n- **Silero VAD** - State-of-the-art speech detection model via ONNX Runtime\n- **RNNoise suppression** - Optional noise reduction pipeline using WebAssembly\n- **Simple callback API** - `onSpeechStart`, `onSpeechEnd`, `onFrameProcessed`, `onVADMisfire`\n- **WAV conversion** - Built-in `audioToWav()` for sending captured audio to STT APIs\n- **Auto CDN versioning** - Pinned, tested versions of vad-web and ONNX Runtime loaded from CDN\n- **Zero configuration** - Sensible defaults, start detecting speech in 5 lines of code\n\n## Installation\n\n```bash\nnpm install @aid-on/vad\n```\n\n**Note:** This package is browser-only. It requires WebAssembly support and access to `navigator.mediaDevices.getUserMedia`.\n\n## Quick Start\n\n```typescript\nimport { createVAD } from \"@aid-on/vad\";\n\nconst vad = await createVAD({\n  onSpeechStart: () => {\n    console.log(\"User started speaking\");\n  },\n  onSpeechEnd: (audio) => {\n    // audio is Float32Array at 16kHz\n    console.log(`Captured ${audio.length} samples`);\n  },\n});\n\nvad.start();\n```\n\n## API Reference\n\n### `createVAD(callbacks, config?)`\n\nCreate a new VAD instance. Requests microphone access, loads the Silero VAD model, and optionally sets up the RNNoise noise suppression pipeline.\n\n```typescript\nimport { createVAD } from \"@aid-on/vad\";\n\nconst vad = await createVAD(\n  {\n    onSpeechStart: () => {\n      // User began speaking\n      updateUI(\"listening\");\n    },\n    onSpeechEnd: (audio: Float32Array) => {\n      // User stopped speaking\n      // audio contains the captured speech at 16kHz mono\n      sendToSTT(audio);\n    },\n    onFrameProcessed: (probability: number) => {\n      // Called on each audio frame with speech probability (0-1)\n      updateMeter(probability);\n    },\n    onVADMisfire: () => {\n      // Speech was too short (below minSpeechFrames threshold)\n      console.log(\"Too short, ignoring\");\n    },\n  },\n  {\n    positiveSpeechThreshold: 0.5,\n    negativeSpeechThreshold: 0.35,\n    minSpeechFrames: 3,\n    noiseSuppression: true,\n  }\n);\n```\n\n**Returns:** `Promise<VADInstance>`\n\n### VADInstance\n\nThe object returned by `createVAD()`.\n\n| Method/Property | Type | Description |\n|----------------|------|-------------|\n| `start()` | `() => void` | Start listening for speech |\n| `pause()` | `() => void` | Pause listening (retains resources) |\n| `listening` | `boolean` | Whether VAD is currently listening |\n| `destroy()` | `() => void` | Stop listening, release microphone, and clean up all resources |\n\n```typescript\n// Lifecycle\nvad.start();              // Begin speech detection\nconsole.log(vad.listening); // true\n\nvad.pause();              // Temporarily stop\nconsole.log(vad.listening); // false\n\nvad.start();              // Resume\n\nvad.destroy();            // Fully clean up (cannot restart after this)\n```\n\n### `audioToWav(samples, sampleRate?)`\n\nConvert a `Float32Array` of audio samples to a WAV `Blob`. Useful for sending captured speech to STT APIs.\n\n```typescript\nimport { audioToWav } from \"@aid-on/vad\";\n\nconst vad = await createVAD({\n  onSpeechEnd: (audio) => {\n    // Convert to WAV for uploading to an STT API\n    const wavBlob = audioToWav(audio, 16000);\n\n    const formData = new FormData();\n    formData.append(\"file\", wavBlob, \"speech.wav\");\n\n    fetch(\"/api/transcribe\", {\n      method: \"POST\",\n      body: formData,\n    });\n  },\n});\n```\n\n**Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `samples` | `Float32Array` | required | Audio sample data (values between -1 and 1) |\n| `sampleRate` | `number` | `16000` | Sample rate in Hz |\n\n**Returns:** `Blob` with MIME type `audio/wav`\n\nThe output is a standard PCM WAV file: mono, 16-bit, with the specified sample rate.\n\n### Configuration\n\n#### VADConfig\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `positiveSpeechThreshold` | `number` | `0.5` | Probability threshold to detect speech start (0-1) |\n| `negativeSpeechThreshold` | `number` | `0.35` | Probability threshold to detect speech end (0-1) |\n| `minSpeechFrames` | `number` | `3` | Minimum frames to count as speech (prevents misfires) |\n| `preSpeechPadFrames` | `number` | `3` | Number of frames to include before speech start |\n| `redemptionFrames` | `number` | `8` | Frames to wait before considering speech ended |\n| `noiseSuppression` | `boolean` | `true` | Enable RNNoise-based noise suppression |\n\n#### VADCallbacks\n\n| Callback | Type | Description |\n|----------|------|-------------|\n| `onSpeechStart` | `() => void` | Called when speech is detected |\n| `onSpeechEnd` | `(audio: Float32Array) => void` | Called when speech ends, with captured audio data |\n| `onFrameProcessed` | `(probability: number) => void` | Called on each frame with speech probability (0-1) |\n| `onVADMisfire` | `() => void` | Called when detected speech was too short |\n\n## Real-World Example: Voice Chat with STT\n\n```typescript\nimport { createVAD, audioToWav } from \"@aid-on/vad\";\n\n// Create VAD with noise suppression for a voice chat application\nconst vad = await createVAD(\n  {\n    onSpeechStart: () => {\n      statusIndicator.textContent = \"Listening...\";\n      statusIndicator.classList.add(\"active\");\n    },\n    onSpeechEnd: async (audio) => {\n      statusIndicator.textContent = \"Processing...\";\n\n      // Convert to WAV and send to STT\n      const wavBlob = audioToWav(audio, 16000);\n      const formData = new FormData();\n      formData.append(\"file\", wavBlob, \"speech.wav\");\n\n      const response = await fetch(\"/api/transcribe\", {\n        method: \"POST\",\n        body: formData,\n      });\n\n      const { text } = await response.json();\n      chatMessages.append(createMessage(text, \"user\"));\n\n      statusIndicator.textContent = \"Ready\";\n      statusIndicator.classList.remove(\"active\");\n    },\n    onFrameProcessed: (probability) => {\n      // Update a visual speech probability meter\n      meterElement.style.width = `${probability * 100}%`;\n    },\n    onVADMisfire: () => {\n      statusIndicator.textContent = \"Ready\";\n    },\n  },\n  {\n    positiveSpeechThreshold: 0.6,   // Slightly higher for noisy environments\n    negativeSpeechThreshold: 0.35,\n    minSpeechFrames: 5,             // Require longer speech to trigger\n    redemptionFrames: 10,           // Wait longer before cutting off\n    noiseSuppression: true,         // Enable RNNoise\n  }\n);\n\n// Start/stop via button\ntoggleButton.addEventListener(\"click\", () => {\n  if (vad.listening) {\n    vad.pause();\n    toggleButton.textContent = \"Start\";\n  } else {\n    vad.start();\n    toggleButton.textContent = \"Stop\";\n  }\n});\n\n// Cleanup on page unload\nwindow.addEventListener(\"beforeunload\", () => {\n  vad.destroy();\n});\n```\n\n## Architecture\n\nThe audio processing pipeline:\n\n```\nMicrophone (48kHz)\n  |\n  +-- [RNNoise] (optional, WebAssembly noise suppression)\n  |     480-sample frames at 48kHz\n  |\n  +-- Silero VAD (ONNX Runtime, speech probability per frame)\n  |\n  +-- Speech segmentation\n        |\n        +-- onSpeechStart()\n        +-- onSpeechEnd(Float32Array @ 16kHz)\n        +-- onVADMisfire()\n```\n\n**CDN Dependencies (loaded at runtime):**\n\n| Package | Version | Purpose |\n|---------|---------|---------|\n| `@ricky0123/vad-web` | `0.0.18` | Silero VAD model and worklet |\n| `onnxruntime-web` | `1.14.0` | ONNX Runtime for WebAssembly inference |\n| `@shiguredo/rnnoise-wasm` | `^2025.1.5` | RNNoise noise suppression (bundled) |\n\n## License\n\nMIT (C) Aid-On\n\n---\n\n<div align=\"center\">\n\n**Real-time voice detection for the browser. Hear what matters.**\n\n<br/>\n\n[NPM](https://www.npmjs.com/package/@aid-on/vad) •\n[GitHub](https://github.com/Aid-On/aid-on-platform)\n\n</div>\n","readmeFilename":"README.md"}