77 lines
1.9 KiB
C++
77 lines
1.9 KiB
C++
|
|
#include "Scope.hpp"
|
|
|
|
#include <iostream>
|
|
|
|
ScopeBuffer::ScopeBuffer(QObject *parent) : QObject(parent) {
|
|
// timer is set in qml
|
|
}
|
|
|
|
ScopeBuffer::ScopeBuffer(ConfigService* config, LoggerService* logger, size_t size) :
|
|
config_(config), logger_(logger), buffer_(size) {
|
|
|
|
}
|
|
|
|
void ScopeBuffer::push(float sample) {
|
|
|
|
size_t w = writeIndex_.fetch_add(1, std::memory_order_relaxed);
|
|
buffer_[w % buffer_.size()] = sample;
|
|
}
|
|
|
|
void ScopeBuffer::read(std::vector<float>& out) {
|
|
|
|
size_t w = writeIndex_.load(std::memory_order_relaxed);
|
|
for(size_t i = 0; i < buffer_.size(); i++) {
|
|
size_t idx = (w + trigger_ + i * wavelength_ / out.size()) % buffer_.size();
|
|
out[i] = buffer_[idx];
|
|
}
|
|
|
|
}
|
|
|
|
Scope::Scope(QQuickItem *parent) : QQuickPaintedItem(parent) {
|
|
setAntialiasing(true);
|
|
}
|
|
|
|
void Scope::setBuffer(ScopeBuffer* scopeBuffer) {
|
|
scopeBuffer_ = scopeBuffer;
|
|
buffer_ = std::vector<float>(scopeBuffer_->size());
|
|
}
|
|
|
|
void Scope::paint(QPainter *painter) {
|
|
|
|
while(scopeBuffer_->spinlock()) {
|
|
// wait
|
|
}
|
|
|
|
if(scopeBuffer_ != nullptr) scopeBuffer_->read(buffer_);
|
|
|
|
// TODO: scale to max amplitude ? probably make it configurable if you want to make scope options
|
|
float maxAmp = 1.0f;
|
|
/*
|
|
for(float s : buffer_) {
|
|
maxAmp = std::max(maxAmp, std::abs(s));
|
|
}
|
|
*/
|
|
|
|
float scaleY = (height() * 0.45f) / maxAmp;
|
|
float midY = height() / 2.0f;
|
|
|
|
painter->fillRect(0, 0, width(), height(), QColor(20, 20, 20));
|
|
|
|
QPen pen;
|
|
pen.setWidthF(3.0f);
|
|
QColor green(50, 255, 70);
|
|
pen.setColor(green);
|
|
painter->setPen(pen);
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
|
|
for(size_t i = 1; i < buffer_.size(); i++) {
|
|
painter->drawLine(
|
|
i * width() / buffer_.size(),
|
|
midY + buffer_[i-1] * scaleY,
|
|
i * width() / buffer_.size(),
|
|
midY + buffer_[i] * scaleY
|
|
);
|
|
}
|
|
}
|