Объединение mesh-audio и apo-profile-switcher в одно приложение с улучшенной синхронизацией и встроенными EQ-профилями.
- VB-Cable — установка/проверка/статус источника по умолчанию + одна кнопка «сделать VB-Cable источником» (через
IPolicyConfig::SetDefaultEndpoint). - EqualizerAPO — авто-детект через реестр + кнопка «Установить EqualizerAPO» (если не обнаружен).
- Колонки — выбор устройств для зеркалирования + per-device trim громкости + per-device offset + ★ кнопка «сделать default» на каждом устройстве.
- EqualizerAPO профили — 10 встроенных профилей (Bass Boost, Classic, JBL Punch, …) + опционально папка пользователя.
- Синхронизация — Global delay, Ring buffer, Warmup, Stability mode, Auto adjust + 8 пресетов (включая
BT Rock Stable). - Метрики — статус источника, заполнение буфера, число корректировок, master volume.
- Тёмная/светлая тема (запоминается в localStorage).
- Все 10 EQ-профилей зашиты в бинарь через
include_str!. Никаких внешних файлов рядом с.exe. - EqualizerAPO путь определяется автоматически:
- Реестр
HKLM\SOFTWARE\EqualizerAPO(InstallLocation/InstallPath). %ProgramFiles%\EqualizerAPO\config,%ProgramFiles(x86)%\EqualizerAPO\config.- Fallback на
C:\Program Files\EqualizerAPO\config. - Можно переопределить через UI (раздел EQ профили → ▼ → Choose EqualizerAPO config).
- Реестр
modio.exeпишетconfig.txtнапрямую в найденную папку EqualizerAPO. Контент профилей инлайнится — никакихInclude:на внешние файлы. Установка модуля в любой каталог.- Состояние modio (выбранные профили, настройки) хранится в
%LOCALAPPDATA%\modio\modio.json.
Старая реактивная схема (discrete skip/inject когда ring buffer уходит от target'а) заменена на непрерывное rate-matched resampling:
- На каждое render-устройство навешивается
IAudioClock. Каждые 200 ms берётсяGetPosition(frames played + QPC timestamp в 100-наносекундных тиках) — это даёт реальную скорость устройства в кадрах на wallclock-секунду. - Per-device resampler (
rubato::FastFixedIn, полиномиальная интерполяция, 480-сэмпловые input-чанки) удерживается на ratio =device_rate / source_rateс EMA-сглаживанием (α=0.3). Изменения ratio применяются с ramp'ом — без щелчков. - Source audio из ring buffer → resampler → WASAPI render. Каждое устройство получает РОВНО столько кадров в секунду, сколько физически потребляет.
Почему это лечит «через половину песни разъезжается»:
- Дискретных коррекций больше нет → нет относительных фазовых сдвигов между колонками, которые накапливались в старой схеме (каждый skip = микро-десинк).
- Resampler непрерывно компенсирует расхождение часов на сотые доли процента (типичный BT drift укладывается в ±0.1%, далеко от max_relative=1.10).
- Дрейф BT-кодека (динамический рост latency из-за качества линка) не виден через WASAPI buffer fill, но виден через IAudioClock как изменение device_rate → resampler реагирует автоматически.
Fallback: если у устройства нет IAudioClock или формат не Float32, mirror идёт сырыми байтами без resampling (как в старой схеме без auto-adjust). В логе будет видна причина.
UI-control'ы (Stability mode, Auto adjust, BT Stable и прочие пресеты)
остались для обратной совместимости команд, но не влияют на runtime — SRC
работает всегда.
Громкость по-прежнему: effective_session_volume = master × per-device trim,
master опрашивается через IAudioEndpointVolume каждые 220 ms.
npm install
npm run tauri:buildАртефакты:
src-tauri/target/release/modio.exe— портативный exe (≈2.6 MB).src-tauri/target/release/bundle/msi/modio_1.0.0_x64_en-US.msi— MSI установщик.src-tauri/target/release/bundle/nsis/modio_1.0.0_x64-setup.exe— NSIS установщик.
npm run tauri:devsrc/i18n.ts — два словаря (ru/en), переключение через setLocale('en'). По умолчанию — русский.