# How Meetily Performs Real-Time Audio Level Monitoring: A Technical Deep Dive

> Discover how Meetily achieves real-time audio level monitoring. Explore its three-layer architecture, Rust audio processing, and RMS/peak level calculations via CPAL streams and Tauri events.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: deep-dive
- Published: 2026-07-11

---

**Meetily performs real-time audio level monitoring using a three-layer architecture that bridges TypeScript frontend code with Rust audio processing, calculating RMS and peak levels every 100ms via CPAL streams and Tauri events.**

Meetily, an open-source meeting assistant from the [Zackriya-Solutions/meetily](https://github.com/Zackriya-Solutions/meetily) repository, implements sophisticated real-time audio level monitoring to visualize microphone input during calls. This system leverages Rust's performance for low-latency audio processing while maintaining a reactive TypeScript frontend through Tauri's event system. The architecture processes raw audio samples to compute RMS and peak levels, transmitting updates to the UI every 100 milliseconds.

## Three-Layer Architecture for Real-Time Audio Level Monitoring

### Tauri Command Layer

The entry point for real-time audio level monitoring resides in [`frontend/src-tauri/src/lib.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/lib.rs). This file exposes three primary Tauri commands that handle the lifecycle of the monitoring system:

- `start_audio_level_monitoring` – Initializes monitoring for specified device names
- `stop_audio_level_monitoring` – Terminates active monitoring sessions  
- `is_audio_level_monitoring` – Returns the current monitoring state

The `start_audio_level_monitoring` command accepts a vector of device names from the frontend and forwards the request to the audio subsystem:

```rust
#[tauri::command]
async fn start_audio_level_monitoring<R: Runtime>(app: AppHandle<R>, device_names: Vec<String>) -> Result<(), String> {
    audio::simple_level_monitor::start_monitoring(app, device_names).await
        .map_err(|e| format!("Failed to start audio level monitoring: {}", e))
}

```

### Audio Monitor Module

The core implementation lives in [`frontend/src-tauri/src/audio/level_monitor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/level_monitor.rs). This module handles **device discovery**, **stream management**, **sample processing**, and **metric calculation** using the following workflow:

1. **Device Discovery**: Uses `cpal::default_host()` to enumerate available input devices and matches them against the names supplied by the UI
2. **Stream Construction**: Builds input streams via `device.build_input_stream` with callbacks that receive raw audio samples in native format (F32, I16, or U16)
3. **Channel Processing**: Converts multi-channel audio to mono using the `audio_to_mono` helper from [`audio_processing.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/audio_processing.rs)
4. **Level Calculation**: Computes three metrics for each audio buffer:
   - **RMS level**: √(Σx²/N) representing average signal power
   - **Peak level**: max(|x|) indicating the highest instantaneous amplitude  
   - **Active flag**: Boolean threshold (rms > 0.001) indicating speech presence
5. **State Management**: Stores results in a thread-safe `Arc<Mutex<Vec<AudioLevelData>>>`
6. **Event Emission**: A Tokio task gathers data every 100ms, constructs an `AudioLevelUpdate` with timestamp and levels, and emits it via `app_handle.emit("audio-levels", &update)`

A simplified version exists in [`frontend/src-tauri/src/audio/simple_level_monitor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/simple_level_monitor.rs) that generates synthetic sinusoidal data for UI testing without accessing hardware.

### Frontend Event Handling

The TypeScript frontend subscribes to the `"audio-levels"` event using Tauri's `listen` API. When the Rust backend emits updates, the UI receives structured data containing timestamps and per-device metrics (RMS level, peak level, and activity status), enabling near-real-time visual meter updates for each monitored device.

## Code Implementation Examples

### Starting Monitoring from the Frontend

The following TypeScript pattern initializes monitoring and subscribes to level updates:

```typescript
import { invoke } from '@tauri-apps/api/tauri';
import { listen } from '@tauri-apps/api/event';

// Start monitoring specific devices
async function startMonitoring() {
  const devices = ['Built-in Microphone', 'BlackHole 2ch'];
  await invoke('start_audio_level_monitoring', { device_names: devices });
}

// Subscribe to real-time level updates
listen<{ timestamp: number; levels: { device_name: string; rms_level: number; peak_level: number; is_active: boolean }[] }>('audio-levels')
  .then(unsub => {
    console.log('Listening for audio level updates');
    // Call unsub() to stop listening
  });

```

### Stopping the Monitor

To terminate active monitoring sessions:

```typescript
import { invoke } from '@tauri-apps/api/tauri';

async function stopMonitoring() {
  await invoke('stop_audio_level_monitoring');
}

```

### Rust Unit Testing

Direct testing of the audio module without the frontend:

```rust
#[tokio::test]
async fn test_level_monitor() {
    use tauri::test::MockApp;
    let app = MockApp::new();
    
    let devices = vec!["Test Mic".to_string()];
    audio::level_monitor::AudioLevelMonitor::new()
        .start_monitoring(app.handle(), devices)
        .await
        .expect("Failed to start level monitoring");
    
    tokio::time::sleep(std::time::Duration::from_millis(500)).await;
    assert!(audio::level_monitor::is_monitoring());
}

```

## Summary

- **Three-layer architecture**: Tauri commands in [`lib.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/lib.rs) route to the audio module, which processes CPAL streams and emits events back to the frontend
- **Core metrics**: RMS (√(Σx²/N)), peak amplitude (max|x|), and activity threshold (rms > 0.001) calculated in [`level_monitor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/level_monitor.rs)
- **100ms update cycle**: Tokio tasks aggregate audio data and emit `AudioLevelUpdate` events via `app_handle.emit("audio-levels", &update)`
- **Frontend integration**: TypeScript uses `invoke` to start monitoring and `listen('audio-levels')` to receive real-time updates
- **Testing support**: The [`simple_level_monitor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/simple_level_monitor.rs) module provides synthetic data generation for UI development without hardware dependencies

## Frequently Asked Questions

### How does Meetily calculate audio levels from raw samples?

Meetily calculates **RMS (Root Mean Square)** and **peak** levels from raw audio buffers in [`frontend/src-tauri/src/audio/level_monitor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/level_monitor.rs). The RMS formula √(Σx²/N) represents the average power of the signal, while the peak value captures the maximum absolute amplitude. The system also applies a threshold (rms > 0.001) to determine if audio is currently active.

### What is the update frequency for audio level changes in the UI?

The system emits updates **every 100 milliseconds** via a Tokio async task that gathers accumulated `AudioLevelData` from all monitored devices and sends it to the frontend through Tauri's event system as an `AudioLevelUpdate` struct.

### Why does Meetily use CPAL for audio monitoring instead of Web APIs?

Meetily uses **CPAL (Cross-Platform Audio Library)** because it provides direct, low-latency access to system audio devices from Rust, bypassing browser sandbox restrictions that limit Web Audio API functionality in Tauri applications. CPAL enables the app to enumerate specific input devices by name and capture raw sample data for precise RMS calculations.

### How does the system handle multiple audio devices simultaneously?

The `start_audio_level_monitoring` command accepts a `Vec<String>` of device names. For each device, the system creates an independent CPAL input stream using `device.build_input_stream`, processes samples in parallel threads, and aggregates results into a single `AudioLevelUpdate` event that contains per-device metrics for the frontend.