41template <
typename SampleType =
float>
45 std::uint64_t& bytes)
noexcept {
47 const auto bins =
static_cast<std::uint64_t
>(
num_bins);
48 if (!charge.
add<SampleType>(bins) || !charge.
add<SampleType>(bins))
50 bytes = charge.
total();
56 seed_ = seed ? seed : 0x9e3779b97f4a7c15ull;
58 env_a_.assign(
static_cast<size_t>(
num_bins), SampleType{0});
59 env_b_.assign(
static_cast<size_t>(
num_bins), SampleType{0});
74 std::copy(noise_mag, noise_mag + num_bins_, env_b_.begin());
76 std::copy(env_b_.begin(), env_b_.end(), env_a_.begin());
84 void advance() { std::swap(env_a_, env_b_); }
97 synth_gain_ = g > SampleType{0} ? g : SampleType{1};
100 void synthesize(SampleType frac, std::complex<SampleType>* out) {
101 const SampleType f = frac < SampleType{0}
103 : (frac > SampleType{1} ? SampleType{1} : frac);
104 for (
int k = 0; k < num_bins_; ++k) {
105 const SampleType mag = (env_a_[
static_cast<size_t>(k)] * (SampleType{1} - f)
106 + env_b_[
static_cast<size_t>(k)] * f) * synth_gain_;
107 const SampleType phase = next_phase();
108 out[k] = std::polar(mag, phase);
115 for (
int k = 0; k < num_bins_; ++k)
116 scratch_[
static_cast<size_t>(k)] = full_mag[k] * noise_mask[k];
121 scratch_.assign(
static_cast<size_t>(num_bins_), SampleType{0});
125 SampleType next_phase() {
129 const std::uint64_t r = rng_ * 0x2545f4914f6cdd1dull;
131 const double u =
static_cast<double>(r >> 11) * (1.0 / 9007199254740992.0);
132 return static_cast<SampleType
>((
u * 2.0 - 1.0) * 3.14159265358979323846);
136 SampleType synth_gain_ = SampleType{1};
137 std::uint64_t seed_ = 0;
138 std::uint64_t rng_ = 0;
139 bool have_prev_ =
false;
140 std::vector<SampleType> env_a_;
141 std::vector<SampleType> env_b_;
142 std::vector<SampleType> scratch_;
Definition checked_allocation.hpp:57
bool add(std::uint64_t elements) noexcept
Definition checked_allocation.hpp:63
std::uint64_t total() const noexcept
Definition checked_allocation.hpp:83
RT contract: prepare() and prepare_masked_scratch() allocate storage and must run off the audio threa...
Definition noise_morpher.hpp:42
void set_synthesis_gain(SampleType g)
Emit one synthesis frame at interpolation position frac in [0,1] between the previous and current env...
Definition noise_morpher.hpp:96
void advance()
Commit the current "to" envelope as the next "from" endpoint.
Definition noise_morpher.hpp:84
void synthesize(SampleType frac, std::complex< SampleType > *out)
Definition noise_morpher.hpp:100
static bool checked_retained_bytes(int num_bins, std::uint64_t target_max_bytes, std::uint64_t &bytes) noexcept
Definition noise_morpher.hpp:44
void prepare(int num_bins, std::uint64_t seed=0x9e3779b97f4a7c15ull)
Definition noise_morpher.hpp:54
void push_masked_envelope(const SampleType *full_mag, const SampleType *noise_mask)
Convenience: pull the noise component out of a full magnitude frame using an STN noise mask,...
Definition noise_morpher.hpp:114
int num_bins() const
Definition noise_morpher.hpp:63
void push_envelope(const SampleType *noise_mag)
Set the noise magnitude envelope for the current analysis frame.
Definition noise_morpher.hpp:73
void prepare_masked_scratch()
Definition noise_morpher.hpp:120
void reset()
Definition noise_morpher.hpp:65
Definition additive_bank.hpp:218
@ u
Definition formant_filter_bank.hpp:20
NoiseMorpherT< float > NoiseMorpher
Definition noise_morpher.hpp:145
NoiseMorpherT< double > NoiseMorpher64
Definition noise_morpher.hpp:146