1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
//! Digital Signal Processing (DSP) module.
//!
//! This module provides core DSP building blocks and traits for processing
//! streams of complex-valued and real-valued samples, commonly used in
//! software-defined radio (SDR) and digital signal analysis applications.
//!
//! # Overview
//!
//! The DSP module is organized into specialized submodules, each providing
//! specific signal processing functionality. These modules can be combined
//! to create complete signal processing pipelines for applications like
//! FM demodulation, frequency analysis, and real-time audio streaming.
//!
//! ## DSP Pipeline Example
//!
//! A typical FM radio demodulation pipeline might look like:
//!
//! ```text
//! I/Q Samples → Rotate → Decimator → AFC → Phase Extractor → LowPass Filter → Deemphasis → Audio
//! ↓ ↓ ↓ ↓ ↓ ↓
//! Freq Shift Downsample Freq Corr FM Demod Audio Filter De-emphasis
//! ```
//!
//! # Modules
//!
//! ## Signal Manipulation
//! - [`rotate`]: Complex rotation for frequency shifting and offset correction
//! - [`decimator`]: Sample rate reduction with anti-aliasing filtering
//! - [`filters`]: Digital filter implementations (FIR low-pass, Butterworth, etc.)
//! - [`iir`]: IIR Butterworth filters with zero-phase filtering (filtfilt)
//! - [`window`]: Window functions for filter design (Hamming, Blackman, Hann)
//! - [`buffer`]: Streaming buffer for sample accumulation and consumption
//!
//! ## Carrier and Timing Recovery
//! - [`nco`]: Numerically Controlled Oscillator with Phase-Locked Loop (PLL)
//! - [`symsync`]: Polyphase Symbol Synchronizer for timing recovery
//! - [`pll_filter`]: Reusable second-order PLL loop filter (used by nco and symsync)
//! - [`agc`]: Automatic Gain Control for amplitude normalization
//!
//! ## Advanced Features
//! - [`afc`]: Automatic Frequency Control for frequency offset correction
//!
//! Note: FM demodulation (phase extraction, de-emphasis), RDS decoding,
//! and adaptive resampling have been moved to the `fmradio` crate for better modularity.
//!
//! # Traits
//!
//! - [`DspBlock`]: A trait representing a generic DSP processing block that
//! operates on slices of complex samples and produces complex output.
//!
//! # Feature Flags
//!
//! None currently. Adaptive resampling has been moved to the `fmradio` crate.
//!
//! # Examples
//!
//! ## Basic Frequency Shifting
//!
//! ```
//! use desperado::dsp::{DspBlock, rotate::Rotate};
//! use num_complex::Complex;
//! use std::f32::consts::PI;
//!
//! // Shift frequency by 200 kHz at 2 MHz sample rate
//! let sample_rate = 2_000_000.0;
//! let freq_offset = 200_000.0;
//! let angle = -2.0 * PI * freq_offset / sample_rate;
//!
//! let mut rotator = Rotate::new(angle);
//! let samples = vec![Complex::new(1.0, 0.0); 100];
//! let shifted = rotator.process(&samples);
//! ```
//!
//! # Performance Considerations
//!
//! - **Decimation**: Use decimation early in the pipeline to reduce computational load
//! - **Filter Length**: Longer FIR filters provide better frequency response but cost more CPU
//! - **Batch Processing**: Process larger chunks of samples for better throughput
//! - **Feature Flags**: Only enable features you need to minimize dependencies
//!
//! # Thread Safety
//!
//! DSP blocks maintain internal state and are **not** thread-safe. Each thread should
//! have its own instance of DSP blocks. For parallel processing, create separate instances
//! per thread or use synchronization primitives.
use Complex;
/// 2-pole Chebyshev Type-I low-pass IIR filter.
/// Integer decimator with anti-aliasing FIR filter.
/// Stateless integer downsampler (every-Nth sample).
/// Complex rotation (frequency shifting) DSP block.
/// Trait for DSP blocks that process complex-valued signals.
///
/// This trait represents a generic DSP processing block that takes a slice
/// of complex samples and produces a vector of complex samples. DSP blocks
/// typically maintain internal state between calls to `process()`.
///
/// # Examples
///
/// ```
/// use desperado::dsp::{DspBlock, rotate::Rotate};
/// use num_complex::Complex;
///
/// let mut rotator = Rotate::new(0.1);
/// let input = vec![Complex::new(1.0, 0.0); 10];
/// let output = rotator.process(&input);
/// assert_eq!(output.len(), 10);
/// ```