# Meetily Recording Path and Transcription Path: Understanding the Difference

> Understand the difference between Meetily recording path and transcription path. Learn how Meetily processes audio for recording and real-time transcription.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: understanding
- Published: 2026-07-20

---

**Meetily processes captured audio through two distinct pipelines: the recording path writes full mixed microphone and system audio to a WAV file at the original sample rate, while the transcription path filters the same mixed audio through Voice Activity Detection (VAD), extracts only speech segments, and downsamples them to 16 kHz for real-time Whisper processing.**

Meetily is an open-source meeting assistant built by Zackriya-Solutions that captures both microphone and system audio to create complete meeting records. Understanding the distinction between the **recording path** and **transcription path** is crucial for developers customizing audio processing or debugging transcription accuracy. Both paths originate in [`frontend/src-tauri/src/audio/pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs), sharing the initial capture and mixing stages before diverging to serve different end goals—one preserves the full audio experience while the other optimizes for speech recognition.

## The Shared Foundation: Audio Capture and Mixing

Both paths begin in the unified audio pipeline implemented in [`frontend/src-tauri/src/audio/pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs). The `AudioCapture` module grabs raw streams from the microphone and system audio, applying noise suppression, high-pass filtering, and loudness normalization to the microphone input.

These synchronized streams accumulate in an `AudioMixerRingBuffer`. When a 50 ms window is available, the `extract_window` method returns two synchronized buffers that are blended by `ProfessionalAudioMixer::mix_window`. This mixing occurs without aggressive ducking—the microphone audio remains normalized while system audio stays at natural levels.

After mixing, the pipeline splits into two parallel processing routes.

## The Recording Path: Full-Fidelity Archival

The **recording path** preserves exactly what the user hears by writing the complete mixed audio stream to disk.

Once the mixed window is built, the pipeline checks for the presence of `recording_sender_for_mixed`. If configured, it wraps the mixed buffer in an `AudioChunk` struct and emits it via the recording sender. According to the Meetily source code, this occurs at lines 68-78 of [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs).

The `AudioChunk` sent to the recording path maintains the original `sample_rate` (typically 48 kHz) and includes metadata identifying it as mixed microphone audio. The `RecordingSaver` component (defined in [`frontend/src-tauri/src/audio/recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_saver.rs)) receives these chunks and appends them directly to the output WAV file.

Key characteristics of the recording path:

- Retains all audio content, including silence, background noise, and system sounds
- Uses the original capture sample rate for maximum quality
- Writes sequentially to disk via `recording_sender_for_mixed.send(recording_chunk)`

## The Transcription Path: Optimized Speech Processing

The **transcription path** optimizes for Whisper speech recognition by stripping non-speech segments and standardizing the audio format.

### Voice Activity Detection (VAD) Processing

After mixing, the same mixed buffer passes through `ContinuousVadProcessor` (implemented in [`frontend/src-tauri/src/audio/vad.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/vad.rs)). This processor identifies speech segments and discards silence, significantly reducing the data volume sent to the transcription engine.

The VAD processing and subsequent emission to the transcription sender occurs at lines 85-108 of [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs). Each detected speech segment is extracted with its precise timestamp, creating discrete chunks of speech-only audio.

### Downsampling for Whisper Optimization

Unlike the recording path, transcription chunks undergo resampling. The pipeline creates new `AudioChunk` instances (lines 44-50) containing the speech segment samples downsampled to **16 kHz**, which is the optimal input rate for OpenAI's Whisper model.

These chunks travel via `transcription_sender` to the engine defined in [`frontend/src-tauri/src/audio/transcription/engine.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/transcription/engine.rs). The engine emits Tauri events (`transcript-update`) that the frontend consumes to display live captions.

## Side-by-Side Comparison

| Aspect | Recording Path | Transcription Path |
|--------|----------------|--------------------|
| **Primary Goal** | Archive complete mixed audio for playback | Extract speech for real-time transcription |
| **Processing Stage** | Direct output from mixer | Mixer output → VAD filter |
| **Audio Content** | Full mixed stream (mic + system) | Speech-only segments |
| **Sample Rate** | Original (e.g., 48 kHz) | Downsampled to 16 kHz |
| **Sender Channel** | `recording_sender_for_mixed` | `transcription_sender` |
| **Destination** | `RecordingSaver` → `.wav` file | Whisper Engine → UI text |
| **Code Location** | [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs) lines 68-78 | [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs) lines 85-108 |

## Implementation in the Codebase

The wiring of both paths occurs during pipeline initialization in `AudioPipelineManager::start` (lines 94-97 of [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs)). Here, the manager optionally sets the recording sender while always configuring the transcription sender.

```rust
// Starting the pipeline (recording + transcription)
let mut manager = AudioPipelineManager::new();
manager.start(
    recording_state.clone(),
    transcription_sender.clone(),
    /*target_chunk_duration_ms=*/ 0,
    /*sample_rate=*/ 48000,
    Some(recording_sender.clone()),          // <- enables recording path
    mic_name.clone(),
    mic_kind,
    system_name.clone(),
    system_kind,
)?;

```

Inside the `AudioPipeline::run` method, the divergence is explicit:

```rust
// Inside AudioPipeline::run – the two diverging paths
if let Some((mic_win, sys_win)) = self.ring_buffer.extract_window() {
    // 1️⃣ Mix the windows
    let mixed = self.mixer.mix_window(&mic_win, &sys_win);

    // ──► Recording path (writes to .wav)
    if let Some(ref rec_sender) = self.recording_sender_for_mixed {
        let rec_chunk = AudioChunk {
            data: mixed.clone(),
            sample_rate: self.sample_rate,
            timestamp: chunk.timestamp,
            chunk_id: self.chunk_id_counter,
            device_type: DeviceType::Microphone,
        };
        let _ = rec_sender.send(rec_chunk);
    }

    // ──► Transcription path (VAD → Whisper)
    if let Ok(segments) = self.vad_processor.process_audio(&mixed) {
        for seg in segments {
            let trans_chunk = AudioChunk {
                data: seg.samples,
                sample_rate: 16_000,
                timestamp: seg.start_timestamp_ms / 1_000.0,
                chunk_id: self.chunk_id_counter,
                device_type: DeviceType::Microphone,
            };
            let _ = self.transcription_sender.send(trans_chunk);
        }
    }
}

```

Supporting files that define this behavior include:

- [`frontend/src-tauri/src/audio/recording_manager.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_manager.rs) – Orchestrates pipeline start/stop
- [`frontend/src-tauri/src/audio/recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_saver.rs) – Handles WAV file writing
- [`frontend/src-tauri/src/audio/vad.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/vad.rs) – Implements speech detection
- [`frontend/src-tauri/src/audio/transcription/engine.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/transcription/engine.rs) – Interfaces with Whisper
- [`frontend/src-tauri/src/audio/capture/microphone.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/capture/microphone.rs) and [`system.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system.rs) – Raw audio capture sources

## Summary

- **Shared Origin**: Both paths start from the same mixed audio window in [`frontend/src-tauri/src/audio/pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs), ensuring synchronization between recording and transcription.
- **Recording Path**: Writes full-fidelity mixed audio at the original sample rate to a WAV file via `recording_sender_for_mixed`, preserving the complete meeting audio including non-speech segments.
- **Transcription Path**: Filters mixed audio through `ContinuousVadProcessor` to extract speech, downsamples to 16 kHz, and streams to Whisper via `transcription_sender` for live captioning.
- **Efficiency**: By separating archival quality from transcription optimization, Meetily avoids redundant processing while maintaining high accuracy in both domains.

## Frequently Asked Questions

### Why does Meetily use two separate paths instead of transcribing the recorded WAV file later?

Meetily processes transcription in real-time to provide live captions during meetings. The **transcription path** operates on a continuous stream with VAD filtering and downsampling to minimize latency and CPU usage, whereas the **recording path** maintains full quality for the final archive. Transcribing the high-fidelity WAV file afterward would introduce significant delays and require re-processing the entire audio stream.

### What happens to audio that the VAD filters out in the transcription path?

Non-speech audio detected by `ContinuousVadProcessor` is simply discarded and never sent to the Whisper engine. However, this audio is still preserved in the **recording path**, ensuring that background sounds, silence, and system audio remain available in the final WAV file even if they do not appear in the transcript.

### Can I disable the recording path while keeping transcription active?

Yes. The recording path is optional and controlled by the presence of `recording_sender_for_mixed`. When initializing the pipeline via `AudioPipelineManager::start`, passing `None` for the recording sender (or omitting it) disables the recording functionality while allowing the transcription path to continue operating normally via `transcription_sender`.

### Why is the transcription path limited to 16 kHz when the recording uses 48 kHz?

OpenAI's Whisper model is trained and optimized for 16 kHz audio input. Down-sampling from 48 kHz to 16 kHz in the **transcription path** reduces data volume by 66% without losing speech recognition accuracy, significantly improving processing speed and reducing memory usage. The **recording path** retains 48 kHz to preserve audio quality for human listeners.