Class: Vizcore::Analysis::FFTProcessor
- Inherits:
-
Object
- Object
- Vizcore::Analysis::FFTProcessor
- Defined in:
- lib/vizcore/analysis/fft_processor.rb
Overview
Performs FFT analysis with optional FFTW acceleration and Ruby fallback.
Defined Under Namespace
Classes: FFTWBackend, RubyBackend
Constant Summary collapse
- SUPPORTED_WINDOWS =
Supported windowing functions applied before FFT.
%i[hamming hann blackman none].freeze
- SUPPORTED_BACKENDS =
Supported transform backends.
%i[auto ruby fftw].freeze
Instance Attribute Summary collapse
-
#backend_name ⇒ Object
readonly
Returns the value of attribute backend_name.
-
#fft_size ⇒ Object
readonly
Returns the value of attribute fft_size.
-
#sample_rate ⇒ Object
readonly
Returns the value of attribute sample_rate.
-
#window ⇒ Object
readonly
Returns the value of attribute window.
Class Method Summary collapse
-
.fftw_available? ⇒ Boolean
True when FFTW3 is available.
Instance Method Summary collapse
-
#bin_frequency(bin_index) ⇒ Float
Frequency in Hz corresponding to the FFT bin.
-
#call(samples) ⇒ Hash
FFT result with magnitudes, complex spectrum, and peak info.
-
#initialize(sample_rate: 44_100, fft_size: 1024, window: :hamming, backend: :auto) ⇒ FFTProcessor
constructor
A new instance of FFTProcessor.
Constructor Details
#initialize(sample_rate: 44_100, fft_size: 1024, window: :hamming, backend: :auto) ⇒ FFTProcessor
Returns a new instance of FFTProcessor.
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 25 def initialize(sample_rate: 44_100, fft_size: 1024, window: :hamming, backend: :auto) @sample_rate = Integer(sample_rate) @fft_size = Integer(fft_size) @window = window.to_sym @backend_requested = backend.to_sym raise ArgumentError, "fft_size must be power of two" unless power_of_two?(@fft_size) raise ArgumentError, "unsupported window: #{@window}" unless SUPPORTED_WINDOWS.include?(@window) raise ArgumentError, "unsupported backend: #{@backend_requested}" unless SUPPORTED_BACKENDS.include?(@backend_requested) @backend = resolve_backend(@backend_requested) end |
Instance Attribute Details
#backend_name ⇒ Object (readonly)
Returns the value of attribute backend_name.
14 15 16 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 14 def backend_name @backend_name end |
#fft_size ⇒ Object (readonly)
Returns the value of attribute fft_size.
14 15 16 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 14 def fft_size @fft_size end |
#sample_rate ⇒ Object (readonly)
Returns the value of attribute sample_rate.
14 15 16 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 14 def sample_rate @sample_rate end |
#window ⇒ Object (readonly)
Returns the value of attribute window.
14 15 16 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 14 def window @window end |
Class Method Details
.fftw_available? ⇒ Boolean
Returns true when FFTW3 is available.
17 18 19 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 17 def self.fftw_available? FFTWFFI.available? end |
Instance Method Details
#bin_frequency(bin_index) ⇒ Float
Returns frequency in Hz corresponding to the FFT bin.
58 59 60 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 58 def bin_frequency(bin_index) Integer(bin_index) * sample_rate.to_f / fft_size.to_f end |
#call(samples) ⇒ Hash
Returns FFT result with magnitudes, complex spectrum, and peak info.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/vizcore/analysis/fft_processor.rb', line 40 def call(samples) frame = prepare_frame(samples) windowed = apply_window(frame) spectrum = execute_transform(windowed) half_spectrum = spectrum.first(@fft_size / 2) magnitudes = half_spectrum.map(&:abs) peak_bin = peak_index(magnitudes) { magnitudes: magnitudes, spectrum: half_spectrum, peak_bin: peak_bin, peak_frequency: bin_frequency(peak_bin) } end |