109 lines
2.6 KiB
C++
109 lines
2.6 KiB
C++
/* #define DEBUGTRACE_ENABLED */
|
|
#include "debugtrace.hpp"
|
|
#include "lasp_ppm.h"
|
|
#include <mutex>
|
|
|
|
using std::cerr;
|
|
using std::endl;
|
|
|
|
using Lck = std::scoped_lock<std::mutex>;
|
|
using rte = std::runtime_error;
|
|
|
|
PPMHandler::PPMHandler(StreamMgr &mgr, const d decay_dBps)
|
|
: ThreadedInDataHandler(mgr), _decay_dBps(decay_dBps) {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
}
|
|
|
|
bool PPMHandler::inCallback_threaded(const DaqData &d) {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
std::scoped_lock<std::mutex> lck(_mtx);
|
|
|
|
dmat data = d.toFloat();
|
|
/* data.print(); */
|
|
|
|
const us nchannels = d.nchannels;
|
|
assert(data.n_cols == nchannels);
|
|
|
|
if (nchannels != _cur_max.size()) {
|
|
DEBUGTRACE_PRINT("Resizing clip and cur max");
|
|
_cur_max = vd(nchannels, arma::fill::value(1e-80));
|
|
_clip_time = vd(nchannels, arma::fill::value(-1));
|
|
}
|
|
assert(_clip_time.size() == _cur_max.size());
|
|
|
|
/// Obtain max abs values
|
|
vd maxabs = arma::max(arma::abs(data), 0).as_col();
|
|
/* maxabs.print(); */
|
|
|
|
arma::uvec clip_indices = arma::find(maxabs > clip_point);
|
|
arma::uvec clip(nchannels, arma::fill::zeros);
|
|
clip.elem(clip_indices).fill(1);
|
|
|
|
arma::uvec update_max_idx = arma::find(maxabs > _cur_max);
|
|
/* update_max_idx.print(); */
|
|
arma::uvec update_max(nchannels, arma::fill::zeros);
|
|
/* update_max.print(); */
|
|
update_max.elem(update_max_idx).fill(1);
|
|
|
|
assert(_cur_max.size() == _clip_time.size());
|
|
|
|
for (us i = 0; i < nchannels; i++) {
|
|
if (clip(i)) {
|
|
/// Reset clip counter
|
|
_clip_time(i) = 0;
|
|
} else if (_clip_time(i) > clip_indication_time) {
|
|
/// Reset to 'unclipped'
|
|
_clip_time(i) = -1;
|
|
} else if (_clip_time(i) >= 0) {
|
|
/// Add a bit of clip time
|
|
_clip_time(i) += _dt;
|
|
}
|
|
|
|
if (update_max(i)) {
|
|
_cur_max(i) = maxabs(i);
|
|
} else {
|
|
_cur_max(i) *= _alpha;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
std::tuple<vd, arma::uvec> PPMHandler::getCurrentValue() const {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
std::scoped_lock<std::mutex> lck(_mtx);
|
|
|
|
arma::uvec clips(_clip_time.size(), arma::fill::zeros);
|
|
clips.elem(arma::find(_clip_time >= 0)).fill(1);
|
|
|
|
return {20 * arma::log10(_cur_max + arma::datum::eps).as_col(), clips};
|
|
}
|
|
|
|
void PPMHandler::reset(const Daq *daq) {
|
|
|
|
/* DEBUGTRACE_ENTER; */
|
|
std::scoped_lock<std::mutex> lck(_mtx);
|
|
|
|
if (daq) {
|
|
|
|
_cur_max.fill(1e-80);
|
|
;
|
|
_clip_time.fill(-1);
|
|
|
|
const d fs = daq->samplerate();
|
|
/* DEBUGTRACE_PRINT(fs); */
|
|
_dt = daq->framesPerBlock() / fs;
|
|
|
|
_alpha = std::max<d>(d_pow(10, -_dt * _decay_dBps / (20)), 0);
|
|
/* DEBUGTRACE_PRINT(_alpha); */
|
|
}
|
|
}
|
|
|
|
PPMHandler::~PPMHandler() {
|
|
DEBUGTRACE_ENTER;
|
|
std::scoped_lock<std::mutex> lck(_mtx);
|
|
stop();
|
|
}
|