Class: PWN::SDR::Decoder::APT::Demod
- Inherits:
-
Object
- Object
- PWN::SDR::Decoder::APT::Demod
- Defined in:
- lib/pwn/sdr/decoder/apt.rb
Overview
Streaming APT demodulator fed by Base.run_native.
Instance Method Summary collapse
- #feed(samples, &emit) ⇒ Object
- #finish ⇒ Object
-
#initialize(rate: 48_000, out_path: nil, max_lines: 1024) ⇒ Demod
constructor
A new instance of Demod.
Constructor Details
#initialize(rate: 48_000, out_path: nil, max_lines: 1024) ⇒ Demod
Returns a new instance of Demod.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/pwn/sdr/decoder/apt.rb', line 28 def initialize(rate: 48_000, out_path: nil, max_lines: 1024) @rate = rate.to_f raise ArgumentError, 'rate must be finite and positive' unless @rate.finite? && @rate.positive? raise ArgumentError, 'max_lines must be positive' unless max_lines.to_i.positive? @env_win = [(@rate / 2400.0).round, 1].max @envelope = Array.new(@env_win, 0.0) @env_index = 0 @env_sum = 0.0 @phase = 0.0 @pgm_path = out_path || "/tmp/apt_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pgm" @max_lines = max_lines.to_i @rows = [] @word_buf = [] @lines = 0 @synced = false end |
Instance Method Details
#feed(samples, &emit) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/pwn/sdr/decoder/apt.rb', line 46 def feed(samples, &emit) samples.each do |sample| value = sample.abs @env_sum += value - @envelope[@env_index] @envelope[@env_index] = value @env_index = (@env_index + 1) % @env_win @phase += WORD_RATE while @phase >= @rate @phase -= @rate @word_buf << (@env_sum / @env_win) extract_lines(&emit) if @word_buf.length >= WORDS_PER_LINE end end end |
#finish ⇒ Object
61 62 63 64 65 |
# File 'lib/pwn/sdr/decoder/apt.rb', line 61 def finish(&) extract_lines(&) @word_buf.clear { path: @pgm_path, width: WORDS_PER_LINE, height: @rows.length, lines: @lines } end |