Conversation
This commit enhances the library by adding a flexible, `no-std` compatible signal analysis module. The `analysis::spectrum` function can now operate on both generative and recorded waveforms by taking the number of samples to analyze as an argument. This approach addresses previous design feedback by: - Consolidating signal representation within the existing `Waveform` struct, using a `WaveformSource` enum. - Keeping the core library `no-std` and agnostic to audio file formats. - Providing a clear, user-friendly analysis function that avoids panics for generative waveforms. Key changes: - `analysis::spectrum` signature changed to `spectrum(waveform, num_samples)`. - `Waveform` can be created from a slice of recorded samples. - An example demonstrates loading a WAV file and analyzing its frequency spectrum. - Tests are updated to cover both generative and recorded waveform analysis.
This commit introduces several major features and improvements: - A `synthesize` function in the `analysis` module to create a generative `Waveform` from a recorded one, based on its harmonic content. - A `time_spectrum` function (STFT) to analyze the frequency content of a signal over time. - A unified, library-wide `Error` enum to provide robust, panic-free error handling. The `superpose`, `normalize_amplitudes`, `time_spectrum`, and `synthesize` functions now return a `Result` instead of panicking on invalid input. This makes the library's API safer and more consistent. An example, `resynthesis.rs`, demonstrates the full workflow of loading, analyzing, and synthesizing a waveform.
This commit introduces several major features and improvements: - A `synthesize` function in the `analysis` module to create a generative `Waveform` from a recorded one, based on its harmonic content. - A `time_spectrum` function (STFT) to analyze the frequency content of a signal over time. - A unified, library-wide `Error` enum to provide robust, panic-free error handling. All functions that previously panicked now return a `Result`. - Module-level documentation for the new `error` and `analysis` modules. - An updated `README.md` with information on the new signal analysis features. An example, `resynthesis.rs`, demonstrates the full workflow of loading, analyzing, and synthesizing a waveform.
This commit introduces a major architectural change to enable high-fidelity, dynamic waveform synthesis and modulation, and improves the ergonomics of the API. Key changes: - A new `Modulation` enum replaces static `amplitude` and `phase` fields in the `Wave` struct. This allows a wave's properties to be modulated by a static value, a pre-calculated envelope, or another `Wave` acting as a Low-Frequency Oscillator (LFO). - `From` traits are implemented for `Modulation` to allow for more ergonomic construction of `Wave`s (e.g., `amplitude: 0.5.into()`). - The `synthesize` function is enhanced to create `Wave`s with dynamic amplitude and phase envelopes, capturing the time-varying nature of recorded sounds. - A new `modulation.rs` example demonstrates how to create tremolo and vibrato effects using LFOs. - A previously deleted test, `test_wave_function_formatting`, has been restored. - All tests and documentation have been updated to reflect these significant API changes.
There was a problem hiding this comment.
Pull Request Overview
This PR introduces comprehensive signal analysis capabilities to the waver library, transforming it from a pure wave generation library into a full-featured signal processing toolkit that can both generate and analyze waveforms.
- Adds support for recorded waveform sources alongside generative ones
- Introduces dynamic amplitude and phase modulation using envelopes and Low-Frequency Oscillators (LFOs)
- Implements frequency analysis (FFT), time-based frequency analysis (STFT), and waveform synthesis from recorded signals
Reviewed Changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/waveform.rs | Major restructure to support both generative and recorded waveform sources with enhanced iterator implementation |
| src/wave.rs | Adds dynamic modulation support through Modulation enum for amplitude and phase properties |
| src/lib.rs | Updates public API to expose new analysis module and error types |
| src/error.rs | New error handling module for library-wide error management |
| src/analysis.rs | Complete signal analysis module with FFT, STFT, and synthesis capabilities |
| examples/*.rs | Three new examples demonstrating modulation, analysis, and resynthesis features |
| README.md | Updates documentation to reflect new signal analysis capabilities |
| Cargo.toml | Adds dependencies for FFT processing and audio file handling |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
- Add FFT spectrum analysis with sub-bin frequency accuracy - Implement STFT (Short-Time Fourier Transform) for spectrograms - Add advanced waveform synthesis from spectral analysis - Include comprehensive test suite covering all frequency ranges - Support extreme frequency analysis (sub-Hz to GHz) - Implement frequency tracking across time frames - Add utility functions for peak detection and phase unwrapping
- Restructure analysis module from single file to comprehensive module - Update waveform module to support new analysis functionality - Update wave module to integrate with signal analysis features - Remove old analysis.rs in favor of modular approach
- Add rustfft dependency for Fast Fourier Transform operations - Add num-complex for complex number arithmetic in FFT - Update dependencies to support advanced signal processing
- Update analysis.rs example to showcase new spectrum analysis capabilities - Update resynthesis.rs example to demonstrate waveform synthesis from analysis - Include practical examples of FFT and STFT usage - Show integration with the new modular analysis system
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #16 +/- ##
============================================
- Coverage 100.00% 76.76% -23.24%
============================================
Files 2 6 +4
Lines 57 284 +227
============================================
+ Hits 57 218 +161
- Misses 0 66 +66 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- Add QuantizationIterator and DequantizationIterator for efficient sample conversion - Implement QuantizeIterator and DequantizeIterator traits for ergonomic API - Provide quantize_samples() and dequantize_samples() convenience functions - Support all standard integer types (i8, i16, i32, u8, u16, u32) and floats - Use NumCast for safe type conversions without unnecessary intermediate types - Design for no-std compatibility using f32 precision to avoid i128 on embedded platforms
- Remove redundant generic parameter F from spectrum() function, keeping only BitDepth - Update spectrum() to work with any FftNum + Float type instead of forcing f32 conversion - Optimize STFT with native BitDepth precision throughout analysis pipeline - Enhance spectral peak detection with improved parabolic interpolation - Add comprehensive frequency tracking with adaptive tolerance based on frequency ranges - Improve synthesis parameter validation and error handling - Update all analysis utilities to maintain precision without unnecessary type casting - Add better phase unwrapping and smoothing for synthesis quality
- Make Wave and Waveform generic over Float types instead of just integer types - Add quantize() method to Wave for direct sample quantization - Export quantization functions and traits in public API - Update Waveform to work natively with floating-point samples - Remove unnecessary BitDepth constraints and phantom data - Add InvalidParameters error type for better analysis error reporting - Improve iterator implementations for better numerical stability - Update all type conversions to use proper float-to-float casting
- Convert all examples to use f32 waveforms with quantization for output - Update README.md example to demonstrate new quantization workflow - Show proper usage of dequantize_samples() for analysis of integer data - Use QuantizeIterator trait for ergonomic sample conversion in examples - Update synthesis parameters for better quality and performance - Fix RFC URL in documentation to point to current Rust issue
- Add 'diagnostics' feature flag for verbose and expensive analysis tests - Allows users to run comprehensive tests with: cargo test --features diagnostics - Keeps regular test suite fast while providing option for thorough validation
- Remove QuantizedWaveIterator struct that duplicated quantization logic - Update Wave::quantize() to use the quantization module's QuantizeIterator trait - Remove inconsistent AsPrimitive<f32> usage in favor of NumCast from quantization module - Clean up imports by removing unused num_traits imports - Maintain same public API: wave.quantize() still works but now uses the proper trait - Fix lifetime bounds in return type to work with quantization iterator infrastructure This eliminates code duplication and ensures consistent quantization behavior across the entire library using a single source of truth in the quantization module."
- Remove Wave::quantize() method that violated single responsibility principle - Update tests to use trait-based quantization: wave.iter().quantize() - Follow Rust idioms where functionality is extended via traits, not direct methods - Maintain separation of concerns: Wave generates samples, quantization converts them - More consistent with iterator ecosystem (collect, map, filter, etc.) - Users now use: wave.iter().quantize().take(100).collect() This follows The Rust Way™ of extension traits over convenience methods, keeping the Wave struct focused on its core responsibility of sample generation."
- Split quantization.rs into modular structure: - core.rs: quantize_samples and dequantize_samples functions - iterators.rs: QuantizationIterator and DequantizationIterator - traits.rs: QuantizeIterator and DequantizeIterator extension traits - mod.rs: module entry point with re-exports - Move tests into tests/ subdirectory with dedicated test files - Improves code organization and maintainability - All 8 quantization tests passing
- Split wave.rs into modular structure: - types.rs: WaveFunc, Modulation, and Wave types with Display impls - iterator.rs: WaveIterator implementation - mod.rs: module entry point with re-exports - Extract tests into tests/ subdirectory: - basic.rs: core functionality tests (4 tests) - modulation.rs: LFO and envelope tests (4 tests) - edge_cases.rs: boundary condition tests (8 tests) - quantization.rs: integration test (1 test) - Improves separation of concerns and code discoverability - All 17 wave tests passing
- Split waveform.rs into modular structure: - types.rs: WaveformSource and Waveform types - iterator.rs: WaveformIterator and WaveformIteratorSource - mod.rs: module entry point with re-exports - Extract tests into tests/ subdirectory: - basic.rs: basic functionality and normalization (4 tests) - recorded.rs: recorded waveform tests (2 tests) - edge_cases.rs: edge case tests (1 test) - Add internal constructor for WaveformIterator to avoid circular deps - Improves code organization and maintainability - All 7 waveform tests passing
- Change `mod wave` to `pub mod wave` - Change `mod waveform` to `pub mod waveform` - Improves public API discoverability - Allows users to access submodules for advanced use cases - Maintains backward compatibility via re-exports
Update README to reflect all major changes in feature/signal-analysis-final branch: New Features: - Signal analysis module (FFT, STFT, dynamic synthesis) - LFO modulation and envelope support - Float-based precision API (f32, f64) - Quantization utilities module - Support for sub-Hz to GHz frequency ranges Documentation improvements: - Comprehensive feature sections with subsections - Module organization guide (wave, waveform, quantization, analysis, error) - Expanded examples covering all major use cases: * Basic waveform generation * Wave superposition * LFO modulation (tremolo/vibrato) * Signal analysis and resynthesis * Quantization methods - Updated version from 0.1 to 0.2 - Updated installation section - Added TODO for inverse FFT support The README now accurately represents the current state of the library with comprehensive documentation for users to understand and utilize all features.
…diences Broaden README appeal from audio-centric to universal signal processing: Key changes: - Updated opening description to emphasize "entire electromagnetic spectrum" from sub-Hz geological signals to GHz radio frequencies - Reframed "Waveform Generation" as "Signal Generation" - Reframed "Signal Analysis" as "Spectral Analysis" with scientific terminology - Added "Quantization & Data Conversion" section emphasizing precision conversion - Renamed "No-std Compatible" to "Embedded & Bare-Metal" with clearer benefits - Updated module organization to use "signal processing" terminology New "Use Cases" section highlights diverse applications: - Audio Processing (20Hz - 20kHz) - RF Communications (MHz - GHz) - Sensor Signal Processing (sub-Hz - kHz) - Scientific Instrumentation - Seismology & Geophysics - Telecommunications Added scientific/engineering examples: - High-frequency RF carrier generation (100 MHz FM radio) - Low-frequency sensor data analysis (tidal measurements, sub-Hz) - Enhanced STFT example showing time-frequency evolution analysis Terminology changes: - "waveform" → "signal" where appropriate - "audio synthesis" → "waveform synthesis" - "online generation" → "streaming generation" - Emphasized "precision" and "spectral" terminology This positions Waver as a universal signal processing library suitable for physicists, RF engineers, sensor researchers, and anyone working with signals beyond just audio applications.
Fixed two failing doc tests by providing valid sample data:
1. "Analyze Low-Frequency Sensor Data" example:
- Increased sample count from 1000 to 2048 (minimum for 1024-point FFT)
- Fixed variable naming (_phase instead of phase to avoid unused warning)
2. "Signal Analysis and Resynthesis" example:
- Wrapped code in fn main() {} to avoid top-level let statements
- Generated actual 440 Hz sine wave test signal instead of empty vec
- Added proper imports (std::f32::consts::PI)
- Limited STFT iteration to first 5 frames to reduce test time
- Fixed unused variable warning (_new_samples)
3. Fixed markdown formatting:
- Added missing blank line between code block and heading
All 18 doc tests now pass successfully.
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 47 out of 49 changed files in this pull request and generated 7 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
No description provided.