Skip to main content

Overview

The VoiceActivityDetector class is an abstract base class for implementing Voice Activity Detection (VAD). VAD is used to identify segments of audio that contain human speech versus silence or background noise. WhisperKit uses VAD to intelligently chunk long audio files for more efficient transcription.

Class Definition

Initializer

Int
default:"16000"
Sample rate of the audio signal in Hz
Int
Length of each analysis frame in samples
Int
default:"0"
Number of samples overlapping between consecutive frames

Properties

Int
The sample rate of the audio signal in samples per second (typically 16000 Hz for WhisperKit)
Int
The length of each analysis frame in samples
Int
The number of samples overlapping between consecutive frames. Useful for catching speech at frame boundaries.

Methods

voiceActivity(in:)

Analyzes audio waveform to detect voice activity. Must be implemented by subclasses.
[Float]
Array of audio samples to analyze
[Bool]
Array where true indicates voice activity and false indicates silence. Each element corresponds to one frame.

voiceActivityAsync(in:)

Async version of voice activity detection.
[Float]
Array of audio samples to analyze
[Bool]
Array indicating voice activity per frame

calculateActiveChunks(in:)

Identifies continuous segments of audio containing voice activity.
[Float]
Array of audio samples
[(startIndex: Int, endIndex: Int)]
Array of tuples containing start and end sample indices for each active segment

voiceActivityIndexToAudioSampleIndex(_:)

Converts a voice activity frame index to an audio sample index.
Int
Voice activity frame index
Int
Corresponding audio sample index

voiceActivityIndexToSeconds(_:)

Converts a voice activity frame index to time in seconds.
Int
Voice activity frame index
Float
Corresponding time in seconds

findLongestSilence(in:)

Finds the longest continuous period of silence.
[Bool]
Voice activity detection results
(startIndex: Int, endIndex: Int)?
Start and end indices of the longest silence, or nil if no silence found

voiceActivityClipTimestamps(in:)

Generates timestamp pairs for active audio segments.
[Float]
Flat array of timestamps: [start1, end1, start2, end2, …]

calculateNonSilentSeekClips(in:)

Calculates seek positions for non-silent segments.
[(start: Int, end: Int)]
Array of seek clip start/end positions in samples

calculateSeekTimestamps(in:)

Calculates timestamp pairs for seeking through active segments.
[(startTime: Float, endTime: Float)]
Array of start/end timestamp pairs in seconds

Built-in Implementation: EnergyVAD

WhisperKit includes a built-in energy-based VAD implementation:

How EnergyVAD Works

EnergyVAD detects voice activity by:
  1. Dividing audio into frames
  2. Calculating RMS energy for each frame
  3. Comparing energy against a threshold
  4. Frames above threshold are marked as containing voice

Custom Implementation

To create a custom VAD, subclass VoiceActivityDetector and implement voiceActivity(in:):

Example Usage

Basic Voice Activity Detection

Find Active Segments

Use VAD with WhisperKit

Visualize Voice Activity

Find Silence for Split Points

Custom Energy Threshold

Process Live Audio with VAD

Best Practices

  1. Frame Length Selection: Use 20-100ms frames (320-1600 samples at 16kHz). Shorter frames = more responsive but noisier.
  2. Threshold Tuning: Adjust energy threshold based on your audio:
    • Clean recordings: 0.01-0.02
    • Noisy environments: 0.03-0.05
    • Test with representative samples
  3. Overlap for Continuity: Use frame overlap (10-20ms) to avoid missing speech at frame boundaries.
  4. Post-Processing: Apply smoothing to reduce false positives:
  5. Chunking Strategy: When using .vad chunking strategy with WhisperKit, ensure your VAD is tuned to avoid creating too many tiny segments.