Background:
The CW decoder previously shipped a decompiled copy of the proprietary
Morse Expert 1.15 (com/ve3nea/morse_expert + obfuscated classes,
libnativedecoderjni.so, suncompat black-magic) — a copyright liability.
This removes all of it and reimplements the decoder on the open-source
fldigi (GPL v3) CW engine as a faithful pure-Kotlin port with no JNI.
Changes:
- Delete all Morse Expert reverse-engineered code: MainActivity,
obfuscated packages (B/B0/D/E2/...), suncompat/, pas/nativedecoder,
armeabi-v7a libnativedecoderjni.so, and the original View-based layouts
(activity_main, cw_panel_main, options_menu).
- Add a full fldigi CW pipeline in core/domain/cw:
- CwFldigiDsp: NCO down-conversion, FFT filter, movavg constants
- CwFftFilt: overlap-add FFT band-pass filter (fftfilt port)
- MorseTable + SomTable: full Morse code table + SOM codebook
- CwFldigiDecoder: decode_stream AGC + hysteresis, state machine,
adaptive speed tracking (5-55 WPM), SOM winner/normalize matching
- Rewrite CwDecodeScreen as pure Compose (DeepCW-style waterfall,
live decode line, history, status cards) and CwSettingsDialog
(speed/bandwidth/SOM) with no View interop.
- Replace the Morse Expert panel in TransceiversPage with a Compose
panel driving the same decoder; mic capture at 8000 Hz.
- Drop the forced armeabi-v7a abiFilters now that no native lib exists.
Verification:
- 8 unit tests pass (CQ/HELLO at 18-20 wpm, A-J at 30 wpm with
adaptive tracking, dot/dash/Farnsworth edge cases) — all decode
correctly from synthesized CW.
- :feature:cw and :feature:radar compile; app assembleDebug succeeds.
- APK contains no ve3nea/nativedecoder/morse_expert classes.