Replace JNA with the FFM API (Panama) for the Opus binding

Bind libopus through java.lang.foreign downcall handles instead of JNA:
the ctl functions are linked with firstVariadicArg(2), and the encoder and
decoder each own a shared Arena holding the handle plus reusable native
PCM/packet buffers, so the hot path only allocates the returned packet.

The library is resolved by system SONAME first, falling back to a bundled
copy extracted from the JAR. Only the Windows x86-64 build is packaged by
default now (-Dnatives.all restores all platforms), since every other
platform ships libopus through its package manager.

Requires Java 26.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 23:35:57 +00:00
parent 022aef633b
commit 9d63522ef2
7 changed files with 381 additions and 100 deletions

View File

@@ -10,8 +10,8 @@ TeaVM/CheerpJ) without touching the library:
| Module | Artifact | Responsibility |
|--------|----------|----------------|
| `core` | `ts3-client-core` | Frontend-agnostic library: protocol integration, server model, connection orchestration, audio **abstractions**. No UI, no platform audio, no JNA. |
| `desktop` | `ts3-client-desktop` | Desktop audio backend: Java Sound capture/playback + native Opus via JNA, implementing the core audio interfaces. |
| `core` | `ts3-client-core` | Frontend-agnostic library: protocol integration, server model, connection orchestration, audio **abstractions**. No UI, no platform audio, no native code. |
| `desktop` | `ts3-client-desktop` | Desktop audio backend: Java Sound capture/playback + native Opus via the FFM API (project Panama), implementing the core audio interfaces. |
| `swing` | `ts3-client-swing` | Swing desktop UI + entry point. Depends on `core` and `desktop`. |
The core exposes `AudioBackend` / `VoiceInput` / `VoiceOutput`; the frontend injects
@@ -21,8 +21,11 @@ frontend supplies its own UI and audio backend while reusing `core` unchanged.
## Features
### Voice (the priority)
- **Native Opus codec** via a direct JNA binding to the system `libopus`
(no bundled/native-jar dependency). Encoding at 48 kHz, 20 ms frames.
- **Native Opus codec** via a direct Panama (Foreign Function & Memory API) binding —
no JNA, no other third-party FFI. The system `libopus` is used when installed,
otherwise a bundled copy is extracted from the JAR. Only the Windows x86-64 build
is bundled by default (build with `-Dnatives.all` to package every platform);
elsewhere install libopus from your package manager. Encoding at 48 kHz, 20 ms frames.
- **Voice Activation Detection (VAD)** with the same three modes as the TS3 client:
- **Volume Gate** — RMS/dBFS threshold with a live input meter and hangover.
- **Automatic** — a dependency-free speech detector (short-term energy + spectral
@@ -78,7 +81,7 @@ frontend supplies its own UI and audio backend while reusing `core` unchanged.
- Change your nickname, mute/deafen from the toolbar.
## Requirements
- Java 17+ (developed/tested on Temurin 26)
- Java 26+ (developed/tested on Temurin 26)
- The native Opus library on the system:
- Debian/Ubuntu: `sudo apt install libopus0`
- Arch: `sudo pacman -S opus`
@@ -124,7 +127,7 @@ core/ com.ts3client
└── ConnectionListener frontend callbacks
desktop/ com.ts3client.audio.desktop
├── Opus JNA binding to native libopus
├── Opus Panama (FFM) binding to native libopus
├── OpusEncoder/OpusDecoder thin codec wrappers
├── AudioDevices device enumeration + line opening (48 kHz/16-bit)
├── JavaSoundVoiceInput capture + VAD/PTT gating + Opus encode