Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
vca.hpp
Go to the documentation of this file.
1#pragma once
2
33
35
36#include <algorithm>
37#include <cmath>
38#include <cstdint>
39
40namespace pulp::signal {
41
42enum class VcaResponse : std::uint8_t { linear, exponential };
43
52template <typename SampleType = float>
53class VcaT {
54public:
56
58 static constexpr double kMinRangeDb = 12.0;
59 static constexpr double kMaxRangeDb = 120.0;
60 static constexpr double kDefaultRangeDb = 60.0;
61
64 static constexpr double kDefaultLagMs = 1.0;
65
66 void prepare(SampleType sample_rate) {
67 sample_rate_ = std::isfinite(static_cast<double>(sample_rate)) &&
68 sample_rate > SampleType{0}
69 ? sample_rate
70 : SampleType{1};
71 update_lag_();
72 reset();
73 }
74
75 void set_response(Response r) { response_ = r; }
76 Response response() const { return response_; }
77
78 void set_range_db(double db) {
79 if (!std::isfinite(db)) return;
80 range_db_ = std::clamp(db, kMinRangeDb, kMaxRangeDb);
81 }
82
83 double range_db() const { return range_db_; }
84
85 void set_lag_ms(double ms) {
86 if (!std::isfinite(ms)) return;
87 lag_ms_ = std::max(0.0, ms);
88 update_lag_();
89 }
90
91 void reset(SampleType control = SampleType{0}) {
92 lag_.set_immediate(control);
93 last_control_ = control;
94 }
95
98 SampleType gain_for(SampleType control) const {
99 if (!std::isfinite(static_cast<double>(control))) return SampleType{0};
100 const SampleType c = std::clamp(control, SampleType{0}, SampleType{1});
101 if (response_ == Response::linear) return c;
102 if (c <= SampleType{0}) return SampleType{0};
103 // Equal control travel is equal dB travel. Keep the endpoint special
104 // so a wide-open VCA remains exactly bit-transparent.
105 if (c >= SampleType{1}) return SampleType{1};
106 return static_cast<SampleType>(
107 std::pow(10.0, (-range_db_ / 20.0) *
108 (1.0 - static_cast<double>(c))));
109 }
110
112 SampleType next_gain(SampleType control) {
113 if (!std::isfinite(static_cast<double>(control))) control = SampleType{0};
114 const SampleType target = std::clamp(control, SampleType{0}, SampleType{1});
115 // Re-targeting every sample would restart the ramp every sample and the
116 // value would approach the target without ever arriving. Only a genuine
117 // change starts a new ramp, so a held control lands exactly.
118 if (target != last_control_) {
119 lag_.set_target(target);
120 last_control_ = target;
121 }
122 return gain_for(lag_.next());
123 }
124
125 SampleType process(SampleType input, SampleType control) {
126 return input * next_gain(control);
127 }
128
131 SampleType control() const { return lag_.current(); }
132
133private:
134 void update_lag_() {
135 lag_.set_ramp_time(static_cast<SampleType>(lag_ms_ * 0.001), sample_rate_);
136 }
137
138 SmoothedValue<SampleType> lag_{};
139 SampleType sample_rate_ = SampleType{48000};
140 SampleType last_control_ = SampleType{0};
141 double lag_ms_ = kDefaultLagMs;
142 double range_db_ = kDefaultRangeDb;
143 Response response_ = Response::linear;
144};
145
148
149} // namespace pulp::signal
Voltage-controlled amplifier.
Definition vca.hpp:53
float control() const
Definition vca.hpp:131
static constexpr double kMaxRangeDb
Definition vca.hpp:59
static constexpr double kDefaultLagMs
Definition vca.hpp:64
void set_range_db(double db)
Definition vca.hpp:78
void set_response(Response r)
Definition vca.hpp:75
SampleType gain_for(SampleType control) const
Static response curve, without the lag.
Definition vca.hpp:98
void set_lag_ms(double ms)
Definition vca.hpp:85
static constexpr double kDefaultRangeDb
Definition vca.hpp:60
void prepare(SampleType sample_rate)
Definition vca.hpp:66
static constexpr double kMinRangeDb
Definition vca.hpp:58
double range_db() const
Definition vca.hpp:83
VcaResponse Response
Definition vca.hpp:55
void reset(SampleType control=SampleType{0})
Definition vca.hpp:91
SampleType next_gain(SampleType control)
Advance the lag by one sample and return the gain that would be applied.
Definition vca.hpp:112
Response response() const
Definition vca.hpp:76
SampleType process(SampleType input, SampleType control)
Definition vca.hpp:125
Definition additive_bank.hpp:218
VcaResponse
Definition vca.hpp:42
@ exponential
Definition mod_tools.hpp:106
@ c
Definition spectrum_trace.hpp:35
@ linear
2-point. Cheapest; audible imaging when pitching up.
Definition granular.hpp:133
VcaT< float > Vca
Definition vca.hpp:146
VcaT< double > Vca64
Definition vca.hpp:147