-
-
Notifications
You must be signed in to change notification settings - Fork 83
[aethercore] Vendor WDSP 2.00 for Hermes-Lite RX #4278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jensenpat
wants to merge
1
commit into
aethersdr:main
Choose a base branch
from
jensenpat:aether/vendor-wdsp-hl2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| # Tell GitHub linguist to ignore reference material and docs | ||
| reference/** linguist-vendored | ||
| docs/** linguist-documentation | ||
|
|
||
| # Preserve the exact upstream WDSP snapshot, including generated-table | ||
| # whitespace, while keeping patch checks useful for AetherSDR-owned files. | ||
| third_party/wdsp/** linguist-vendored whitespace=-trailing-space,-space-before-tab |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| # WDSP 2.00 integration boundary | ||
|
|
||
| **Status:** Foundation implemented; Hermes-Lite 2 backend integration remains a | ||
| separate phase. This boundary is engine-only and introduces no radio behavior. | ||
|
|
||
| ## Decision | ||
|
|
||
| AetherSDR uses WDSP as a **whole-channel DSP engine** for raw-IQ radio backends. | ||
| It does not select individual WDSP stages and interleave them with | ||
| `AudioEngine`. For Hermes-Lite 2, one RX `WdspChannel` will own the complete | ||
| IQ-to-audio receive chain; a separate TX `WdspChannel` will later own the | ||
| complete audio-to-IQ transmit chain. A spectrum tap may observe the raw IQ, but | ||
| must not participate in or mutate the audio DSP chain. | ||
|
|
||
| This makes the ownership line testable: | ||
|
|
||
| ```text | ||
| Metis UDP RX -> bounded IQ queue -> HL2 DSP worker -> WDSP RX channel -> PCM outlet | ||
| | | ||
| +-> read-only FFT/spectrum tap | ||
|
|
||
| PCM TX source -> bounded audio queue -> HL2 DSP worker -> WDSP TX channel -> Metis EP2 | ||
| ``` | ||
|
|
||
| No GUI target, `AudioEngine`, or backend-neutral model may include a WDSP | ||
| header. `src/core/dsp/WdspChannel` is the only C++ entry point, and the C API in | ||
| `third_party/wdsp/include/aether_wdsp.h` is private to `aethercore`. | ||
|
|
||
| ## Reproducible source and build | ||
|
|
||
| The snapshot is pinned to TAPR/OpenHPSDR-wdsp commit | ||
| `584e8aca5ba1c4c6bc66fc0cc164ce567c8ba1e3`, whose subject is | ||
| `Release Version 2.00`. `third_party/wdsp/COMMIT` is the machine-readable pin. | ||
| The upstream PDF and binary calculus lookup table are not vendored. The latter | ||
| is optional in WDSP and its source fallback remains active. | ||
|
|
||
| `third_party/wdsp/CMakeLists.txt` produces the position-independent static | ||
| target `aether::wdsp`. Only `aethercore` links it, privately. WDSP's FFTW and | ||
| thread dependencies, source include directory, warning policy, and platform | ||
| definitions do not become public AetherSDR usage requirements. | ||
|
|
||
| The source snapshot has three documented teardown corrections. See | ||
| `third_party/wdsp/AETHERSDR-PATCHES.md`; refreshes must either find the fixes | ||
| upstream or reapply and retest them explicitly. | ||
|
|
||
| ## Portability layer | ||
|
|
||
| All platform adaptation stays under `third_party/wdsp/port/`: | ||
|
|
||
| - Win32-style critical sections, semaphores, events, waits, and worker starts | ||
| map to pthreads on macOS/Linux. | ||
| - aligned allocation is routed through one shim on every platform; counters | ||
| make callback allocation and teardown leaks test-visible. | ||
| - symbol export annotations and the small CRT compatibility surface are | ||
| neutralized at the boundary rather than scattered through WDSP. | ||
| - flush-to-zero setup uses AArch64 FPCR or SSE MXCSR as appropriate. | ||
| - priority requests are deliberately best-effort; the owning backend chooses | ||
| its worker scheduling policy rather than allowing WDSP to own it globally. | ||
|
|
||
| The port implements only calls consumed by the pinned snapshot. Adding another | ||
| Win32 emulation API requires a concrete WDSP call site and a unit test. | ||
|
|
||
| ## Lifetime and real-time contract | ||
|
|
||
| `WdspChannel` owns one numeric slot in WDSP's process-global channel table. | ||
| Construction acquires a unique slot; destruction closes the channel and returns | ||
| the slot. Copy and move are disabled so a slot has exactly one C++ owner. | ||
|
|
||
| WDSP setup is serialized because its FFTW planner and channel tables are global. | ||
| `OpenChannel`, `CloseChannel`, rate changes, mode changes, and filter changes are | ||
| control-thread operations. `processIq` is the only real-time operation: | ||
|
|
||
| - input and output buffers have fixed, validated sizes; | ||
| - no FFT plan or WDSP object is created or destroyed; | ||
| - allocation sequence changes are reported as `AllocationViolation`; | ||
| - nonblocking starvation is reported as `Underrun`; | ||
| - control/callback overlap is rejected as `Busy`. | ||
|
|
||
| The current `reconfigure` API requires the caller to stop the feed. For a live | ||
| HL2, do not close and rebuild the active channel on the DSP worker. Prepare a | ||
| second `WdspChannel` completely on a control thread, then swap owners at a block | ||
| boundary and retire the old instance off the real-time path. This also makes | ||
| 48/96/192/384 kHz changes bounded and rollback-safe. | ||
|
|
||
| ## HL2 staging and safety | ||
|
|
||
| Phase 1 is one receiver and no transmission: | ||
|
|
||
| 1. packet parsing and loss accounting feed a bounded SPSC IQ queue; | ||
| 2. a fixed-block DSP worker owns one preplanned RX `WdspChannel`; | ||
| 3. queue starvation inserts a timestamped zero-IQ gap and increments an | ||
| underrun counter rather than blocking the UDP thread; | ||
| 4. demodulated PCM and spectrum frames leave through backend-owned outlets; | ||
| 5. `canTransmit` remains false and no MOX-bearing packet is generated. | ||
|
|
||
| Phase 2 adds a distinct TX channel only after live RX is stable. TX construction | ||
| does not imply authorization to key: the operator-intent/arbiter gate must pass | ||
| before the backend sets MOX or emits a nonzero TX IQ sample. Teardown clears MOX | ||
| first, stops EP2 production second, then destroys the TX channel. | ||
|
|
||
| ## Verification and future performance matrix | ||
|
|
||
| `wdsp_channel_test` currently covers: | ||
|
|
||
| - reproducible RX complex-tone to audio and TX audio-tone to IQ vectors; | ||
| - allocation-free processing; | ||
| - explicit nonblocking underruns; | ||
| - rate/block reconfiguration outside the callback; | ||
| - unique concurrent channel IDs and leak-free repeated teardown. | ||
|
|
||
| Captured Metis frames and packet-gap fixtures belong in the future HL2 backend | ||
| test, not in this generic WDSP test. | ||
|
|
||
| Performance work starts only after the live RX path is correct. Record p50/p95/ | ||
| p99 block time, CPU, peak resident memory, underruns, and queue high-water mark | ||
| for 1, 2, 4, and the supported maximum receiver count at 48/96/192/384 kHz on | ||
| macOS ARM, Windows x64, and Linux x64. A run passes only when p99 remains below | ||
| the block deadline with zero steady-state allocations and zero underruns after | ||
| warm-up. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
add_subdirectoryis unconditional, andthird_party/wdsp/CMakeLists.txtdoesif(NOT FFTW3_FOUND) message(FATAL_ERROR ...). Combined with the unconditionaltarget_link_libraries(aethercore PRIVATE aether::wdsp), this promotes FFTW from optional-with-fallback (the oldNR2 will use fallback FFTwarning path) to a hard configure-time requirement on all platforms — a machine without FFTW that used to configure and build now fails at CMake configure.That's a reasonable consequence since WDSP genuinely needs FFTW, but it's a behavior change worth making deliberate: either guard this on
if(FFTW3_FOUND)(and skip the raw-IQ backend when absent), or update the build docs to state FFTW is now mandatory. CI runners provide it, so this won't block here.