Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
additive_spectral_envelope.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <array>
7#include <cmath>
8#include <cstddef>
9#include <cstdint>
10
11namespace pulp::signal {
12
36enum class SpectralDomain : std::uint8_t { absolute_hz, relative_to_f0 };
37
45public:
48 static constexpr int kMaxBreakpoints = 64;
49
52 void clear() { count_ = 0; }
53
54 int size() const { return count_; }
55
59 bool add(double abscissa, double gain_db) {
60 if (count_ >= kMaxBreakpoints) return false;
61 if (!(std::isfinite(abscissa) && abscissa > 0.0) || !std::isfinite(gain_db))
62 return false;
63 if (count_ > 0 && abscissa <= x_[static_cast<std::size_t>(count_ - 1)])
64 return false;
65 x_[static_cast<std::size_t>(count_)] = abscissa;
66 db_[static_cast<std::size_t>(count_)] = gain_db;
67 ++count_;
68 return true;
69 }
70
75 double gain_db_at(double abscissa) const {
76 if (count_ == 0) return 0.0;
77 if (count_ == 1 || abscissa <= x_[0]) return db_[0];
78 const auto last = static_cast<std::size_t>(count_ - 1);
79 if (abscissa >= x_[last]) return db_[last];
80
81 std::size_t hi = 1;
82 while (hi < last && x_[hi] < abscissa) ++hi;
83 const double lx = std::log2(x_[hi - 1]);
84 const double hx = std::log2(x_[hi]);
85 const double t = (std::log2(abscissa) - lx) / (hx - lx);
86 return db_[hi - 1] + t * (db_[hi] - db_[hi - 1]);
87 }
88
93 static SpectralEnvelope tilt(double db_per_octave, double reference = 1.0) {
95 const double lo = reference * 0.001;
96 const double hi = reference * 1000.0;
97 e.add(lo, db_per_octave * std::log2(lo / reference));
98 e.add(hi, db_per_octave * std::log2(hi / reference));
99 return e;
100 }
101
102private:
103 std::array<double, kMaxBreakpoints> x_{};
104 std::array<double, kMaxBreakpoints> db_{};
105 int count_ = 0;
106};
107
108} // namespace pulp::signal
A break-point spectral envelope: gain in dB as a function of frequency, interpolated linearly in the ...
Definition additive_spectral_envelope.hpp:44
void clear()
Removes every break-point.
Definition additive_spectral_envelope.hpp:52
double gain_db_at(double abscissa) const
Gain in dB at an abscissa.
Definition additive_spectral_envelope.hpp:75
int size() const
Definition additive_spectral_envelope.hpp:54
static constexpr int kMaxBreakpoints
Break-point capacity.
Definition additive_spectral_envelope.hpp:48
bool add(double abscissa, double gain_db)
Appends a break-point.
Definition additive_spectral_envelope.hpp:59
static SpectralEnvelope tilt(double db_per_octave, double reference=1.0)
Builds a constant-slope envelope — db_per_octave measured from reference — as two break-points spanni...
Definition additive_spectral_envelope.hpp:93
Definition additive_bank.hpp:218
@ reference
Platform sine; the compatibility default.
Definition fast_math.hpp:40
@ e
Definition formant_filter_bank.hpp:20
SpectralDomain
This enum exists because "sampling a spectral envelope makes timbrepitch-independent" is only true un...
Definition additive_spectral_envelope.hpp:36
@ relative_to_f0
Definition additive_spectral_envelope.hpp:36
@ absolute_hz
Definition additive_spectral_envelope.hpp:36