### RealFFT: Transform and Inverse Transform Signal Source: https://github.com/henquist/realfft/blob/master/README.md This example demonstrates how to perform a forward real-to-complex FFT and then an inverse complex-to-real FFT using the realfft crate. It requires the `realfft` and `rustfft` crates. The process involves planning the FFT, creating input data, processing the forward transform to get the spectrum, planning the inverse FFT, and processing the spectrum back to the time domain. ```rust use realfft::RealFftPlanner; use rustfft::num_complex::Complex; use rustfft::num_traits::Zero; let length = 256; // make a planner let mut real_planner = RealFftPlanner::::new(); // create a FFT let r2c = real_planner.plan_fft_forward(length); // make a dummy real-valued signal (filled with zeros) let mut indata = r2c.make_input_vec(); // make a vector for storing the spectrum let mut spectrum = r2c.make_output_vec(); // Are they the length we expect? assert_eq!(indata.len(), length); assert_eq!(spectrum.len(), length/2+1); // forward transform the signal r2c.process(&mut indata, &mut spectrum).unwrap(); // create an inverse FFT let c2r = real_planner.plan_fft_inverse(length); // create a vector for storing the output let mut outdata = c2r.make_output_vec(); assert_eq!(outdata.len(), length); // inverse transform the spectrum back to a real-valued signal c2r.process(&mut spectrum, &mut outdata).unwrap(); ``` -------------------------------- ### RealFftPlanner: Create and Cache FFT Instances Source: https://context7.com/henquist/realfft/llms.txt The RealFftPlanner acts as a factory for creating and caching FFT instances for both forward and inverse transforms. It supports f32 and f64 precisions and reuses previously created instances for the same signal length, optimizing performance by avoiding redundant computations. ```rust use realfft::RealFftPlanner; use rustfft::num_complex::Complex; // Create planner for f64 precision let mut planner = RealFftPlanner::::new(); // Create forward FFT for 1024-element signal let fft_forward = planner.plan_fft_forward(1024); // Create inverse FFT for 1024-element signal let fft_inverse = planner.plan_fft_inverse(1024); // Subsequent calls with same length return cached instances let fft_forward_cached = planner.plan_fft_forward(1024); // Reuses existing // For f32 precision let mut planner_f32 = RealFftPlanner::::new(); let fft_f32 = planner_f32.plan_fft_forward(512); ``` -------------------------------- ### RustFFT Forward and Inverse Transform with Normalization Source: https://context7.com/henquist/realfft/llms.txt Demonstrates a complete round-trip FFT process using RealFFT in Rust. It includes creating a signal, performing a forward FFT, an inverse FFT, and finally normalizing the reconstructed signal by 1/N. This snippet highlights the necessity of scaling for accurate reconstruction. ```rust use realfft::RealFftPlanner; let length = 256; let mut planner = RealFftPlanner::::new(); // Create original signal let r2c = planner.plan_fft_forward(length); let mut original = r2c.make_input_vec(); for i in 0..length { original[i] = (i as f64).sin(); } let original_copy = original.clone(); // Forward transform let mut spectrum = r2c.make_output_vec(); r2c.process(&mut original, &mut spectrum).unwrap(); // Inverse transform let c2r = planner.plan_fft_inverse(length); let mut reconstructed = c2r.make_output_vec(); c2r.process(&mut spectrum, &mut reconstructed).unwrap(); // Normalize by 1/N for round-trip let scale = 1.0 / length as f64; for val in reconstructed.iter_mut() { *val *= scale; } // Verify reconstruction let max_error: f64 = original_copy.iter() .zip(reconstructed.iter()) .map(|(a, b)| (a - b).abs()) .fold(0.0, f64::max); println!("Reconstruction error: {:.2e}", max_error); ``` -------------------------------- ### Rust: Optimize FFT Transforms with Reusable Scratch Buffers Source: https://context7.com/henquist/realfft/llms.txt Demonstrates how to reuse scratch buffers for FFT transforms to improve performance in loops. This avoids repeated memory allocations by planning and allocating buffers once, then using them across multiple processing cycles. It's ideal for real-time or high-frequency transform applications. ```rust use realfft::RealFftPlanner; let length = 1024; let mut planner = RealFftPlanner::::new(); let r2c = planner.plan_fft_forward(length); // Allocate buffers once let mut input = r2c.make_input_vec(); let mut spectrum = r2c.make_output_vec(); let mut scratch = r2c.make_scratch_vec(); // Process multiple frames without reallocating scratch for frame_num in 0..1000 { // Fill input with new data for (i, val) in input.iter_mut().enumerate() { *val = ((frame_num + i) as f64).sin(); } // Transform using pre-allocated scratch buffer r2c.process_with_scratch(&mut input, &mut spectrum, &mut scratch) .expect("FFT failed"); // Process spectrum... let magnitude = spectrum[10].norm(); // Scratch buffer can be larger than minimum required // Check minimum: let min_scratch = r2c.get_scratch_len(); } ``` -------------------------------- ### Rust: Thread-Safe Concurrent FFT Processing with Arc Source: https://context7.com/henquist/realfft/llms.txt Illustrates how to leverage Rust's `Send` and `Sync` traits to share FFT instances across multiple threads using `Arc`. Each thread can independently process signals using its own input/output buffers, preventing duplicated planning overhead and enabling efficient parallel computation. ```rust use realfft::RealFftPlanner; use std::sync::Arc; use std::thread; let mut planner = RealFftPlanner::::new(); let fft = planner.plan_fft_forward(512); // Share FFT across threads let threads: Vec<_> = (0..4) .map(|thread_id| { let fft_clone = Arc::clone(&fft); thread::spawn(move || { // Each thread has its own buffers let mut input = fft_clone.make_input_vec(); let mut spectrum = fft_clone.make_output_vec(); // Fill with thread-specific data for (i, val) in input.iter_mut().enumerate() { *val = ((thread_id * 1000 + i) as f32).sin(); } // Process independently fft_clone.process(&mut input, &mut spectrum) .expect("FFT failed"); // Return result spectrum[20].norm() }) }) .collect(); // Collect results let results: Vec = threads.into_iter() .map(|t| t.join().unwrap()) .collect(); println!("Processed {} signals in parallel", results.len()); ``` -------------------------------- ### ComplexToReal: Perform Inverse Complex-to-Real FFT Source: https://context7.com/henquist/realfft/llms.txt Transforms a complex frequency spectrum back into a real-valued time-domain signal using the ComplexToReal trait. It accepts N/2+1 complex inputs and produces N real outputs. Input constraints include zero imaginary parts for the first and, if applicable, the middle complex bins, otherwise an error is returned. ```rust use realfft::RealFftPlanner; use rustfft::num_complex::Complex; let length = 256; let mut planner = RealFftPlanner::::new(); let c2r = planner.plan_fft_inverse(length); // Create complex spectrum (e.g., from previous forward FFT) let mut spectrum = c2r.make_input_vec(); spectrum[10] = Complex::new(100.0, 50.0); // Add energy at bin 10 spectrum[0] = Complex::new(0.0, 0.0); // DC must have im=0 if length % 2 == 0 { spectrum[length/2].im = 0.0; // Nyquist must have im=0 } // Create output buffer let mut output = c2r.make_output_vec(); // Perform inverse FFT match c2r.process(&mut spectrum, &mut output) { Ok(_) => { println!("Inverse FFT completed: {} complex bins -> {} real samples", spectrum.len(), output.len()); // Note: output is not normalized, scale by 1/length if needed } Err(e) => { eprintln!("Inverse FFT warning/error: {}", e); // Transform still completed, but input had invalid zero constraints } } ``` -------------------------------- ### RealToComplex: Perform Forward Real-to-Complex FFT Source: https://context7.com/henquist/realfft/llms.txt Transforms a real-valued signal into its complex frequency spectrum using the RealToComplex trait. An input signal of length N produces N/2+1 complex output values. The input buffer is modified during processing and should be treated as scratch space afterward. Error handling is included for the processing step. ```rust use realfft::RealFftPlanner; use rustfft::num_complex::Complex; let length = 256; let mut planner = RealFftPlanner::::new(); let r2c = planner.plan_fft_forward(length); // Create input signal with sample data let mut input = r2c.make_input_vec(); for (i, val) in input.iter_mut().enumerate() { *val = (2.0 * std::f64::consts::PI * 10.0 * i as f64 / length as f64).sin(); } // Create output spectrum buffer let mut spectrum = r2c.make_output_vec(); // Perform forward FFT match r2c.process(&mut input, &mut spectrum) { Ok(_) => { println!("FFT completed: {} real samples -> {} complex bins", length, spectrum.len()); println!("DC component: {}", spectrum[0].re); // spectrum[0].im is always 0 // For even lengths, spectrum[length/2].im is also 0 } Err(e) => eprintln!("FFT error: {}", e), } ``` -------------------------------- ### Rust: Handle RealFFT Errors with FftError Enum Source: https://context7.com/henquist/realfft/llms.txt Shows how to handle errors returned by the RealFFT library using the `FftError` enum. This enum provides specific variants for buffer size mismatches, invalid input constraints, and other issues, facilitating robust error management within Rust's standard error handling mechanisms. ```rust use realfft::{RealFftPlanner, FftError}; let length = 100; let mut planner = RealFftPlanner::::new(); let r2c = planner.plan_fft_forward(length); let mut input = vec![0.0; 50]; // Wrong size! let mut spectrum = r2c.make_output_vec(); match r2c.process(&mut input, &mut spectrum) { Ok(_) => println!("Success"), Err(FftError::InputBuffer(expected, got)) => { eprintln!("Input size mismatch: expected {}, got {}", expected, got); } Err(FftError::OutputBuffer(expected, got)) => { eprintln!("Output size mismatch: expected {}, got {}", expected, got); } Err(FftError::ScratchBuffer(min_needed, got)) => { eprintln!("Scratch buffer too small: need {}, got {}", min_needed, got); } Err(FftError::InputValues(first_invalid, last_invalid)) => { eprintln!("Invalid zero constraints violated: first={}, last={}", first_invalid, last_invalid); // Transform was still performed but may be incorrect } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.