Class: PWN::SDR::Decoder::APT::Demod

Inherits:
Object
  • Object
show all
Defined in:
lib/pwn/sdr/decoder/apt.rb

Overview

Streaming APT demodulator fed by Base.run_native.

Instance Method Summary collapse

Constructor Details

#initialize(rate: 48_000, out_path: nil, max_lines: 1024) ⇒ Demod

Returns a new instance of Demod.

Raises:

  • (ArgumentError)


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

#finishObject



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