Module: RTLSDR::FFTW
- Extended by:
- FFI::Library
- Defined in:
- lib/rtlsdr/fftw.rb
Overview
This is an internal module. Use RTLSDR::DSP.fft and related methods instead.
FFI bindings for FFTW3 (Fastest Fourier Transform in the West)
This module provides low-level FFI bindings to the FFTW3 library for performing fast Fourier transforms. FFTW3 must be installed on the system.
FFTW Planning Flags collapse
- FFTW_MEASURE =
Returns Measure execution time to find optimal plan.
0- FFTW_DESTROY_INPUT =
Returns Allow input array to be destroyed during planning.
1- FFTW_UNALIGNED =
Returns Don't assume arrays are aligned in memory.
2- FFTW_CONSERVE_MEMORY =
Returns Minimize memory usage at cost of speed.
4- FFTW_EXHAUSTIVE =
Returns Try all possible algorithms (very slow planning).
8- FFTW_PRESERVE_INPUT =
Returns Preserve input array contents during transform.
16- FFTW_PATIENT =
Returns Like MEASURE but try harder (slower planning).
32- FFTW_ESTIMATE =
Returns Use quick heuristic to pick plan (fast planning, default).
64- FFTW_WISDOM_ONLY =
Returns Only use wisdom (cached plans), fail if none available.
2_097_152
FFT Direction Constants collapse
- FFTW_FORWARD =
Returns Forward FFT direction (time to frequency domain).
-1- FFTW_BACKWARD =
Returns Backward/Inverse FFT direction (frequency to time domain).
1- COMPLEX_SIZE =
Size of a complex number in FFTW (two doubles)
16
Constant Summary collapse
- LIBRARY_NAMES =
Try to load FFTW3 library with common paths
%w[ fftw3 libfftw3.so.3 libfftw3.dylib libfftw3-3.dll ].freeze
Class Attribute Summary collapse
-
.load_error ⇒ String?
readonly
Get the error message if FFTW3 failed to load.
FFT Direction Constants collapse
-
.backward(spectrum) ⇒ Array<Complex>
Perform inverse FFT on complex spectrum.
-
.forward(samples) ⇒ Array<Complex>
Perform forward FFT on complex samples.
Class Method Summary collapse
-
.available? ⇒ Boolean
Check if FFTW3 library is available.
Class Attribute Details
.load_error ⇒ String? (readonly)
Get the error message if FFTW3 failed to load
45 46 47 |
# File 'lib/rtlsdr/fftw.rb', line 45 def load_error @load_error end |
Class Method Details
.available? ⇒ Boolean
Check if FFTW3 library is available
38 39 40 |
# File 'lib/rtlsdr/fftw.rb', line 38 def available? @available end |
.backward(spectrum) ⇒ Array<Complex>
Perform inverse FFT on complex spectrum
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rtlsdr/fftw.rb', line 161 def self.backward(spectrum) raise "FFTW3 library not available: #{load_error}" unless available? n = spectrum.length return [] if n.zero? # Allocate input and output arrays input = fftw_malloc(n * COMPLEX_SIZE) output = fftw_malloc(n * COMPLEX_SIZE) begin # Copy spectrum to input array spectrum.each_with_index do |sample, i| input.put_float64(i * COMPLEX_SIZE, sample.real) input.put_float64((i * COMPLEX_SIZE) + 8, sample.imag) end # Create and execute plan plan = fftw_plan_dft_1d(n, input, output, FFTW_BACKWARD, FFTW_ESTIMATE) raise "Failed to create FFTW plan" if plan.null? begin fftw_execute(plan) # Read output and normalize (FFTW doesn't normalize IFFT) result = Array.new(n) do |i| real = output.get_float64(i * COMPLEX_SIZE) / n imag = output.get_float64((i * COMPLEX_SIZE) + 8) / n Complex(real, imag) end result ensure fftw_destroy_plan(plan) end ensure fftw_free(input) fftw_free(output) end end |
.forward(samples) ⇒ Array<Complex>
Perform forward FFT on complex samples
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/rtlsdr/fftw.rb', line 115 def self.forward(samples) raise "FFTW3 library not available: #{load_error}" unless available? n = samples.length return [] if n.zero? # Allocate input and output arrays input = fftw_malloc(n * COMPLEX_SIZE) output = fftw_malloc(n * COMPLEX_SIZE) begin # Copy samples to input array (interleaved real/imag doubles) samples.each_with_index do |sample, i| input.put_float64(i * COMPLEX_SIZE, sample.real) input.put_float64((i * COMPLEX_SIZE) + 8, sample.imag) end # Create and execute plan plan = fftw_plan_dft_1d(n, input, output, FFTW_FORWARD, FFTW_ESTIMATE) raise "Failed to create FFTW plan" if plan.null? begin fftw_execute(plan) # Read output into Ruby Complex array result = Array.new(n) do |i| real = output.get_float64(i * COMPLEX_SIZE) imag = output.get_float64((i * COMPLEX_SIZE) + 8) Complex(real, imag) end result ensure fftw_destroy_plan(plan) end ensure fftw_free(input) fftw_free(output) end end |