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.
27 lines
674 B
Kotlin
27 lines
674 B
Kotlin
import com.android.build.api.variant.CanProduceConsumerProguardFiles
|
|
|
|
plugins {
|
|
alias(libs.plugins.convention.featurePlugin)
|
|
}
|
|
|
|
android {
|
|
namespace = "com.rtbishop.look4sat.feature.cw"
|
|
compileOptions {
|
|
encoding = "UTF-8"
|
|
}
|
|
}
|
|
|
|
// R8 consumer rules (kept for compatibility; the fldigi port has no native code)
|
|
androidComponents {
|
|
onVariants(selector().all()) { variant ->
|
|
(variant as? CanProduceConsumerProguardFiles)?.consumerProguardFiles?.add(
|
|
project.layout.projectDirectory.file("proguard-rules.pro")
|
|
)
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation(project(":core:domain"))
|
|
implementation(project(":core:data"))
|
|
}
|