2025-03-09 10:16:40 +01:00
|
|
|
#include "agc.h"
|
2025-04-24 22:34:17 +02:00
|
|
|
#include "common/dsp/complex.h"
|
2025-03-09 10:16:40 +01:00
|
|
|
|
|
|
|
|
namespace satdump
|
|
|
|
|
{
|
|
|
|
|
namespace ndsp
|
|
|
|
|
{
|
|
|
|
|
template <typename T>
|
|
|
|
|
AGCBlock<T>::AGCBlock()
|
2025-04-24 22:34:17 +02:00
|
|
|
: BlockSimple<T, T>(std::is_same_v<T, complex_t> ? "agc_cc" : "agc_ff", {{"in", std::is_same_v<T, complex_t> ? DSP_SAMPLE_TYPE_CF32 : DSP_SAMPLE_TYPE_F32}},
|
|
|
|
|
{{"out", std::is_same_v<T, complex_t> ? DSP_SAMPLE_TYPE_CF32 : DSP_SAMPLE_TYPE_F32}})
|
2025-03-09 10:16:40 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
AGCBlock<T>::~AGCBlock()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
2025-04-24 22:34:17 +02:00
|
|
|
uint32_t AGCBlock<T>::process(T *in, uint32_t nsamples, T *out)
|
2025-03-09 10:16:40 +01:00
|
|
|
{
|
2025-04-24 22:34:17 +02:00
|
|
|
for (uint32_t i = 0; i < nsamples; i++)
|
2025-03-09 10:16:40 +01:00
|
|
|
{
|
2025-04-24 22:34:17 +02:00
|
|
|
T output = in[i] * gain;
|
2025-03-09 10:16:40 +01:00
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, float>)
|
|
|
|
|
gain += rate * (reference - fabsf(output));
|
|
|
|
|
if constexpr (std::is_same_v<T, complex_t>)
|
2025-04-24 22:34:17 +02:00
|
|
|
gain += rate * (reference - sqrt(output.real * output.real + output.imag * output.imag));
|
2025-03-09 10:16:40 +01:00
|
|
|
|
|
|
|
|
if (max_gain > 0.0 && gain > max_gain)
|
|
|
|
|
gain = max_gain;
|
|
|
|
|
|
2025-04-24 22:34:17 +02:00
|
|
|
out[i] = output;
|
2025-03-09 10:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
2025-04-24 22:34:17 +02:00
|
|
|
return nsamples;
|
2025-03-09 10:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template class AGCBlock<complex_t>;
|
|
|
|
|
template class AGCBlock<float>;
|
2025-04-24 22:34:17 +02:00
|
|
|
} // namespace ndsp
|
|
|
|
|
} // namespace satdump
|