How Meetily Handles Audio Resampling to Maintain Consistent 48kHz Sample Rates

Meetily normalizes every incoming audio stream to a uniform 48kHz sample rate using a DynamicResampler that applies linear interpolation, ensuring that downstream mixing, voice activity detection, and transcription components receive consistent PCM data regardless of the input device's native configuration.

The Meetily audio pipeline enforces sample rate consistency at the boundary between capture and processing. According to the source code in the audio_v2 module, any audio buffer that does not match the target 48kHz rate is transparently converted before entering the mixing ring buffer or transcription engine. This architectural decision simplifies downstream DSP operations while allowing the application to gracefully handle heterogeneous audio hardware.

The DynamicResampler Implementation

The core resampling logic resides in [frontend/src-tauri/src/audio_v2/resampler.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio_v2/resampler.rs). The DynamicResampler struct is initialized with a fixed target rate and provides a per-chunk resampling interface.

The current implementation uses a linear interpolation algorithm as a lightweight fallback. While the source contains explicit TODO markers indicating plans for a more sophisticated phase-3 resampler, the existing code already guarantees sample-accurate conversion for real-time conferencing needs.

Initializing the Resampler

When the audio pipeline starts, it instantiates a resampler configured for the mandatory output rate:

// Create a resampler targeting 48kHz
let mut resampler = DynamicResampler::new(48_000);

This initialization occurs before any device capture begins, ensuring the resampler is ready to handle the first audio frame.

The Resampling Algorithm

The resample method accepts a slice of f32 PCM samples along with the source and destination sample rates. It calculates resampling ratios and applies linear interpolation to generate the target buffer:

// audio_chunk: &[f32] captured at native_rate (e.g., 44.1kHz)
// target_rate: 48_000 (enforced constant)
let normalized_buffer = resampler.resample(&audio_chunk, native_rate, target_rate);

As implemented in lines 25–53 of resampler.rs, this method handles fractional resampling ratios, allowing seamless conversion from common rates like 44.1kHz, 32kHz, or 96kHz down to (or up to) the 48kHz standard.

Pipeline Integration and Runtime Adaptability

The resampler integrates into the capture pipeline in [frontend/src-tauri/src/audio/pipeline.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs). Before audio reaches the mixer or VAD (Voice Activity Detection) stages, the pipeline inspects the stream's sample rate metadata.

Conditional Resampling Logic

The pipeline checks each incoming buffer's sample rate against the 48kHz constant:

if let Some(rate) = incoming_stream.sample_rate {
    if rate != 48_000 {
        // Normalize to target rate before processing
        let resampled = resampler.resample(&buffer, rate, 48_000);
        mixer.push(resampled);
    } else {
        // Native 48kHz streams pass through unchanged
        mixer.push(buffer);
    }
}

This conditional approach minimizes CPU overhead for devices that already capture at 48kHz while guaranteeing consistency for all other sources.

Handling Runtime Rate Changes

A key advantage of the DynamicResampler design is its ability to handle runtime sample rate switches without pipeline restart. When a user switches audio devices mid-session, the resampler detects the new source rate on the next chunk and adjusts its interpolation ratios accordingly. This prevents audio glitches or transcription errors during hardware transitions.

Key Source Files

The following modules collaborate to maintain the 48kHz standard:

Summary

  • Meetily enforces a 48kHz standard for all internal audio processing to simplify mixing and transcription algorithms.
  • The DynamicResampler in audio_v2/resampler.rs handles conversion via linear interpolation, with architecture ready for future algorithmic upgrades.
  • Resampling occurs per-chunk in the pipeline, allowing transparent handling of heterogeneous input devices and runtime hardware switches.
  • Devices already capturing at 48kHz pass through the pipeline with zero conversion overhead.

Frequently Asked Questions

Does Meetily support audio devices with sample rates other than 48kHz?

Yes. Meetily explicitly supports common rates including 44.1kHz, 32kHz, and 96kHz. The DynamicResampler converts these to 48kHz transparently during the capture phase, so users can connect any standard audio device without manual configuration.

What happens if I switch audio devices during a meeting?

The pipeline detects the new device's sample rate on the next audio chunk and invokes the resampler with the updated source rate. This dynamic adaptation prevents dropouts or pitch shifts when switching between devices with different native rates, such as moving from a 44.1kHz headset to a 48kHz microphone.

Is the current linear interpolation resampler production-ready?

According to the source code, the linear interpolation implementation is functional and actively used, though marked with TODO comments for future enhancement. The current algorithm provides sufficient quality for speech transcription and conferencing while maintaining low CPU usage, with planned upgrades to more sophisticated filter-based resampling in future releases.

Where is the 48kHz target rate defined in the codebase?

The target sample rate is hardcoded as 48_000 in the DynamicResampler::new() constructor calls within the pipeline initialization code. While audio_v2 uses this constant throughout, the specific enforcement logic resides in the pipeline's buffer handling routines where incoming_stream.sample_rate is compared against the literal 48_000 value before mixing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →