/* #define DEBUGTRACE_ENABLED */ #include "lasp_siggen.h" #include "debugtrace.hpp" #include "lasp_mathtypes.h" #include #include 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; 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) { 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(); }