even more stuff
This commit is contained in:
62
core/src/dsp/bench/peak_level_meter.h
Normal file
62
core/src/dsp/bench/peak_level_meter.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include "../sink.h"
|
||||
|
||||
namespace dsp::bench {
|
||||
template<class T>
|
||||
class PeakLevelMeter : Sink<T> {
|
||||
using base_type = Sink<T>;
|
||||
public:
|
||||
PeakLevelMeter() {}
|
||||
|
||||
PeakLevelMeter(stream<T>* in) { base_type::init(in); }
|
||||
|
||||
T getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
void resetLevel() {
|
||||
assert(base_type::_block_init);
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
level = 0.0f;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, complex_t> || std::is_same_v<T, stereo_t>) {
|
||||
level = { 0.0f, 0.0f };
|
||||
}
|
||||
}
|
||||
|
||||
int process(int count, T* in) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
float lvl = fabsf(in[i]);
|
||||
if (lvl > level) { level = lvl; }
|
||||
}
|
||||
if constexpr (std::is_same_v<T, complex_t>) {
|
||||
float lvlre = fabsf(in[i].re);
|
||||
float lvlim = fabsf(in[i].im);
|
||||
if (lvlre > level.re) { level.re = lvlre; }
|
||||
if (lvlim > level.im) { level.im = lvlim; }
|
||||
}
|
||||
if constexpr (std::is_same_v<T, stereo_t>) {
|
||||
float lvll = fabsf(in[i].l);
|
||||
float lvlr = fabsf(in[i].r);
|
||||
if (lvll > level.l) { level.l = lvll; }
|
||||
if (lvlr > level.r) { level.r = lvlr; }
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int run() {
|
||||
int count = base_type::_in->read();
|
||||
if (count < 0) { return -1; }
|
||||
|
||||
process(count, base_type::_in->readBuf);
|
||||
|
||||
base_type::_in->flush();
|
||||
return count;
|
||||
}
|
||||
|
||||
protected:
|
||||
T level;
|
||||
};
|
||||
}
|
||||
105
core/src/dsp/bench/speed_tester.h
Normal file
105
core/src/dsp/bench/speed_tester.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include <assert.h>
|
||||
#include "../stream.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace dsp::bench {
|
||||
template<class I, class O>
|
||||
class SpeedTester {
|
||||
public:
|
||||
SpeedTester() {}
|
||||
|
||||
SpeedTester(stream<I>* in, stream<O>* out) { init(in, out); }
|
||||
|
||||
void init(stream<I>* in, stream<O>* out) {
|
||||
_in = in;
|
||||
_out = out;
|
||||
_init = true;
|
||||
}
|
||||
|
||||
void setInput(stream<I>* in) {
|
||||
assert(_init);
|
||||
_in = in;
|
||||
}
|
||||
|
||||
void setOutput(stream<O>* out) {
|
||||
assert(_init);
|
||||
_out = out;
|
||||
}
|
||||
|
||||
double benchmark(int durationMs, int bufferSize) {
|
||||
assert(_init);
|
||||
|
||||
// Allocate and fill buffer
|
||||
inCount = bufferSize;
|
||||
randBuf = buffer::alloc<I>(inCount);
|
||||
for (int i = 0; i < inCount; i++) {
|
||||
if constexpr (std::is_same_v<I, complex_t>) {
|
||||
randBuf[i].re = (2.0f * (float)rand() / (float)RAND_MAX) - 1.0f;
|
||||
randBuf[i].im = (2.0f * (float)rand() / (float)RAND_MAX) - 1.0f;
|
||||
}
|
||||
else if constexpr (std::is_same_v<I, float>) {
|
||||
randBuf[i] = (2.0f * (float)rand() / (float)RAND_MAX) - 1.0f;
|
||||
}
|
||||
else {
|
||||
randBuf[i] = rand();
|
||||
}
|
||||
}
|
||||
|
||||
// Run test
|
||||
start();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(durationMs));
|
||||
stop();
|
||||
buffer::free(randBuf);
|
||||
return (double)sampCount * 1000.0 / (double)durationMs;
|
||||
}
|
||||
|
||||
protected:
|
||||
void start() {
|
||||
if (running) { return; }
|
||||
running = true;
|
||||
sampCount = 0;
|
||||
wthr = std::thread(&SpeedTester::writeWorker, this);
|
||||
rthr = std::thread(&SpeedTester::readWorker, this);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (!running) { return; }
|
||||
running = false;
|
||||
_in->stopWriter();
|
||||
_out->stopReader();
|
||||
if (wthr.joinable()) { wthr.join(); }
|
||||
if (rthr.joinable()) { rthr.join(); }
|
||||
_in->clearWriteStop();
|
||||
_out->clearReadStop();
|
||||
}
|
||||
|
||||
void writeWorker() {
|
||||
while (true) {
|
||||
memcpy(_in->writeBuf, randBuf, inCount * sizeof(I));
|
||||
if (!_in->swap(inCount)) { return; }
|
||||
sampCount += inCount;
|
||||
}
|
||||
}
|
||||
|
||||
void readWorker() {
|
||||
while (true) {
|
||||
int count = _out->read();
|
||||
_out->flush();
|
||||
if (count < 0) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
bool _init = false;
|
||||
bool running = false;
|
||||
int inCount;
|
||||
stream<I>* _in;
|
||||
stream<O>* _out;
|
||||
I* randBuf;
|
||||
std::thread wthr;
|
||||
std::thread rthr;
|
||||
uint64_t sampCount;
|
||||
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user