fix: CW decoder was loosing first caracters
This commit is contained in:
@@ -46,7 +46,8 @@ type Decoder struct {
|
||||
quietHops int // consecutive key-up hops while locked
|
||||
noise float64 // broadband noise estimate (percentile of bins)
|
||||
relockHops int // quiet hops before the lock is released
|
||||
acqSNR float64 // minimum tone/noise ratio to acquire a lock
|
||||
acqSNR float64 // tone/noise ratio to acquire after a few stable hops
|
||||
strongSNR float64 // tone/noise ratio to lock immediately (1 hop)
|
||||
|
||||
// Adaptive keying envelope, on the LOCKED bin's magnitude.
|
||||
peak, floor float64
|
||||
@@ -88,9 +89,10 @@ func New(sampleRate int, onChar func(string), onStatus func(Status)) *Decoder {
|
||||
d := &Decoder{
|
||||
fs: sampleRate,
|
||||
hop: sampleRate / 250, // ~4 ms resolution
|
||||
win: sampleRate / 62, // ~16 ms Goertzel window
|
||||
win: sampleRate / 100, // ~10 ms Goertzel window (snappy edges)
|
||||
dotHops: 15, // ~20 WPM seed
|
||||
acqSNR: 1.8, // mild: just enough to ignore pure noise
|
||||
acqSNR: 1.5, // mild: ignore pure noise, still catch weak
|
||||
strongSNR: 2.6, // a clearly-strong tone locks in 1 hop
|
||||
lockIdx: -1,
|
||||
candIdx: -1,
|
||||
statusEvery: 25, // ~10 Hz
|
||||
@@ -172,14 +174,16 @@ func (d *Decoder) analyze() {
|
||||
d.noise = d.nbuf[int(0.4*float64(len(d.nbuf)-1)+0.5)]
|
||||
|
||||
if d.lockIdx < 0 {
|
||||
// Acquire: lock when the same bin has been dominant for a few hops and
|
||||
// is at least mildly above the noise (so we don't lock onto pure noise).
|
||||
if maxIdx == d.candIdx {
|
||||
d.candHops++
|
||||
} else {
|
||||
d.candIdx, d.candHops = maxIdx, 1
|
||||
}
|
||||
if d.candHops >= 5 && maxMag/(d.noise+1e-9) > d.acqSNR {
|
||||
snr := maxMag / (d.noise + 1e-9)
|
||||
// Tiered acquisition: a clearly strong tone locks on the FIRST hop (so we
|
||||
// don't eat the first element of a strong signal), a marginal/weak tone
|
||||
// locks after a couple of stable hops (so we don't lock onto pure noise).
|
||||
if snr > d.strongSNR || (d.candHops >= 2 && snr > d.acqSNR) {
|
||||
d.lockIdx = maxIdx
|
||||
d.peak, d.floor = maxMag, d.noise // seed the envelope to this bin
|
||||
d.quietHops = 0
|
||||
@@ -208,12 +212,12 @@ func (d *Decoder) step() {
|
||||
if m < d.floor {
|
||||
d.floor += (m - d.floor) * 0.4
|
||||
} else {
|
||||
d.floor += (m - d.floor) * 0.01
|
||||
d.floor += (m - d.floor) * 0.005 // creep up slowly so marks aren't swallowed
|
||||
}
|
||||
span := d.peak - d.floor
|
||||
if span > d.floor*0.3+1e-9 {
|
||||
onTh := d.floor + 0.55*span
|
||||
offTh := d.floor + 0.35*span
|
||||
if span > d.floor*0.22+1e-9 {
|
||||
onTh := d.floor + 0.50*span
|
||||
offTh := d.floor + 0.30*span
|
||||
if d.state {
|
||||
on = m > offTh
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user