How Meetily Handles Audio Resampling for Different Sample Rates

Meetily normalizes all incoming audio to a uniform 48 kHz sample rate using a DynamicResampler that implements linear interpolation, ensuring consistent processing across diverse capture devices.

Meetily, an open-source meeting transcription tool developed by Zackriya-Solutions, standardizes audio processing by converting all input streams to a target sample rate before mixing and transcription. The audio resampling logic resides in the audio_v2 module and gracefully handles runtime device switches without interrupting the recording pipeline.

Meetily's Audio Resampling Architecture

The architecture centers on normalization. Regardless of whether a microphone captures at 44.1 kHz, 48 kHz, or 96 kHz, the pipeline forces every buffer to 48 kHz before it reaches the mixer or voice-activity detector (VAD).

At the core is the DynamicResampler struct defined in frontend/src-tauri/src/audio_v2/resampler.rs. This component provides a resample method that accepts raw PCM buffers along with their native and target sample rates, performing real-time conversion on a per-chunk basis.

The current implementation uses a lightweight linear interpolation algorithm. While the source code contains TODO markers indicating plans for a more sophisticated phase-3 implementation, the existing logic reliably bridges sample rate mismatches in production environments.

The DynamicResampler Implementation

Linear Interpolation Fallback

The resampler is instantiated with a fixed target rate—typically 48,000 Hz—and processes incoming audio frame-by-frame.

// From frontend/src-tauri/src/audio_v2/resampler.rs
let mut resampler = DynamicResampler::new(48_000);

The resample method signature accepts the source buffer, original sample rate, and destination sample rate:

let resampled_buffer = resampler.resample(&audio_chunk, native_rate, 48_000);

This design allows the pipeline to defer resampling until necessary, minimizing CPU overhead for devices that already capture at the target rate.

Audio Pipeline Integration

Capture and Normalization

When the recorder module opens an audio stream, it queries the device's native sample rate. If the rate differs from 48 kHz, the pipeline instantiates a DynamicResampler and normalizes each buffer before forwarding it to the mixing ring buffer.

// Conceptual flow based on pipeline.rs and recorder.rs integration
if let Some(rate) = incoming_stream.sample_rate {
    if rate != 48_000 {
        let normalized = resampler.resample(&buffer, rate, 48_000);
        mixer.push(normalized);
    } else {
        mixer.push(buffer);
    }
}

Runtime Rate Changes

Because the resampler operates on individual chunks rather than maintaining persistent state across the entire stream, Meetily can handle runtime rate changes seamlessly. When a user switches from a 44.1 kHz headset to a 48 kHz USB microphone, the pipeline simply adjusts the from_rate parameter in subsequent resample calls without dropping the recording session.

Key Source Files

Summary

  • Meetily enforces a uniform 48 kHz internal sample rate to simplify downstream audio processing.
  • The DynamicResampler in audio_v2/resampler.rs handles conversion via linear interpolation.
  • Resampling occurs on a per-chunk basis, enabling seamless handling of runtime device switches.
  • Devices already capturing at 48 kHz bypass the resampler to minimize CPU usage.
  • The modular design allows future upgrades to the resampling algorithm without changing the pipeline interface.

Frequently Asked Questions

What sample rate does Meetily use internally?

Meetily standardizes all audio processing to 48 kHz (48,000 Hz). This target rate is hardcoded in the pipeline constants and used by the DynamicResampler as the destination sample rate for all conversion operations.

How does Meetily handle devices with different native sample rates?

When a device provides audio at a rate other than 48 kHz—such as 44.1 kHz or 96 kHz—the pipeline passes the buffer to the DynamicResampler::resample() method. This method performs linear interpolation to generate a 48 kHz version of the audio before it enters the mixing or transcription stages.

Is the current resampling implementation optimized for production?

The current implementation is a functional linear interpolation fallback. While the source code in resampler.rs contains explicit TODO comments indicating plans for a more sophisticated algorithm in phase-3 development, the existing code is production-ready and handles real-time conversion without blocking the audio thread.

Where is the resampling logic located in the codebase?

The core resampling logic resides in frontend/src-tauri/src/audio_v2/resampler.rs, which defines the DynamicResampler struct. Integration with the capture pipeline occurs in frontend/src-tauri/src/audio/pipeline.rs, while device-specific sample rate detection happens in frontend/src-tauri/src/audio_v2/recorder.rs.

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 →