1use scirs2_core::ndarray::Array1;
10use scirs2_core::random::thread_rng;
11use std::f32::consts::PI;
12
13pub trait SignalGenerator {
15 fn next_sample(&mut self) -> f32;
17
18 fn generate(&mut self, n: usize) -> Array1<f32> {
20 let samples: Vec<f32> = (0..n).map(|_| self.next_sample()).collect();
21 Array1::from_vec(samples)
22 }
23
24 fn reset(&mut self);
26}
27
28#[derive(Debug, Clone)]
30pub struct SineGenerator {
31 frequency: f32,
32 amplitude: f32,
33 phase: f32,
34 sample_rate: f32,
35 sample_index: usize,
36}
37
38impl SineGenerator {
39 pub fn new(frequency: f32, amplitude: f32, sample_rate: f32) -> Self {
41 Self {
42 frequency,
43 amplitude,
44 phase: 0.0,
45 sample_rate,
46 sample_index: 0,
47 }
48 }
49
50 pub fn with_phase(mut self, phase: f32) -> Self {
52 self.phase = phase;
53 self
54 }
55}
56
57impl SignalGenerator for SineGenerator {
58 fn next_sample(&mut self) -> f32 {
59 let t = self.sample_index as f32 / self.sample_rate;
60 let sample = self.amplitude * (2.0 * PI * self.frequency * t + self.phase).sin();
61 self.sample_index += 1;
62 sample
63 }
64
65 fn reset(&mut self) {
66 self.sample_index = 0;
67 }
68}
69
70#[derive(Debug, Clone)]
72pub struct SquareGenerator {
73 frequency: f32,
74 amplitude: f32,
75 duty_cycle: f32,
76 sample_rate: f32,
77 sample_index: usize,
78}
79
80impl SquareGenerator {
81 pub fn new(frequency: f32, amplitude: f32, sample_rate: f32) -> Self {
83 Self {
84 frequency,
85 amplitude,
86 duty_cycle: 0.5,
87 sample_rate,
88 sample_index: 0,
89 }
90 }
91
92 pub fn with_duty_cycle(mut self, duty: f32) -> Self {
94 self.duty_cycle = duty.clamp(0.0, 1.0);
95 self
96 }
97}
98
99impl SignalGenerator for SquareGenerator {
100 fn next_sample(&mut self) -> f32 {
101 let t = self.sample_index as f32 / self.sample_rate;
102 let period = 1.0 / self.frequency;
103 let phase = (t % period) / period;
104 let sample = if phase < self.duty_cycle {
105 self.amplitude
106 } else {
107 -self.amplitude
108 };
109 self.sample_index += 1;
110 sample
111 }
112
113 fn reset(&mut self) {
114 self.sample_index = 0;
115 }
116}
117
118#[derive(Debug, Clone)]
120pub struct SawtoothGenerator {
121 frequency: f32,
122 amplitude: f32,
123 sample_rate: f32,
124 sample_index: usize,
125}
126
127impl SawtoothGenerator {
128 pub fn new(frequency: f32, amplitude: f32, sample_rate: f32) -> Self {
130 Self {
131 frequency,
132 amplitude,
133 sample_rate,
134 sample_index: 0,
135 }
136 }
137}
138
139impl SignalGenerator for SawtoothGenerator {
140 fn next_sample(&mut self) -> f32 {
141 let t = self.sample_index as f32 / self.sample_rate;
142 let period = 1.0 / self.frequency;
143 let phase = (t % period) / period;
144 let sample = self.amplitude * (2.0 * phase - 1.0);
145 self.sample_index += 1;
146 sample
147 }
148
149 fn reset(&mut self) {
150 self.sample_index = 0;
151 }
152}
153
154#[derive(Debug, Clone)]
156pub struct TriangleGenerator {
157 frequency: f32,
158 amplitude: f32,
159 sample_rate: f32,
160 sample_index: usize,
161}
162
163impl TriangleGenerator {
164 pub fn new(frequency: f32, amplitude: f32, sample_rate: f32) -> Self {
166 Self {
167 frequency,
168 amplitude,
169 sample_rate,
170 sample_index: 0,
171 }
172 }
173}
174
175impl SignalGenerator for TriangleGenerator {
176 fn next_sample(&mut self) -> f32 {
177 let t = self.sample_index as f32 / self.sample_rate;
178 let period = 1.0 / self.frequency;
179 let phase = (t % period) / period;
180 let sample = self.amplitude * (4.0 * (phase - (phase + 0.5).floor()).abs() - 1.0);
181 self.sample_index += 1;
182 sample
183 }
184
185 fn reset(&mut self) {
186 self.sample_index = 0;
187 }
188}
189
190#[derive(Debug, Clone)]
192pub struct WhiteNoiseGenerator {
193 amplitude: f32,
194 seed: u64,
195 state: u64,
196}
197
198impl WhiteNoiseGenerator {
199 pub fn new(amplitude: f32) -> Self {
201 let seed = thread_rng().random::<u64>();
202 Self {
203 amplitude,
204 seed,
205 state: seed,
206 }
207 }
208
209 pub fn with_seed(amplitude: f32, seed: u64) -> Self {
211 Self {
212 amplitude,
213 seed,
214 state: seed,
215 }
216 }
217
218 fn next_random(&mut self) -> f32 {
220 self.state = self.state.wrapping_mul(1103515245).wrapping_add(12345);
222 ((self.state >> 16) & 0x7fff) as f32 / 32768.0
224 }
225}
226
227impl SignalGenerator for WhiteNoiseGenerator {
228 fn next_sample(&mut self) -> f32 {
229 self.amplitude * (self.next_random() * 2.0 - 1.0)
230 }
231
232 fn reset(&mut self) {
233 self.state = self.seed;
234 }
235}
236
237#[derive(Debug, Clone)]
239pub struct PinkNoiseGenerator {
240 amplitude: f32,
241 seed: u64,
242 state: u64,
243 rows: [f32; 16],
245 running_sum: f32,
246 index: usize,
247}
248
249impl PinkNoiseGenerator {
250 pub fn new(amplitude: f32) -> Self {
252 let seed = thread_rng().random::<u64>();
253 Self {
254 amplitude,
255 seed,
256 state: seed,
257 rows: [0.0; 16],
258 running_sum: 0.0,
259 index: 0,
260 }
261 }
262
263 pub fn with_seed(amplitude: f32, seed: u64) -> Self {
265 Self {
266 amplitude,
267 seed,
268 state: seed,
269 rows: [0.0; 16],
270 running_sum: 0.0,
271 index: 0,
272 }
273 }
274
275 fn next_random(&mut self) -> f32 {
277 self.state = self.state.wrapping_mul(1103515245).wrapping_add(12345);
278 ((self.state >> 16) & 0x7fff) as f32 / 32768.0
279 }
280}
281
282impl SignalGenerator for PinkNoiseGenerator {
283 fn next_sample(&mut self) -> f32 {
284 let last_index = self.index;
286 self.index = (self.index + 1) % (1 << 16);
287
288 let diff = self.index ^ last_index;
290 for i in 0..16 {
291 if (diff >> i) & 1 == 1 {
292 self.running_sum -= self.rows[i];
293 self.rows[i] = self.next_random() * 2.0 - 1.0;
294 self.running_sum += self.rows[i];
295 }
296 }
297
298 self.amplitude * self.running_sum / 16.0
299 }
300
301 fn reset(&mut self) {
302 self.state = self.seed;
303 self.rows = [0.0; 16];
304 self.running_sum = 0.0;
305 self.index = 0;
306 }
307}
308
309#[derive(Debug, Clone)]
311pub struct ImpulseGenerator {
312 amplitude: f32,
313 delay_samples: usize,
314 sample_index: usize,
315}
316
317impl ImpulseGenerator {
318 pub fn new(amplitude: f32, delay_samples: usize) -> Self {
320 Self {
321 amplitude,
322 delay_samples,
323 sample_index: 0,
324 }
325 }
326}
327
328impl SignalGenerator for ImpulseGenerator {
329 fn next_sample(&mut self) -> f32 {
330 let sample = if self.sample_index == self.delay_samples {
331 self.amplitude
332 } else {
333 0.0
334 };
335 self.sample_index += 1;
336 sample
337 }
338
339 fn reset(&mut self) {
340 self.sample_index = 0;
341 }
342}
343
344#[derive(Debug, Clone)]
346pub struct StepGenerator {
347 amplitude: f32,
348 step_sample: usize,
349 sample_index: usize,
350}
351
352impl StepGenerator {
353 pub fn new(amplitude: f32, step_sample: usize) -> Self {
355 Self {
356 amplitude,
357 step_sample,
358 sample_index: 0,
359 }
360 }
361}
362
363impl SignalGenerator for StepGenerator {
364 fn next_sample(&mut self) -> f32 {
365 let sample = if self.sample_index >= self.step_sample {
366 self.amplitude
367 } else {
368 0.0
369 };
370 self.sample_index += 1;
371 sample
372 }
373
374 fn reset(&mut self) {
375 self.sample_index = 0;
376 }
377}
378
379#[derive(Debug, Clone)]
381pub struct ChirpGenerator {
382 start_freq: f32,
383 end_freq: f32,
384 amplitude: f32,
385 duration: f32,
386 sample_rate: f32,
387 sample_index: usize,
388}
389
390impl ChirpGenerator {
391 pub fn new(
393 start_freq: f32,
394 end_freq: f32,
395 amplitude: f32,
396 duration: f32,
397 sample_rate: f32,
398 ) -> Self {
399 Self {
400 start_freq,
401 end_freq,
402 amplitude,
403 duration,
404 sample_rate,
405 sample_index: 0,
406 }
407 }
408}
409
410impl SignalGenerator for ChirpGenerator {
411 fn next_sample(&mut self) -> f32 {
412 let t = self.sample_index as f32 / self.sample_rate;
413 if t > self.duration {
414 return 0.0;
415 }
416
417 let k = (self.end_freq - self.start_freq) / self.duration;
419 let phase = 2.0 * PI * (self.start_freq * t + 0.5 * k * t * t);
422 let sample = self.amplitude * phase.sin();
423
424 self.sample_index += 1;
425 sample
426 }
427
428 fn reset(&mut self) {
429 self.sample_index = 0;
430 }
431}
432
433#[derive(Debug, Clone)]
435pub struct MultiToneGenerator {
436 frequencies: Vec<f32>,
437 amplitudes: Vec<f32>,
438 sample_rate: f32,
439 sample_index: usize,
440}
441
442impl MultiToneGenerator {
443 pub fn new(frequencies: Vec<f32>, amplitudes: Vec<f32>, sample_rate: f32) -> Self {
445 assert_eq!(
446 frequencies.len(),
447 amplitudes.len(),
448 "Frequencies and amplitudes must have same length"
449 );
450 Self {
451 frequencies,
452 amplitudes,
453 sample_rate,
454 sample_index: 0,
455 }
456 }
457
458 pub fn uniform(frequencies: Vec<f32>, amplitude: f32, sample_rate: f32) -> Self {
460 let amplitudes = vec![amplitude / frequencies.len() as f32; frequencies.len()];
461 Self::new(frequencies, amplitudes, sample_rate)
462 }
463}
464
465impl SignalGenerator for MultiToneGenerator {
466 fn next_sample(&mut self) -> f32 {
467 let t = self.sample_index as f32 / self.sample_rate;
468 let sample: f32 = self
469 .frequencies
470 .iter()
471 .zip(self.amplitudes.iter())
472 .map(|(&f, &a)| a * (2.0 * PI * f * t).sin())
473 .sum();
474 self.sample_index += 1;
475 sample
476 }
477
478 fn reset(&mut self) {
479 self.sample_index = 0;
480 }
481}
482
483#[cfg(test)]
484mod tests {
485 use super::*;
486
487 #[test]
488 fn test_sine_generator() {
489 let mut gen = SineGenerator::new(1.0, 1.0, 4.0);
490 let samples = gen.generate(4);
491 assert_eq!(samples.len(), 4);
492 assert!(samples[0].abs() < 0.01);
494 assert!((samples[1] - 1.0).abs() < 0.01);
496 }
497
498 #[test]
499 fn test_square_generator() {
500 let mut gen = SquareGenerator::new(1.0, 1.0, 4.0);
501 let samples = gen.generate(4);
502 assert_eq!(samples.len(), 4);
503 assert_eq!(samples[0], 1.0);
505 assert_eq!(samples[1], 1.0);
506 assert_eq!(samples[2], -1.0);
508 assert_eq!(samples[3], -1.0);
509 }
510
511 #[test]
512 fn test_white_noise() {
513 let mut gen = WhiteNoiseGenerator::new(1.0);
514 let samples = gen.generate(1000);
515 assert_eq!(samples.len(), 1000);
516 let mean: f32 = samples.iter().sum::<f32>() / samples.len() as f32;
518 assert!(mean.abs() < 0.1);
519 }
520
521 #[test]
522 fn test_impulse_generator() {
523 let mut gen = ImpulseGenerator::new(1.0, 2);
524 let samples = gen.generate(5);
525 assert_eq!(samples[0], 0.0);
526 assert_eq!(samples[1], 0.0);
527 assert_eq!(samples[2], 1.0);
528 assert_eq!(samples[3], 0.0);
529 }
530
531 #[test]
532 fn test_step_generator() {
533 let mut gen = StepGenerator::new(1.0, 2);
534 let samples = gen.generate(5);
535 assert_eq!(samples[0], 0.0);
536 assert_eq!(samples[1], 0.0);
537 assert_eq!(samples[2], 1.0);
538 assert_eq!(samples[3], 1.0);
539 }
540
541 #[test]
542 fn test_chirp_generator() {
543 let mut gen = ChirpGenerator::new(1.0, 10.0, 1.0, 1.0, 100.0);
544 let samples = gen.generate(100);
545 assert_eq!(samples.len(), 100);
546 for s in samples.iter() {
548 assert!(*s >= -1.0 && *s <= 1.0);
549 }
550 }
551
552 #[test]
553 fn test_multi_tone() {
554 let mut gen = MultiToneGenerator::uniform(vec![1.0, 2.0], 1.0, 100.0);
555 let samples = gen.generate(100);
556 assert_eq!(samples.len(), 100);
557 }
558
559 #[test]
560 fn test_reset() {
561 let mut gen = SineGenerator::new(1.0, 1.0, 4.0);
562 let first = gen.generate(4);
563 gen.reset();
564 let second = gen.generate(4);
565
566 for i in 0..4 {
567 assert!((first[i] - second[i]).abs() < 1e-6);
568 }
569 }
570}