Compilation depuis les sources

Table des matières

  1. Prérequis
  2. Compilation rapide
  3. Si vous avez déjà cloné sans --recursive
  4. Structure du projet
  5. Tests
  6. Paquets de version
  7. Tester sans matériel (tools/emu)
  8. Dépendances

Prérequis

  • Rust (stable, 1.90 ou ultérieur) via rustup
  • Visual Studio 2022 ou ultérieur (ou ses Build Tools) avec la charge de travail « Développement Desktop en C++ » : les bibliothèques C (BTstack, les codecs) sont compilées avec MSVC
  • Node.js 22 et pnpm pour l’interface (corepack enable fournit pnpm)
  • Git (pour les sous-modules)
  • PowerShell 7 (pwsh) pour build.ps1 / build.bat (winget install Microsoft.PowerShell)
  • Pour les versions ARM64 : le composant Visual Studio « MSVC v143 - VS 2022 C++ ARM64 build tools » et, sur un PC x64, « C++ Clang Compiler for Windows » (ring, de rustls, assemble son code ARM64 avec clang ; installer/build-release.ps1 trouve lui-même le clang de Visual Studio), et rustup target add aarch64-pc-windows-msvc

Compilation rapide

git clone --recursive https://github.com/SeiyaFunaokaJP/A2DP-Windows-Bridge.git
cd A2DP-Windows-Bridge
pwsh ./build.ps1

Ou double-cliquez sur build.bat dans l’Explorateur : il lance build.ps1 et attend une touche à la fin (build.bat -Test transmet les options). build.ps1 vérifie d’abord que Rust, Node.js, pnpm et les sous-modules sont présents, lance pnpm install si node_modules est absent, compile la page de la fenêtre puis les trois programmes dans target/release/ : a2dpwb-core.exe (le cœur résident : Bluetooth, audio, zone de notification), a2dpwb.exe (la fenêtre) et a2dpwb-driver.exe (l’assistant élevé qui attribue / restaure le pilote WinUSB). Gardez les trois dans un même dossier ; a2dpwb-core.exe --cli diffuse sans la fenêtre.

Options : -Debug (profil de développement, target/debug/), -Test (puis les vérifications de la section « Tests »), -Decoder (aussi l’outil de décodage), -Emu (aussi le test sans matériel), -Release -Arch x64|arm64 (uniquement le script de publication, voir « Paquets de version »).

Pas à pas (ce que fait build.ps1 ; la page de la fenêtre doit être compilée avant a2dpwb.exe, qui l’intègre) :

cargo build --release -p a2dpwb-core-exe -p a2dpwb-driver
cd app/src/ui
pnpm install --frozen-lockfile
pnpm build
cd ../../..
cargo build --release -p a2dpwb-ui

Si vous avez déjà cloné sans --recursive

git submodule update --init --recursive

Structure du projet

A2DP-Windows-Bridge/
├── app/
│   ├── src/
│   │   ├── core/           a2dpwb-core.exe: resident core, tray, IPC server, --cli
│   │   ├── ui/             a2dpwb.exe: Tauri 2 + SolidJS (pnpm dev runs it in a browser with a mock core)
│   │   ├── driver/         a2dpwb-driver.exe: WinUSB assign / restore (elevated)
│   │   └── crates/         Libraries: btstack-sys, hci-transport, bt-host, codec, the codec -sys crates,
│   │                       pipeline, audio-capture, win-sys, core (a2dpwb-core), ipc, le-audio, lc3-sys
│   ├── lang/               Localization (en.json is the source; tools/check_lang.py checks the others)
│   └── resources/          Icon and manifest
├── Cargo.toml              Cargo workspace
├── installer/              Release script, NSIS hooks, updater notes (installer/README.md)
├── compat/                 MSVC compatibility headers for the AOSP code
├── docs/                   Documentation (this site) and the design document (v2-design.md)
├── extern/                 Third-party C libraries (git submodules)
│   ├── btstack/            BTstack Bluetooth stack
│   ├── libldac/            AOSP LDAC encoder
│   ├── libopenaptx/        aptX / aptX HD / aptX LL encoder
│   ├── fdk-aac/            Fraunhofer AAC encoder
│   ├── lhdcv5-enc/         LHDC V5 encoder
│   └── opus/               libopus (Opus encoder)
└── tools/
    ├── a2dp_decode/        a2dpwb_decode: checks / decodes the media stream in an HCI capture (.pklg)
    ├── emu/                End-to-end test against a virtual Bluetooth sink (Python)
    └── linux_sink/         a2dpwb_sink: measuring A2DP receiver on Linux (Python, Bumble)

Tests

cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cd app/src/ui && pnpm exec tsc --noEmit && pnpm exec vitest run
python tools/check_lang.py

Paquets de version

pwsh installer/build-release.ps1 -Arch x64

produit le programme d’installation (A2DPWB-<version>-win64-setup.exe), le zip portable et le manifeste de mise à jour dans target/dist. La signature des mises à jour intégrées à l’application et les autres détails sont décrits dans installer/README.md.

Tester sans matériel (tools/emu)

tools/emu diffuse chaque codec depuis A2DPWB vers un récepteur Bluetooth virtuel sur le même PC, sans adaptateur ni casque. Il fonctionne uniquement sous Windows et nécessite Python 3.11 ou ultérieur ainsi que CMake (fourni avec Visual Studio) pour l’outil de décodage.

python tools/emu/setup_env.py                       # une fois : crée tools/emu/.venv avec des paquets aux versions figées
cmake -S tools/a2dp_decode -B build/a2dp_decode     # une fois : l'outil de décodage
cmake --build build/a2dp_decode --config Release
cargo build --release -p a2dpwb-core-exe
python tools/emu/run_test.py                        # environ 35 s pour tous les codecs

Fonctionnement :

  • emu_sink.py exécute deux contrôleurs virtuels Bumble reliés par une liaison interne au processus. L’un est exposé en H4 via TCP (127.0.0.1) pour A2DPWB. L’autre est utilisé par un récepteur A2DP Bumble qui propose SBC, AAC, aptX, aptX HD, aptX LL et LDAC, et enregistre son trafic HCI.
  • run_test.py lance a2dpwb-core.exe --cli pour chaque codec avec les options de développement : --hci-tcp (contrôleur virtuel au lieu de WinUSB), --test-tone (1 kHz à gauche / 1,5 kHz à droite au lieu de l’audio du système), --duration, --hci-capture. La variable d’environnement A2DPWB_CONFIG_DIR fait utiliser à A2DPWB un dossier de configuration séparé, si bien que l’association avec le récepteur virtuel ne touche jamais vos vraies clés de liaison.
  • Les deux captures HCI sont ensuite vérifiées avec a2dpwb_decode (le côté récepteur avec --received).

Un codec réussit le test lorsque toutes ces conditions sont remplies :

  • le codec demandé a été négocié
  • a2dpwb_decode ne trouve aucun problème, ni côté envoi ni côté réception
  • le récepteur a reçu chaque paquet média et chaque trame envoyés par A2DPWB, et au moins 90 % de la durée audio demandée a été envoyée
  • sauf pour LDAC (pas de décodeur open source) : l’audio décodé est identique des deux côtés et correspond au signal de test
Option Description
--codecs sbc aac ... Tester uniquement ces codecs (sbc aac aptx aptxhd aptxll ldac, par défaut : tous)
--duration <s> Secondes de diffusion par codec (5 par défaut)
--max-packet <bytes> Transmis à A2DPWB (taille max. des paquets média, voir Utilisation)
--a2dpwb <exe> Le cœur à tester (par défaut target/release/a2dpwb-core.exe)
--decoder <exe> L’outil de décodage (par défaut build/a2dp_decode/Release/a2dpwb_decode.exe)
--out <dir> Dossier de sortie (par défaut tools/emu/out)

Pour chaque codec, tools/emu/out/<codec>/ contient les captures (a2dpwb.pklg, sink.pklg), les journaux, les rapports d’a2dpwb_decode et les fichiers WAV décodés. Le code de sortie est 0 lorsque tous les codecs ont réussi.

La liaison virtuelle n’a pas de radio : elle vérifie l’encodage, la mise en paquets, la signalisation AVDTP / L2CAP et l’interopérabilité avec une pile Bluetooth indépendante (Bumble), mais pas les conditions radio, le timing sur du vrai matériel ni la façon dont un vrai casque restitue l’audio. Les paquets Bumble ne sont que des outils de test et ne font pas partie d’A2DPWB (voir THIRD_PARTY_LICENSES.md).

emu_vhci.py fait de même vis-à-vis de la pile Bluetooth de Linux : sous Linux, il attache un adaptateur virtuel à BlueZ via /dev/vhci, que le récepteur de mesure tools/linux_sink prend ensuite comme un vrai adaptateur - il peut ainsi être testé sans matériel, éventuellement avec des paquets média perdus ou retenus (--drop, --stall). Voir tools/linux_sink/README.md.

Dépendances

Les bibliothèques C sont des sous-modules git ; les crates Rust et les paquets npm de l’interface sont récupérés par Cargo et pnpm (versions figées dans Cargo.lock et app/src/ui/pnpm-lock.yaml ; cargo deny check vérifie leurs licences).

Bibliothèque Méthode Version figée Licence
BTstack sous-module git v1.8.1-6-g5bc5cbdbe BTstack License (de type BSD-3-Clause avec une clause non commerciale)
Codec SBC Bluedroid encodeur porté en Rust ; le décodeur (tests, outils) provient de la copie de BTstack celle de BTstack Apache-2.0
rijndael inclus dans BTstack (3rd-party/rijndael) celle de BTstack Domaine public
liblc3 (lc3-google) inclus dans BTstack (3rd-party/lc3-google) celle de BTstack Apache-2.0
micro-ecc inclus dans BTstack (3rd-party/micro-ecc) celle de BTstack BSD-2-Clause
libldac (AOSP) sous-module git android-15.0.0_r36-4-geeee1a3 Apache-2.0
libopenaptx sous-module git 0.2.0 (ne pas mettre à jour) LGPL-2.1+
fdk-aac sous-module git v2.0.3-158-gd8e6b1a FDK AAC License
Encodeur LHDC V5 sous-module git celle du sous-module Apache-2.0
libopus sous-module git v1.5.2 BSD-3-Clause
Tauri, SolidJS, crates Rust Cargo / pnpm Cargo.lock, pnpm-lock.yaml MIT / Apache-2.0 et autres (licenses/rust-crates.txt dans la version publiée)

Comme BTstack y est lié, tout A2DPWB que vous compilez ne peut être utilisé et redistribué qu’à des fins personnelles et non commerciales, même si le code source d’A2DPWB lui-même est sous double licence Apache-2.0 ou MIT.

Voir THIRD_PARTY_LICENSES.md pour le détail complet des licences.