29 std::vector<ComplexType>
CwSignal::render(
const std::vector<interp::InterpPoint>& ,
unsigned& size,
37 std::unique_ptr<Signal> signal,
const SimId id) :
39 _power(power), _carrierfreq(carrierfreq), _length(length), _signal(std::move(signal))
43 throw std::runtime_error(
"Signal is empty");
47 std::vector<ComplexType>
RadarSignal::render(
const std::vector<interp::InterpPoint>& points,
unsigned& size,
50 auto data = _signal->render(points, size, fracWinDelay);
51 const RealType scale = std::sqrt(_power);
53 std::ranges::for_each(data, [scale](
auto& value) { value *= scale; });
68 _data.resize(samples * ratio);
69 _size = samples * ratio;
70 _rate = sampleRate * ratio;
74 std::ranges::copy(inData, _data.begin());
82 std::vector<ComplexType>
Signal::render(
const std::vector<interp::InterpPoint>& points,
unsigned& size,
83 const double fracWinDelay)
const
85 auto out = std::vector<ComplexType>(_size);
88 const RealType timestep = 1.0 / _rate;
92 auto iter = points.begin();
93 auto next = points.size() > 1 ? std::next(iter) : iter;
94 const RealType idelay = std::round(_rate * iter->delay);
97 for (
int i = 0; i < static_cast<int>(_size); ++i)
99 if (sample_time > next->time && next != iter)
102 if (std::next(next) != points.end())
108 auto [amplitude, phase, fdelay, i_sample_unwrap] =
109 calculateWeightsAndDelays(iter, next, sample_time, idelay, fracWinDelay);
110 const auto& filt =
interp.getFilter(fdelay);
111 ComplexType accum = performConvolution(i, filt.data(), filt_length, amplitude, i_sample_unwrap);
112 out[
static_cast<std::size_t
>(i)] = std::exp(
ComplexType(0.0, 1.0) * phase) * accum;
114 sample_time += timestep;
120 std::tuple<RealType, RealType, RealType, int>
121 Signal::calculateWeightsAndDelays(
const std::vector<interp::InterpPoint>::const_iterator iter,
122 const std::vector<interp::InterpPoint>::const_iterator next,
124 const RealType fracWinDelay)
const noexcept
126 const RealType bw = iter < next ? (sampleTime - iter->time) / (next->time - iter->time) : 0.0;
128 const RealType amplitude = std::lerp(std::sqrt(iter->power), std::sqrt(next->power), bw);
129 const RealType phase = std::lerp(iter->phase, next->phase, bw);
130 RealType fdelay = -(std::lerp(iter->delay, next->delay, bw) * _rate - idelay + fracWinDelay);
132 const int i_sample_unwrap =
static_cast<int>(std::floor(fdelay));
133 fdelay -= i_sample_unwrap;
135 return {amplitude, phase, fdelay, i_sample_unwrap};
138 ComplexType Signal::performConvolution(
const int i,
const RealType* filt,
const int filtLength,
139 const RealType amplitude,
const int iSampleUnwrap)
const noexcept
141 const int start = std::max(-filtLength / 2, -i);
142 const int end = std::min(filtLength / 2,
static_cast<int>(_size) - i);
146 for (
int j = start; j < end; ++j)
148 const int sample_idx = i + j + iSampleUnwrap;
149 const int filt_idx = j + filtLength / 2;
150 if (sample_idx >= 0 && sample_idx <
static_cast<int>(_size) && filt_idx >= 0 && filt_idx < filtLength)
152 accum += amplitude * _data[
static_cast<std::size_t
>(sample_idx)] * filt[filt_idx];
Thread-safe Meyers singleton for generating unique object IDs.
std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, RealType fracWinDelay) const override
Renders the signal data.
RadarSignal(std::string name, RealType power, RealType carrierfreq, RealType length, std::unique_ptr< Signal > signal, const SimId id=0)
Constructs a RadarSignal object.
std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, RealType fracWinDelay) const
Renders the radar signal.
void clear() noexcept
Clears the internal signal data.
void load(std::span< const ComplexType > inData, unsigned samples, RealType sampleRate)
Loads complex radar waveform data.
virtual std::vector< ComplexType > render(const std::vector< interp::InterpPoint > &points, unsigned &size, double fracWinDelay) const
Renders the signal data based on interpolation points.
static InterpFilter & getInstance() noexcept
Retrieves the singleton instance of the InterpFilter class.
double RealType
Type for real numbers.
std::complex< RealType > ComplexType
Type for complex numbers.
Header file for Digital Signal Processing (DSP) filters and upsampling/downsampling functionality.
Interpolation filter implementation using Kaiser windowing.
Defines a structure to store interpolation point data for signal processing.
void upsample(const std::span< const ComplexType > in, const unsigned size, std::span< ComplexType > out)
Upsamples a signal by a given ratio.
unsigned oversampleRatio() noexcept
Get the oversampling ratio.
unsigned renderFilterLength() noexcept
Get the render filter length.
Defines the Parameters struct and provides methods for managing simulation parameters.
Classes for handling radar waveforms and signals.
uint64_t SimId
64-bit Unique Simulation ID.
ObjectType
Categorizes objects for ID generation.