FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
noise_generators.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2006-2008 Marc Brooker and Michael Inggs
4// Copyright (c) 2008-present FERS Contributors (see AUTHORS.md).
5//
6// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
7
8/**
9 * @file noise_generators.cpp
10 * @brief Implementation file for noise generator classes.
11 */
12
13#include "noise_generators.h"
14
15#include <cmath>
16#include <ranges>
17#include <utility>
18
19#include "core/parameters.h"
20#include "noise/falpha_branch.h"
21
22namespace noise
23{
25 _scale(1.0 / std::pow(10.0, (-alpha + 2.0) * 2.0)), _rng_engine(rngEngine)
26 {
27 const RealType beta = -(alpha - 2) / 2.0;
28 const int fint = static_cast<int>(std::floor(beta));
29 const RealType ffrac = std::fmod(beta, 1.0);
30
31 createTree(ffrac, fint, branches);
32 // TODO: verify scale factor calculation (* 2.0 appears to be a bug)
33 }
34
35 // NOLINTNEXTLINE(readability-make-member-function-const)
36 void MultirateGenerator::skipSamples(const std::size_t samples) noexcept
37 {
38 if (samples == 0)
39 {
40 return;
41 }
42
43 if (const int skip_branches = static_cast<int>(std::log10(static_cast<double>(samples))) - 1; skip_branches > 0)
44 {
45 std::vector<FAlphaBranch*> flushbranches;
46 FAlphaBranch* branch = _topbranch.get();
47
48 for (int i = 0; i < skip_branches && (branch != nullptr); ++i)
49 {
50 flushbranches.push_back(branch);
51 branch = branch->getPre();
52 }
53
54 if (branch != nullptr)
55 {
56 const auto reduced_samples =
57 samples / static_cast<std::size_t>(std::pow(10.0, static_cast<double>(skip_branches)));
58 for (std::size_t i = 0; i < reduced_samples; ++i)
59 {
60 branch->getSample();
61 }
62 }
63
64 for (const auto& fb : std::ranges::reverse_view(flushbranches))
65 {
66 fb->flush(1.0);
67 }
68 }
69 else
70 {
71 for (std::size_t i = 0; i < samples; ++i)
72 {
73 _topbranch->getSample();
74 }
75 }
76 }
77
78 void MultirateGenerator::createTree(const RealType fAlpha, const int fInt, const unsigned branches)
79 {
80 std::unique_ptr<FAlphaBranch> previous_branch = nullptr;
81 for (unsigned i = 0; i < branches; ++i)
82 {
83 previous_branch = std::make_unique<FAlphaBranch>(_rng_engine.get(), fAlpha, fInt,
84 std::move(previous_branch), i == branches - 1);
85 }
86 _topbranch = std::move(previous_branch);
87 }
88
89 // NOLINTNEXTLINE(readability-make-member-function-const)
91 {
92 std::vector<FAlphaBranch*> branches;
93 // NOLINTNEXTLINE(misc-const-correctness): Collected branches are flushed through mutable aliases below.
94 FAlphaBranch* branch = _topbranch.get();
95
96 while (branch != nullptr)
97 {
98 branches.push_back(branch);
99 branch = branch->getPre();
100 }
101
102 for (const auto& b : std::ranges::reverse_view(branches))
103 {
104 b->flush(1.0);
105 }
106 }
107
108 ClockModelGenerator::ClockModelGenerator(std::mt19937& rngEngine, const std::vector<RealType>& alpha,
109 const std::vector<RealType>& inWeights, const RealType frequency,
111 int branches) noexcept :
112 _rng_engine(rngEngine), _weights(inWeights), _phase_offset(phaseOffset), _freq_offset(freqOffset),
113 _frequency(frequency)
114 {
115 for (size_t i = 0; i < alpha.size(); ++i)
116 {
117 auto mgen = std::make_unique<MultirateGenerator>(_rng_engine.get(), alpha[i], branches);
118 _generators.push_back(std::move(mgen));
119
120 switch (static_cast<int>(alpha[i]))
121 {
122 case 2:
123 _weights[i] *= std::pow(10.0, 1.225);
124 break;
125 case 1:
126 _weights[i] *= std::pow(10.0, 0.25);
127 break;
128 case 0:
129 _weights[i] *= std::pow(10.0, -0.25);
130 break;
131 case -1:
132 _weights[i] *= std::pow(10.0, -0.5);
133 break;
134 case -2:
135 _weights[i] *= std::pow(10.0, -1.0);
136 break;
137 default:
138 break;
139 }
140 }
141 }
142
144 {
145 RealType sample = 0;
146 for (size_t i = 0; i < _generators.size(); ++i)
147 {
148 sample += _generators[i]->getSample() * _weights[i];
149 }
150
151 sample += _phase_offset;
152 sample += 2 * PI * _freq_offset * static_cast<double>(_count) / params::rate();
153 ++_count;
154
155 return sample;
156 }
157
158 void ClockModelGenerator::skipSamples(const std::size_t samples)
159 {
160 for (const auto& generator : _generators)
161 {
162 generator->skipSamples(samples);
163 }
164 _count += samples;
165 }
166
168 {
169 // reset() call chain is only called if sync on pulse is enabled,
170 // otherwise the all generators and counts remain as-is
171 for (const auto& generator : _generators)
172 {
173 generator->reset();
174 }
175 _count = 0;
176 }
177
179 {
180 return !_generators.empty() || _freq_offset != 0 || _phase_offset != 0;
181 }
182}
void reset()
Resets the noise generator state.
bool enabled() const
Checks if the noise generator is enabled.
ClockModelGenerator(std::mt19937 &rngEngine, const std::vector< RealType > &alpha, const std::vector< RealType > &inWeights, RealType frequency, RealType phaseOffset, RealType freqOffset, int branches) noexcept
Constructor to initialize the clock model generator.
RealType getSample() override
Generates a clock model noise sample.
void skipSamples(std::size_t samples)
Skips a number of samples in the noise sequence.
Class responsible for generating fractional and integer noise components.
MultirateGenerator(std::mt19937 &rngEngine, RealType alpha, unsigned branches)
Constructor to initialize the multirate generator.
void reset() noexcept
Resets the noise generator state.
void skipSamples(std::size_t samples) noexcept
Skips a number of samples in the noise sequence.
double RealType
Type for real numbers.
Definition config.h:27
constexpr RealType PI
Mathematical constant π (pi).
Definition config.h:43
Implementation of the FAlphaBranch class for noise generation.
RealType rate() noexcept
Get the rendering sample rate.
Definition parameters.h:121
Header file for noise generator classes.
Defines the Parameters struct and provides methods for managing simulation parameters.
math::Vec3 max
RealType b