Преминете към основното съдържание

Аудио pipeline

Аудио модулът (client/src/audio/) отговаря за захващане на звук от микрофона, генериране на звукови нотификации и управление на системния mute. Той е първото звено в pipeline-а: микрофон -> f32 samples -> WAV кодиране -> WebSocket.

Архитектура

Модул capture.rs

AudioCapture struct

AudioCapture е основният интерфейс за управление на записа:

pub struct AudioCapture {
device_name: Option<String>, // Избран микрофон (None = default)
audio_tx: Sender<Vec<f32>>, // Канал за изпращане на samples
capturing: Arc<AtomicBool>, // Флаг за спиране
thread: Option<JoinHandle<()>>, // Capture thread handle
}

Методи:

  • new(audio_tx, device_name) -- създава инстанция без да стартира запис
  • start() -- spawn-ва capture нишка
  • stop() -- спира записа и join-ва нишката
  • list_devices() -- изброява налични capture устройства

WASAPI Capture Loop (Windows)

Ключови параметри

ПараметърСтойностОписание
TARGET_SAMPLE_RATE16,000 HzЧестота за ASR модела
Форматmono float3232-bit floating point, 1 канал
autoconverttrueWASAPI автоматично ресемплира от native формата на устройството
StreamModeEventsSharedСподелен режим с event-based wake
Chunk size1600 frames~100ms при 16kHz
Event timeout500msМаксимално изчакване за данни

Избор на микрофон

Потребителят може да избере конкретен микрофон от настройките. list_devices() изброява всички capture устройства чрез WASAPI DeviceEnumerator. Списъкът се генерира в отделна нишка за да не замърсява COM apartment-а на main thread-а (който трябва да остане STA за egui/winit).

Ако избраното устройство не бъде намерено, се използва default capture device.

macOS (TODO)

macOS имплементацията е stub -- планирана е чрез cpal crate с rubato resampler за конверсия от 48kHz към 16kHz.

Модул sound.rs

Генерира звукови нотификации за начало и край на запис. Звуците са синусоидални бипове, генерирани в паметта като PCM WAV:

ЗвукОписаниеЧестотиПродължителност
StartНарастващ двутонов бип600Hz -> 900Hz2 x 120ms
StopПадащ двутонов бип900Hz -> 600Hz2 x 120ms

Характеристики

  • Sample rate: 22,050 Hz
  • Формат: PCM 16-bit mono WAV
  • Envelope: 5ms attack + 15ms release (елиминира клик-артефакти)
  • Кеширане: WAV байтовете се генерират веднъж чрез OnceLock и се преизползват
  • Възпроизвеждане: Win32 PlaySoundW (SND_MEMORY | SND_SYNC) в background нишка

Mute интеграция

Звуковият модул координира с volume модула при mute_on_record настройка:

Модул volume.rs

Управлява системния mute/unmute чрез Windows Core Audio COM API:

  1. CoCreateInstance -> IMMDeviceEnumerator
  2. GetDefaultAudioEndpoint(eRender, eConsole) -> IMMDevice
  3. Activate(IID_IAudioEndpointVolume) -> IAudioEndpointVolume
  4. SetMute(true/false) или GetMute()

Имплементацията използва ръчни COM vtable извиквания (без windows-rs bindings) за минимален binary размер.

WAV кодиране

WAV кодирането се извършва в transcription/client.rs чрез hound crate:

fn encode_wav(audio: &[f32]) -> Result<Vec<u8>, String> {
let spec = hound::WavSpec {
channels: 1,
sample_rate: 16_000,
bits_per_sample: 32,
sample_format: hound::SampleFormat::Float,
};
// ... write to in-memory Cursor
}

Формат на WAV файла:

  • Канали: 1 (mono)
  • Sample rate: 16,000 Hz
  • Bits per sample: 32 (float)
  • Encoding: IEEE Float

Целият WAV се записва в Vec<u8> в паметта (без файл на диска) и се изпраща като Binary WebSocket frame.