DaisySP
Loading...
Searching...
No Matches
resonator.h
Go to the documentation of this file.
1/*
2Copyright (c) 2020 Electrosmith, Corp, Emilie Gillet
3
4Use of this source code is governed by an MIT-style
5license that can be found in the LICENSE file or at
6https://opensource.org/licenses/MIT.
7*/
8
9#pragma once
10#ifndef DSY_RESONATOR_H
11#define DSY_RESONATOR_H
12
13#include <stdint.h>
14#include <stddef.h>
15#include "Utility/dsp.h"
16#ifdef __cplusplus
17
18
21namespace daisysp
22{
23// We render 4 modes simultaneously since there are enough registers to hold
24// all state variables.
33template <int batch_size>
35{
36 public:
37 enum FilterMode
38 {
39 LOW_PASS,
40 BAND_PASS,
41 BAND_PASS_NORMALIZED,
42 HIGH_PASS
43 };
44
45 ResonatorSvf() {}
46 ~ResonatorSvf() {}
47
48 void Init()
49 {
50 for(int i = 0; i < batch_size; ++i)
51 {
52 state_1_[i] = state_2_[i] = 0.0f;
53 }
54 }
55
56 template <FilterMode mode, bool add>
57 void Process(const float* f,
58 const float* q,
59 const float* gain,
60 const float in,
61 float* out)
62 {
63 float g[batch_size];
64 float r[batch_size];
65 float r_plus_g[batch_size];
66 float h[batch_size];
67 float state_1[batch_size];
68 float state_2[batch_size];
69 float gains[batch_size];
70 for(int i = 0; i < batch_size; ++i)
71 {
72 g[i] = fasttan(f[i]);
73 r[i] = 1.0f / q[i];
74 h[i] = 1.0f / (1.0f + r[i] * g[i] + g[i] * g[i]);
75 r_plus_g[i] = r[i] + g[i];
76 state_1[i] = state_1_[i];
77 state_2[i] = state_2_[i];
78 gains[i] = gain[i];
79 }
80
81 float s_in = in;
82 float s_out = 0.0f;
83 for(int i = 0; i < batch_size; ++i)
84 {
85 const float hp
86 = (s_in - r_plus_g[i] * state_1[i] - state_2[i]) * h[i];
87 const float bp = g[i] * hp + state_1[i];
88 state_1[i] = g[i] * hp + bp;
89 const float lp = g[i] * bp + state_2[i];
90 state_2[i] = g[i] * bp + lp;
91 s_out += gains[i] * ((mode == LOW_PASS) ? lp : bp);
92 }
93 if(add)
94 {
95 *out++ += s_out;
96 }
97 else
98 {
99 *out++ = s_out;
100 }
101
102 for(int i = 0; i < batch_size; ++i)
103 {
104 state_1_[i] = state_1[i];
105 state_2_[i] = state_2[i];
106 }
107 }
108
109 private:
110 static constexpr float kPiPow3 = PI_F * PI_F * PI_F;
111 static constexpr float kPiPow5 = kPiPow3 * PI_F * PI_F;
112 static inline float fasttan(float f)
113 {
114 const float a = 3.260e-01 * kPiPow3;
115 const float b = 1.823e-01 * kPiPow5;
116 float f2 = f * f;
117 return f * (PI_F + f2 * (a + b * f2));
118 }
119
120 float state_1_[batch_size];
121 float state_2_[batch_size];
122};
123
124
134{
135 public:
136 Resonator() {}
137 ~Resonator() {}
138
144 void Init(float position, int resolution, float sample_rate);
145
149 float Process(const float in);
150
154 void SetFreq(float freq);
155
159 void SetStructure(float structure);
160
164 void SetBrightness(float brightness);
165
169 void SetDamping(float damping);
170
171 private:
172 int resolution_;
173 float frequency_, brightness_, structure_, damping_;
174
175 static constexpr int kMaxNumModes = 24;
176 static constexpr int kModeBatchSize = 4;
177 static constexpr float ratiofrac_ = 1.f / 12.f;
178 static constexpr float stiff_frac_ = 1.f / 64.f;
179 static constexpr float stiff_frac_2 = 1.f / .6f;
180
181 float sample_rate_;
182
183 float CalcStiff(float sig);
184
185 float mode_amplitude_[kMaxNumModes];
186 ResonatorSvf<kModeBatchSize> mode_filters_[kMaxNumModes / kModeBatchSize];
187};
188
189} // namespace daisysp
190#endif
191#endif
Resonant Body Simulation.
Definition resonator.h:134
void SetDamping(float damping)
Definition resonator.cpp:129
void Init(float position, int resolution, float sample_rate)
Definition resonator.cpp:6
float Process(const float in)
Definition resonator.cpp:46
void SetStructure(float structure)
Definition resonator.cpp:119
void SetFreq(float freq)
Definition resonator.cpp:114
void SetBrightness(float brightness)
Definition resonator.cpp:124
SVF for use in the Resonator Class .
Definition resonator.h:35
FIR Filter implementation, generic and ARM CMSIS DSP based.
Definition adenv.h:16