This commit is contained in:
parent
4fde79b64b
commit
e435dc9ecd
@ -14,6 +14,7 @@ set(lasp_dsp_files
|
||||
lasp_slm.cpp
|
||||
lasp_threadedindatahandler.cpp
|
||||
lasp_ppm.cpp
|
||||
lasp_clip.cpp
|
||||
)
|
||||
|
||||
|
||||
|
94
src/lasp/dsp/lasp_clip.cpp
Normal file
94
src/lasp/dsp/lasp_clip.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* #define DEBUGTRACE_ENABLED */
|
||||
#include "debugtrace.hpp"
|
||||
#include "lasp_clip.h"
|
||||
#include <mutex>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
using Lck = std::scoped_lock<std::mutex>;
|
||||
using rte = std::runtime_error;
|
||||
|
||||
ClipHandler::ClipHandler(StreamMgr &mgr)
|
||||
: ThreadedInDataHandler(mgr){
|
||||
|
||||
DEBUGTRACE_ENTER;
|
||||
}
|
||||
|
||||
bool ClipHandler::inCallback_threaded(const DaqData &d) {
|
||||
|
||||
DEBUGTRACE_ENTER;
|
||||
Lck lck(_mtx);
|
||||
|
||||
dmat data = d.toFloat();
|
||||
|
||||
const us nchannels = d.nchannels;
|
||||
assert(data.n_cols == nchannels);
|
||||
|
||||
if (nchannels != _clip_time.size()) {
|
||||
DEBUGTRACE_PRINT("Resizing clip indication");
|
||||
_clip_time = vd(nchannels, arma::fill::value(-1));
|
||||
}
|
||||
|
||||
/// Obtain max abs values for each column, convert this row-vec to a column
|
||||
/// vector, and scale with the max-range for each channel
|
||||
vd maxabs = arma::max(arma::abs(data), 0).as_col() / _max_range;
|
||||
|
||||
/// Find indices for channels that have a clip
|
||||
arma::uvec clips = maxabs > clip_point;
|
||||
|
||||
for (us i = 0; i < nchannels; i++) {
|
||||
if (clips(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;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
arma::uvec ClipHandler::getCurrentValue() const {
|
||||
|
||||
DEBUGTRACE_ENTER;
|
||||
Lck lck(_mtx);
|
||||
|
||||
arma::uvec clips(_clip_time.size(), arma::fill::zeros);
|
||||
clips.elem(arma::find(_clip_time >= 0)).fill(1);
|
||||
|
||||
return {clips};
|
||||
}
|
||||
|
||||
void ClipHandler::reset(const Daq *daq) {
|
||||
|
||||
DEBUGTRACE_ENTER;
|
||||
Lck lck(_mtx);
|
||||
|
||||
if (daq) {
|
||||
|
||||
const us nchannels = daq->neninchannels();
|
||||
_max_range.resize(nchannels);
|
||||
|
||||
dvec ranges = daq->inputRangeForEnabledChannels();
|
||||
assert(ranges.size() == nchannels);
|
||||
for(us i=0;i<daq->neninchannels();i++) {
|
||||
_max_range[i] = ranges[i];
|
||||
}
|
||||
|
||||
_clip_time.fill(-1);
|
||||
|
||||
const d fs = daq->samplerate();
|
||||
/* DEBUGTRACE_PRINT(fs); */
|
||||
_dt = daq->framesPerBlock() / fs;
|
||||
}
|
||||
}
|
||||
|
||||
ClipHandler::~ClipHandler() {
|
||||
DEBUGTRACE_ENTER;
|
||||
Lck lck(_mtx);
|
||||
stop();
|
||||
}
|
77
src/lasp/dsp/lasp_clip.h
Normal file
77
src/lasp/dsp/lasp_clip.h
Normal file
@ -0,0 +1,77 @@
|
||||
// lasp_clip.h
|
||||
//
|
||||
// Author: J.A. de Jong - ASCEE
|
||||
//
|
||||
// Description: Peak Programme Meter
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "lasp_filter.h"
|
||||
#include "lasp_mathtypes.h"
|
||||
#include "lasp_threadedindatahandler.h"
|
||||
|
||||
/**
|
||||
* \addtogroup dsp
|
||||
* @{
|
||||
*
|
||||
* \addtogroup rt
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clipping detector (Clip). Detects when a signal overdrives the input
|
||||
* */
|
||||
class ClipHandler: public ThreadedInDataHandler {
|
||||
|
||||
/**
|
||||
* @brief Assuming full scale of a signal is +/- 1.0. If a value is found
|
||||
*/
|
||||
static inline const d clip_point = 0.98;
|
||||
|
||||
/**
|
||||
* @brief How long it takes in [s] after a clip event has happened, that we
|
||||
* are actually still in 'clip' mode.
|
||||
*/
|
||||
static inline const d clip_indication_time = 2.0;
|
||||
|
||||
/**
|
||||
* @brief Inverse of block sampling frequency [s]: (framesPerBlock/fs)
|
||||
*/
|
||||
d _dt;
|
||||
|
||||
|
||||
mutable std::mutex _mtx;
|
||||
/**
|
||||
* @brief How long ago the last clip has happened. Negative in case no clip
|
||||
* has happened.
|
||||
*/
|
||||
vd _clip_time;
|
||||
|
||||
/**
|
||||
* @brief Storage for maximum values
|
||||
*/
|
||||
vd _max_range;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs Clipping indicator
|
||||
*
|
||||
* @param mgr Stream Mgr to operate on
|
||||
*/
|
||||
ClipHandler(StreamMgr& mgr);
|
||||
~ClipHandler();
|
||||
|
||||
/**
|
||||
* @brief Get the current values of the clip handler. Returns a vector of of True's.
|
||||
*
|
||||
* @return clipping indication
|
||||
*/
|
||||
arma::uvec getCurrentValue() const;
|
||||
|
||||
bool inCallback_threaded(const DaqData& ) override final;
|
||||
void reset(const Daq*) override final;
|
||||
|
||||
};
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
@ -3,6 +3,7 @@
|
||||
#include "arma_npy.h"
|
||||
#include "debugtrace.hpp"
|
||||
#include "lasp_ppm.h"
|
||||
#include "lasp_clip.h"
|
||||
#include "lasp_rtaps.h"
|
||||
#include "lasp_streammgr.h"
|
||||
#include "lasp_threadedindatahandler.h"
|
||||
@ -192,6 +193,17 @@ void init_datahandler(py::module &m) {
|
||||
ColToNpy<arma::uword>(std::get<1>(tp)));
|
||||
});
|
||||
|
||||
/// Clip Detector
|
||||
py::class_<ClipHandler, ThreadedInDataHandler> clip(m, "ClipHandler");
|
||||
clip.def(py::init<StreamMgr &>());
|
||||
|
||||
clip.def("getCurrentValue", [](const ClipHandler &clip) {
|
||||
|
||||
arma::uvec cval = clip.getCurrentValue();
|
||||
|
||||
return ColToNpy<arma::uword>(cval); // something goes wrong here
|
||||
});
|
||||
|
||||
/// Real time Aps
|
||||
///
|
||||
py::class_<RtAps, ThreadedInDataHandler> rtaps(m, "RtAps");
|
||||
|
Loading…
Reference in New Issue
Block a user