EWMA Resonators#
Implementation of the basic (non-tracking) form of the "Resonate" algorithm presented in "Resonate: Efficient Low Latency Spectral Analysis of Audio Signals" and https://alexandrefrancois.org/Resonate/
Pseudocode#
define EWMAResonators ( $f_s$ : sample rate, $f_{min}$ : frequency of lowest resonator, $K$ : number of resonators, $x$ : stream of input samples )
- setup resonators: $\forall k \in { 0, \ldots, K-1 }$
- $f_k := f_{min} \cdot 2^{k / B}$
- $\omega_k := 2 \pi f_k$
- $\tau_k := \dfrac{c_\tau (\log_{10}(1+f_k))^{n_\tau}}{f_k}$
- $c_\tau = \text{given or } 1, \quad n_\tau = \text{given or } 1$
- $\alpha_k := 1 - \exp \left( \frac{-1}{f_s \tau_k} \right)$
- $\beta_k := \text{given or } \alpha_k$
- $\gamma_k := \text{given or } \alpha_k$
- $A_k := \exp(-i \omega_k T_s)$
- $P_k : \mathbb{C}, R_k : \mathbb{C}, \tilde{R}_k : \mathbb{C}, D_k : \mathbb{C}$
- $P_k \leftarrow 1$ , $R_k \leftarrow 0$ , $\tilde{R}_k \leftarrow 0$ , $D_k \leftarrow 1$
- on each input frame $x_{0:M-1}$ :
- on each input $x$ :
- $\forall k \in { 0, \ldots, K-1 }$
- $R_k \leftarrow (1 - \alpha_k) \cdot R_k + \alpha_k \cdot x \cdot P_k$
- $\tilde R_k^{prev} \leftarrow \tilde R_k$
- $\tilde R_k \leftarrow (1-\beta_k),\tilde R_k + \beta_k , R_k$
- $D_k \leftarrow (1 - \gamma_k) , D_k + \gamma_k \tilde{R}_k ( \tilde R_k^{prev})^\ast$
- $P_k \leftarrow P_k \cdot A_k$
- output:
- power $\leftarrow |\tilde{R}_k|^2$
- phase $\leftarrow \arg \tilde{R}_k$
- inst. freq. $\leftarrow \begin{cases} f_k + \dfrac{f_s , \arg D_k}{2 \pi} & \text{if } |D_k| \geq 10^{-6} \ f_k & \text{otherwise} \end{cases}$
- $\forall k \in { 0, \ldots, K-1 }$
- $\forall k \in { 0, \ldots, K-1 }$
- (numerical stabilization of $P_k$ )
- for $f(x) = x^{-1/2}$ , first-order Taylor expansion around $x = 1$ yields: $$f(x) \approx \dfrac{3 - x}{2} =: g(x) \quad (x \approx 1)$$
- $g(|P_k|^2)$ is then used as a scaling factor, which for magnitudes sufficiently close to $1$ has the effect of decreasing $|P_k|$ when larger than 1 and increasing it when smaller than 1
- $P_k \leftarrow P_k \cdot \dfrac{3 - |P_k|^2}{2}$
- (numerical stabilization of $P_k$ )
- on each input $x$ :