forked from RustAudio/dasp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrms.rs
More file actions
128 lines (120 loc) · 4.31 KB
/
rms.rs
File metadata and controls
128 lines (120 loc) · 4.31 KB
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
//! An extension to the **Signal** trait that monitors the RMS of a signal.
//!
//! ### Required Features
//!
//! - When using `dasp_signal`, this module requires the **rms** feature to be enabled.
//! - When using `dasp`, this module requires the **signal-rms** feature to be enabled.
use crate::Signal;
use dasp_frame::Frame;
use dasp_ring_buffer as ring_buffer;
use dasp_rms as rms;
/// An extension to the **Signal** trait that monitors the RMS of a signal.
///
/// ### Required Features
///
/// - When using `dasp_signal`, this item requires the **rms** feature to be enabled.
/// - When using `dasp`, this item requires the **signal-rms** feature to be enabled.
pub trait SignalRms: Signal {
/// An adaptor that yields the RMS of the signal.
///
/// The window size of the RMS detector is equal to the given ring buffer length.
///
/// # Example
///
/// ```
/// use dasp_ring_buffer as ring_buffer;
/// use dasp_signal::{self as signal, Signal};
/// use dasp_signal::rms::SignalRms;
///
/// fn main() {
/// let frames = [[0.9], [-0.8], [0.6], [-0.9]];
/// let signal = signal::from_iter(frames.iter().cloned());
/// let ring_buffer = ring_buffer::Fixed::from([[0.0]; 2]);
/// let mut rms_signal = signal.rms(ring_buffer);
///
/// let result = rms_signal.next()[0];
/// assert!(f64::abs(result - 0.6363961030678927) < 0.000001,
/// "Expected ~0.6363961030678927, got {}", result);
///
/// let result = rms_signal.next()[0];
/// assert!(f64::abs(result - 0.8514693182963201) < 0.000001,
/// "Expected ~0.8514693182963201, got {}", result);
///
/// let result = rms_signal.next()[0];
/// assert!(f64::abs(result - 0.7071067811865476) < 0.000001,
/// "Expected ~0.7071067811865476, got {}", result);
/// }
/// ```
///
/// ### Required Features
///
/// - When using `dasp_signal`, this item requires the **rms** feature to be enabled.
/// - When using `dasp`, this item requires the **signal-rms** feature to be enabled.
fn rms<S>(self, ring_buffer: ring_buffer::Fixed<S>) -> Rms<Self, S>
where
Self: Sized,
S: ring_buffer::Slice<Element = <Self::Frame as Frame>::Float> + ring_buffer::SliceMut,
{
Rms {
signal: self,
rms: rms::Rms::new(ring_buffer),
}
}
}
/// An adaptor that yields the RMS of the signal.
///
/// The window size of the RMS detector is equal to the given ring buffer length.
///
/// ### Required Features
///
/// - When using `dasp_signal`, this item requires the **rms** feature to be enabled.
/// - When using `dasp`, this item requires the **signal-rms** feature to be enabled.
#[derive(Clone)]
pub struct Rms<S, D>
where
S: Signal,
D: ring_buffer::Slice<Element = <S::Frame as Frame>::Float>,
{
signal: S,
rms: rms::Rms<S::Frame, D>,
}
impl<S, D> Rms<S, D>
where
S: Signal,
D: ring_buffer::Slice<Element = <S::Frame as Frame>::Float> + ring_buffer::SliceMut,
{
/// The same as `Signal::next` but does not calculate the final square root required to
/// determine the RMS.
///
/// ### Required Features
///
/// - When using `dasp_signal`, this item requires the **rms** feature to be enabled.
/// - When using `dasp`, this item requires the **signal-rms** feature to be enabled.
pub fn next_squared(&mut self) -> <Self as Signal>::Frame {
self.rms.next_squared(self.signal.next())
}
/// Consumes the `Rms` signal and returns its inner signal `S` and `Rms` detector.
///
/// ### Required Features
///
/// - When using `dasp_signal`, this item requires the **rms** feature to be enabled.
/// - When using `dasp`, this item requires the **signal-rms** feature to be enabled.
pub fn into_parts(self) -> (S, rms::Rms<S::Frame, D>) {
let Rms { signal, rms } = self;
(signal, rms)
}
}
impl<S, D> Signal for Rms<S, D>
where
S: Signal,
D: ring_buffer::Slice<Element = <S::Frame as Frame>::Float> + ring_buffer::SliceMut,
{
type Frame = <S::Frame as Frame>::Float;
fn next(&mut self) -> Self::Frame {
self.rms.next(self.signal.next())
}
fn is_exhausted(&self) -> bool {
self.signal.is_exhausted()
}
}
impl<T> SignalRms for T where T: Signal {}