Class: PWN::SDR::Decoder::Morse::Demod
- Inherits:
-
Object
- Object
- PWN::SDR::Decoder::Morse::Demod
- Defined in:
- lib/pwn/sdr/decoder/morse.rb
Overview
Stateful, streaming CW demodulator fed by Base.run_native.
Instance Method Summary collapse
- #feed(samples) ⇒ Object
-
#initialize(rate: 48_000) ⇒ Demod
constructor
A new instance of Demod.
Constructor Details
#initialize(rate: 48_000) ⇒ Demod
Returns a new instance of Demod.
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/pwn/sdr/decoder/morse.rb', line 17 def initialize(rate: 48_000) @rate = rate # single-pole low-pass on |x|; τ ≈ 5 ms @env_a = Math.exp(-1.0 / (rate * 0.005)) @env = 0.0 @floor = 0.0 @peak = 0.0 @state = :off @run = 0 @dit = rate * 60 / 1000 # seed 60 ms (≈ 20 WPM) @sym = +'' @word = +'' end |
Instance Method Details
#feed(samples) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/pwn/sdr/decoder/morse.rb', line 31 def feed(samples, &) samples.each do |x| @env = (@env_a * @env) + ((1.0 - @env_a) * x.abs) # slow trackers for adaptive threshold (attack fast, decay slow) @peak = @env > @peak ? ((@peak * 0.7) + (@env * 0.3)) : (@peak * 0.9999) @floor = @env < @floor ? @env : ((@floor * 0.9999) + (@env * 0.0001)) thresh = @floor + ((@peak - @floor) * 0.4) on = @env > thresh && (@peak - @floor) > 0.01 if on == (@state == :on) @run += 1 else classify_run(&) @state = on ? :on : :off @run = 1 end end return unless @state == :off && @run > 5 * @dit && !(@sym.empty? && @word.empty?) flush_char flush_word(&) end |