Module: PWN::FFI::Volk
- Extended by:
- Library
- Defined in:
- lib/pwn/ffi/volk.rb
Overview
Thin VOLK (Vector-Optimized Library of Kernels) binding.
Dispatches to SIMD kernels (SSE/AVX/NEON/…) when the host provides them. Used by PWN::SDR::Decoder::DSP hot paths so MHz-rate I/Q work stays off the Ruby GC heap while orchestration remains pure Ruby.
Nothing here shells out and nothing is compiled at gem-install time —
if libvolk is missing, .available? is false and callers fall back.
Class Attribute Summary collapse
-
.load_error ⇒ Object
readonly
Returns the value of attribute load_error.
Class Method Summary collapse
-
.accumulate(opts = {}) ⇒ Object
- Supported Method Parameters
sum = PWN::FFI::Volk.accumulate(samples: Array
).
-
.authors ⇒ Object
- Author(s)
0day Inc.
-
.available? ⇒ Boolean
- Supported Method Parameters
PWN::FFI::Volk.available?.
-
.dot_prod(opts = {}) ⇒ Object
- Supported Method Parameters
sum = PWN::FFI::Volk.dot_prod(a: Array
, b: Array ).
-
.help ⇒ Object
Display Usage for this Module.
-
.magnitude_squared(opts = {}) ⇒ Object
- Supported Method Parameters
power = PWN::FFI::Volk.magnitude_squared( iq: 'required - Array of interleaved I/Q Floats (even length)' ) Returns Array
of |z|^2 per complex sample.
-
.scale(opts = {}) ⇒ Object
- Supported Method Parameters
out = PWN::FFI::Volk.scale(samples: Array
, factor: Float) Multiplies every sample by factor.
-
.sqrt(opts = {}) ⇒ Object
- Supported Method Parameters
out = PWN::FFI::Volk.sqrt(samples: Array
).
-
.unpack_s16le(opts = {}) ⇒ Object
- Supported Method Parameters
samples = PWN::FFI::Volk.unpack_s16le( data: 'required - raw String of little-endian signed 16-bit PCM' ) Returns Array
normalised to -1.0..1.0 (same contract as PWN::SDR::Decoder::DSP.unpack_s16le).
Class Attribute Details
.load_error ⇒ Object (readonly)
Returns the value of attribute load_error.
28 29 30 |
# File 'lib/pwn/ffi/volk.rb', line 28 def load_error @load_error end |
Class Method Details
.accumulate(opts = {}) ⇒ Object
- Supported Method Parameters
sum = PWN::FFI::Volk.accumulate(samples: Array
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/pwn/ffi/volk.rb', line 82 public_class_method def self.accumulate(opts = {}) raise 'ERROR: libvolk not available' unless available? samples = opts[:samples] n = samples.length return 0.0 if n.zero? in_ptr = float_ptr(samples) out_ptr = PubFFI::MemoryPointer.new(:float, 1) accum_fn.call(out_ptr, in_ptr, n) out_ptr.read_float end |
.authors ⇒ Object
- Author(s)
0day Inc. support@0dayinc.com
168 169 170 |
# File 'lib/pwn/ffi/volk.rb', line 168 public_class_method def self. "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n" end |
.available? ⇒ Boolean
- Supported Method Parameters
PWN::FFI::Volk.available?
51 52 53 54 55 |
# File 'lib/pwn/ffi/volk.rb', line 51 public_class_method def self.available? !@load_error && respond_to?(:volk_get_alignment, true) rescue StandardError false end |
.dot_prod(opts = {}) ⇒ Object
- Supported Method Parameters
sum = PWN::FFI::Volk.dot_prod(a: Array
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/pwn/ffi/volk.rb', line 151 public_class_method def self.dot_prod(opts = {}) raise 'ERROR: libvolk not available' unless available? a = opts[:a] b = opts[:b] n = [a.length, b.length].min return 0.0 if n.zero? a_ptr = float_ptr(a) b_ptr = float_ptr(b) out_ptr = PubFFI::MemoryPointer.new(:float, 1) dot_fn.call(out_ptr, a_ptr, b_ptr, n) out_ptr.read_float end |
.help ⇒ Object
Display Usage for this Module
174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/pwn/ffi/volk.rb', line 174 public_class_method def self.help puts "USAGE: #{self}.available? # => true/false #{self}.unpack_s16le(data: raw_bytes) # s16le → Float[-1,1] #{self}.accumulate(samples:) # Σ samples #{self}.magnitude_squared(iq:) # |z|² per complex pair #{self}.sqrt(samples:) #{self}.scale(samples:, factor:) #{self}.dot_prod(a:, b:) #{self}.authors " end |
.magnitude_squared(opts = {}) ⇒ Object
- Supported Method Parameters
power = PWN::FFI::Volk.magnitude_squared(
iq: 'required - Array of interleaved I/Q Floats (even length)'
)
Returns Array
101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/pwn/ffi/volk.rb', line 101 public_class_method def self.magnitude_squared(opts = {}) raise 'ERROR: libvolk not available' unless available? iq = opts[:iq] n_c = iq.length / 2 return [] if n_c.zero? in_ptr = float_ptr(iq) out_ptr = PubFFI::MemoryPointer.new(:float, n_c) mag2_fn.call(out_ptr, in_ptr, n_c) out_ptr.read_array_of_float(n_c) end |
.scale(opts = {}) ⇒ Object
- Supported Method Parameters
out = PWN::FFI::Volk.scale(samples: Array
134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/pwn/ffi/volk.rb', line 134 public_class_method def self.scale(opts = {}) raise 'ERROR: libvolk not available' unless available? samples = opts[:samples] factor = opts[:factor].to_f n = samples.length return [] if n.zero? in_ptr = float_ptr(samples) out_ptr = PubFFI::MemoryPointer.new(:float, n) scale_fn.call(out_ptr, in_ptr, factor, n) out_ptr.read_array_of_float(n) end |
.sqrt(opts = {}) ⇒ Object
- Supported Method Parameters
out = PWN::FFI::Volk.sqrt(samples: Array
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/pwn/ffi/volk.rb', line 117 public_class_method def self.sqrt(opts = {}) raise 'ERROR: libvolk not available' unless available? samples = opts[:samples] n = samples.length return [] if n.zero? in_ptr = float_ptr(samples) out_ptr = PubFFI::MemoryPointer.new(:float, n) sqrt_fn.call(out_ptr, in_ptr, n) out_ptr.read_array_of_float(n) end |
.unpack_s16le(opts = {}) ⇒ Object
- Supported Method Parameters
samples = PWN::FFI::Volk.unpack_s16le(
data: 'required - raw String of little-endian signed 16-bit PCM'
)
Returns Arrayscalar as a
divisor, so pass 32768.0 to get unit-range floats.
65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/pwn/ffi/volk.rb', line 65 public_class_method def self.unpack_s16le(opts = {}) raise 'ERROR: libvolk not available' unless available? data = opts[:data].to_s n = data.bytesize / 2 return [] if n.zero? in_ptr = PubFFI::MemoryPointer.from_string(data) # from_string null-terminates — reclaim only the payload region out_ptr = PubFFI::MemoryPointer.new(:float, n) convert_fn.call(out_ptr, in_ptr, 32_768.0, n) out_ptr.read_array_of_float(n) end |