2026-01-26 21:45:00 -03:00
|
|
|
#include "waveform.h"
|
|
|
|
|
|
|
|
|
|
namespace satdump
|
|
|
|
|
{
|
|
|
|
|
namespace ndsp
|
|
|
|
|
{
|
|
|
|
|
template <typename T>
|
|
|
|
|
WaveformBlock<T>::WaveformBlock()
|
2026-01-27 11:47:14 -03:00
|
|
|
: Block("waveform_" + getShortTypeName<T>(), {}, //
|
2026-01-26 21:45:00 -03:00
|
|
|
{{"out", getTypeSampleType<T>()}})
|
|
|
|
|
{
|
|
|
|
|
d_buffer_size = p_buffer_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
void WaveformBlock<T>::init()
|
|
|
|
|
{
|
|
|
|
|
d_waveform = p_waveform;
|
|
|
|
|
d_samprate = p_samprate;
|
|
|
|
|
d_freq = p_freq;
|
|
|
|
|
d_amp = p_amp;
|
|
|
|
|
d_phase = p_phase;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
WaveformBlock<T>::~WaveformBlock()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
bool WaveformBlock<T>::work()
|
|
|
|
|
{
|
|
|
|
|
if (!work_should_exit)
|
|
|
|
|
{
|
|
|
|
|
auto oblk = outputs[0].fifo->newBufferSamples(d_buffer_size, sizeof(T));
|
|
|
|
|
T *obuf = oblk.template getSamples<T>();
|
|
|
|
|
|
|
|
|
|
if (needs_reinit)
|
|
|
|
|
{
|
|
|
|
|
needs_reinit = false;
|
|
|
|
|
init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int nsamples = d_buffer_size;
|
|
|
|
|
|
|
|
|
|
double noise_imp = 1;
|
|
|
|
|
double noise_snr_linear = 1e3 * pow(10, -150 / 10);
|
|
|
|
|
|
|
|
|
|
if (p_waveform == "cosine")
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < nsamples; i++)
|
|
|
|
|
{
|
2026-02-02 11:57:11 -03:00
|
|
|
float t = i / (double)d_samprate;
|
2026-01-26 21:45:00 -03:00
|
|
|
|
|
|
|
|
d_phase += ((d_phase >= 2.0 * M_PI) * -2.0 * M_PI) + ((d_phase < 0.0) * 2.0 * M_PI);
|
|
|
|
|
|
2026-02-02 11:57:11 -03:00
|
|
|
float cosWave = d_amp * float(cos(2.0 * M_PI * d_freq * t + d_phase));
|
2026-01-26 21:45:00 -03:00
|
|
|
|
2026-02-03 20:42:10 -03:00
|
|
|
tmp_val_f = cosWave;
|
2026-01-26 21:45:00 -03:00
|
|
|
|
2026-02-02 11:57:11 -03:00
|
|
|
float ns = float(sqrt((noise_imp * noise_snr_linear) / 2)) * float(d_rng.gasdev());
|
|
|
|
|
|
2026-02-03 20:42:10 -03:00
|
|
|
tmp_val_f += ns;
|
|
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, float>)
|
|
|
|
|
{
|
|
|
|
|
obuf[i] = tmp_val_f;
|
|
|
|
|
}
|
2026-02-02 11:57:11 -03:00
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, complex_t>)
|
|
|
|
|
{
|
2026-02-03 20:42:10 -03:00
|
|
|
float sinOfCos = d_amp * float(sin(2.0 * M_PI * d_freq * t + d_phase));
|
|
|
|
|
|
|
|
|
|
sinOfCos += ns;
|
|
|
|
|
|
|
|
|
|
obuf[i] = complex_t(tmp_val_f, sinOfCos);
|
2026-02-02 11:57:11 -03:00
|
|
|
}
|
2026-01-26 21:45:00 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (p_waveform == "sine")
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < nsamples; i++)
|
|
|
|
|
{
|
2026-02-02 11:57:11 -03:00
|
|
|
float t = i / (double)d_samprate;
|
2026-01-26 21:45:00 -03:00
|
|
|
|
|
|
|
|
d_phase += ((d_phase >= 2.0 * M_PI) * -2.0 * M_PI) + ((d_phase < 0.0) * 2.0 * M_PI);
|
|
|
|
|
|
2026-02-02 11:57:11 -03:00
|
|
|
float sinWave = d_amp * float(sin(2.0 * M_PI * d_freq * t + d_phase));
|
2026-01-26 21:45:00 -03:00
|
|
|
|
2026-02-03 20:42:10 -03:00
|
|
|
tmp_val_f = sinWave;
|
2026-01-26 21:45:00 -03:00
|
|
|
|
2026-02-02 11:57:11 -03:00
|
|
|
float ns = float(sqrt((noise_imp * noise_snr_linear) / 2)) * float(d_rng.gasdev());
|
|
|
|
|
|
2026-02-03 20:42:10 -03:00
|
|
|
tmp_val_f += ns;
|
|
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, float>)
|
|
|
|
|
{
|
|
|
|
|
obuf[i] = tmp_val_f;
|
|
|
|
|
}
|
2026-02-02 11:57:11 -03:00
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, complex_t>)
|
|
|
|
|
{
|
2026-02-03 20:42:10 -03:00
|
|
|
float cosOfSin = d_amp * float(cos(2.0 * M_PI * d_freq * t + d_phase));
|
|
|
|
|
|
|
|
|
|
cosOfSin += ns;
|
|
|
|
|
|
|
|
|
|
obuf[i] = complex_t(cosOfSin, tmp_val_f);
|
2026-02-02 11:57:11 -03:00
|
|
|
}
|
2026-01-26 21:45:00 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oblk.size = d_buffer_size;
|
|
|
|
|
outputs[0].fifo->wait_enqueue(oblk);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
outputs[0].fifo->wait_enqueue(outputs[0].fifo->newBufferTerminator());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-02-02 11:57:11 -03:00
|
|
|
template class WaveformBlock<complex_t>;
|
2026-01-26 21:45:00 -03:00
|
|
|
template class WaveformBlock<float>;
|
|
|
|
|
} // namespace ndsp
|
|
|
|
|
} // namespace satdump
|