Class: PWN::SDR::Decoder::P25::DemodIQ
- Inherits:
-
Object
- Object
- PWN::SDR::Decoder::P25::DemodIQ
- Defined in:
- lib/pwn/sdr/decoder/p25.rb
Overview
Streaming C4FM demod for Base.run_iq — I/Q → NAC/DUID frames.
Constant Summary collapse
- AUDIO_RATE =
48_000
Instance Method Summary collapse
- #feed_iq(samples, rate: nil) ⇒ Object
-
#initialize(rate:) ⇒ DemodIQ
constructor
A new instance of DemodIQ.
Constructor Details
#initialize(rate:) ⇒ DemodIQ
Returns a new instance of DemodIQ.
41 42 43 44 45 |
# File 'lib/pwn/sdr/decoder/p25.rb', line 41 def initialize(rate:) @rate = rate.to_f @dibits = [] @seen_fs = 0 end |
Instance Method Details
#feed_iq(samples, rate: nil) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/pwn/sdr/decoder/p25.rb', line 47 def feed_iq(samples, rate: nil, &) @rate = rate.to_f if rate @fm_state ||= {} @audio ||= [] @audio.concat(DSP.fm_demod_iq(iq: samples, state: @fm_state)) # Fixed 10 ms analysis windows keep resampler and slicer resets # independent of USB/file/UDP chunk boundaries. window = [(@rate * 0.01).round, 1].max while @audio.length >= window audio = DSP.resample(samples: @audio.shift(window), src_rate: @rate, dst_rate: AUDIO_RATE) @dibits.concat(DSP.slice_4fsk(samples: audio, rate: AUDIO_RATE, baud: 4800)) scan(&) if block_given? end @dibits.shift(@dibits.length - 4096) if @dibits.length > 8192 end |