lasp/cpp_src/dsp/lasp_siggen.cpp

96 lines
2.2 KiB
C++

/* #define DEBUGTRACE_ENABLED */
#include "lasp_siggen.h"
#include "debugtrace.hpp"
#include "lasp_mathtypes.h"
#include <cassert>
#include <type_traits>
using std::cerr;
using std::endl;
using rte = std::runtime_error;
inline d level_amp(d level_dB) { return pow(10, level_dB / 20); }
using slock = std::scoped_lock<std::recursive_mutex>;
vd Siggen::genSignal(const us nframes) {
DEBUGTRACE_ENTER;
slock lck(_mtx);
DEBUGTRACE_PRINT(nframes);
vd signal(nframes, arma::fill::value(_dc_offset));
if (!_muted) {
vd signal_dynamic = _level_linear * genSignalUnscaled(nframes);
// Filter signal
for (auto f : _filters) {
assert(f.second);
f.second->filter(signal_dynamic);
}
// Check whether we are running / not for signal interruption.
bool activated = false;
if (_interrupt_period_s < 0) {
activated = true;
} else {
if (_interruption_frame_count < _interrupt_period_s*_fs) {
activated = true;
}
_interruption_frame_count += nframes;
if (_interruption_frame_count >= 2 * _interrupt_period_s*_fs) {
_interruption_frame_count = 0;
}
}
if (activated) {
signal += signal_dynamic;
}
} // end if(!_muted)
return signal;
}
void Siggen::setInterruptPeriod(const d newPeriod) {
slock lck(_mtx);
if (newPeriod == 0) {
throw rte("Interruption period cannot be 0");
}
if (newPeriod < 0) {
_interrupt_period_s = -1;
} else {
_interrupt_period_s = newPeriod;
}
}
void Siggen::setFilter(const std::string &name,
std::shared_ptr<Filter> filter) {
DEBUGTRACE_ENTER;
slock lck(_mtx);
if (filter) {
_filters[name] = filter;
} else if (_filters.find(name) != _filters.end()) {
_filters.extract(name);
}
}
void Siggen::setDCOffset(const d offset) {
DEBUGTRACE_ENTER;
slock lck(_mtx);
_dc_offset = offset;
}
void Siggen::setLevel(const d level, bool dB) {
DEBUGTRACE_ENTER;
slock lck(_mtx);
_level_linear = dB ? level_amp(level) : level;
}
void Siggen::reset(const d newFs) {
DEBUGTRACE_ENTER;
slock lck(_mtx);
_fs = newFs;
for (auto &f : _filters) {
assert(f.second);
f.second->reset();
}
_interruption_frame_count = 0;
resetImpl();
}