quicklevel polish
parent
b86452b1af
commit
25408ba776
3
notes
3
notes
|
@ -32,7 +32,8 @@ parameters {
|
|||
|
||||
TODO {
|
||||
immediate frontburner {
|
||||
???
|
||||
standardized "draw panel" function in nodeobject
|
||||
^ use in both default draw and quicklevel
|
||||
|
||||
distortion effect
|
||||
single-selection sampler
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
using Xybrid::Gadgets::QuickLevel;
|
||||
using namespace Xybrid::Data;
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGraphicsScene>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
@ -28,7 +31,6 @@ namespace {
|
|||
i->category = "Gadget";
|
||||
i->createInstance = []{ return std::make_shared<QuickLevel>(); };
|
||||
PluginRegistry::registerPlugin(i);
|
||||
//inf = i;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -40,6 +42,29 @@ void QuickLevel::init() {
|
|||
auto in = addPort(Port::Input, Port::Audio, 0);
|
||||
auto out = addPort(Port::Output, Port::Audio, 0);
|
||||
out->passthroughTo = in;
|
||||
|
||||
lv[0][0] = 0;
|
||||
lv[0][1] = 0;
|
||||
lv[1][0] = 0;
|
||||
lv[1][1] = 0;
|
||||
}
|
||||
|
||||
void QuickLevel::reset() {
|
||||
release();
|
||||
auto sr = audioEngine->curSampleRate();
|
||||
buf.setCapacity(static_cast<int>(sr * SPAN_TIME)); // fixed timestep
|
||||
}
|
||||
|
||||
void QuickLevel::release() {
|
||||
buf.clear();
|
||||
buf.setCapacity(0);
|
||||
|
||||
lv[0][0] = 0;
|
||||
lv[0][1] = 0;
|
||||
lv[1][0] = 0;
|
||||
lv[1][1] = 0;
|
||||
|
||||
if (obj) obj->scene()->update();
|
||||
}
|
||||
|
||||
void QuickLevel::process() {
|
||||
|
@ -52,15 +77,29 @@ void QuickLevel::process() {
|
|||
lv[c][1] = std::numeric_limits<double>::min();
|
||||
}
|
||||
|
||||
for (size_t s = 0; s < ts; s++) {
|
||||
AudioFrame f = (*in)[s];
|
||||
// push entire tick; we don't need to clear anything as the buffer's maximum size is exactly how much we want
|
||||
for (size_t s = 0; s < ts; s++) buf.append(static_cast<AudioFrame>((*in)[s]));
|
||||
|
||||
if (!buf.areIndexesValid()) buf.normalizeIndexes();
|
||||
auto fst = buf.firstIndex(), lst = buf.lastIndex();
|
||||
for (int i = fst; i <= lst; i++) {
|
||||
auto f = buf.at(i);
|
||||
lv[0][0] = std::min(lv[0][0], f.l);
|
||||
lv[0][1] = std::max(lv[0][1], f.l);
|
||||
lv[1][0] = std::min(lv[1][0], f.r);
|
||||
lv[1][1] = std::max(lv[1][1], f.r);
|
||||
}
|
||||
|
||||
//if (obj) obj->update(obj->boundingRect());
|
||||
if (obj) obj->scene()->update();
|
||||
}
|
||||
|
||||
// clear levels on port disconnect
|
||||
void QuickLevel::onPortDisconnected(Data::Port::Type, Data::Port::DataType, uint8_t, std::weak_ptr<Data::Port>) {
|
||||
lv[0][0] = 0;
|
||||
lv[0][1] = 0;
|
||||
lv[1][0] = 0;
|
||||
lv[1][1] = 0;
|
||||
|
||||
if (obj) obj->scene()->update();
|
||||
}
|
||||
|
||||
|
@ -68,17 +107,30 @@ void QuickLevel::onGadgetCreated() {
|
|||
if (!obj) return;
|
||||
|
||||
obj->customChrome = true;
|
||||
//obj->autoPositionPorts = false;
|
||||
//qreal ps = (PortObject::portSize + PortObject::portSpacing) * 2;
|
||||
obj->setGadgetSize(QPointF(48, 95));
|
||||
obj->autoPositionPorts = false;
|
||||
obj->setGadgetSize(QPointF(43, 89));
|
||||
|
||||
auto r = obj->boundingRect();
|
||||
auto pm = PortObject::portSize * .5 + PortObject::portSpacing;
|
||||
auto offs = QPointF(r.width() / 2 + pm, 0);
|
||||
obj->inputPortContainer->setPos(r.center() - offs);
|
||||
obj->outputPortContainer->setPos(r.center() + offs);
|
||||
}
|
||||
|
||||
namespace {
|
||||
inline constexpr double dval(double in) {
|
||||
in = std::clamp(in, -1.0, 1.0);
|
||||
double n = in < 0.0 ? -1.0 : 1.0;
|
||||
return std::pow(std::abs(in), QuickLevel::DISPLAY_EXPONENT) * n;
|
||||
}
|
||||
}
|
||||
|
||||
void QuickLevel::drawCustomChrome(QPainter* painter, const QStyleOptionGraphicsItem* opt) {
|
||||
// first, draw backing panel
|
||||
QColor outline = QColor(31, 31, 31);
|
||||
if (opt->state & QStyle::State_Selected) outline = QColor(127, 127, 255);
|
||||
|
||||
auto r = obj->boundingRect();
|
||||
//auto rf = r - QMarginsF(1, 1, 1, 1);
|
||||
|
||||
QLinearGradient fill(QPointF(0, 0), QPointF(0, r.height()));
|
||||
fill.setColorAt(0, QColor(95, 95, 95));
|
||||
|
@ -89,36 +141,41 @@ void QuickLevel::drawCustomChrome(QPainter* painter, const QStyleOptionGraphicsI
|
|||
painter->setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||
painter->setBrush(QBrush(fill));
|
||||
painter->setPen(QPen(QBrush(outline), 2));
|
||||
painter->drawRoundedRect(r, 8, 8);
|
||||
painter->drawRoundedRect(r, 4, 4);
|
||||
|
||||
// set up bar geometry
|
||||
QSizeF barSize(16, 81);
|
||||
//QRectF barL(r.topLeft() + QPointF(1, 1), barSize);
|
||||
QRectF barL(QPointF(), barSize);
|
||||
QRectF barR(QPointF(), barSize);
|
||||
barL.moveCenter(r.center() + QPointF(-10, 0));
|
||||
barR.moveCenter(r.center() + QPointF(10, 0));
|
||||
barL.moveCenter(r.center() + QPointF(-9.5, 0));
|
||||
barR.moveCenter(r.center() + QPointF(9.5, 0));
|
||||
|
||||
double oh = barSize.height() / 2;
|
||||
|
||||
painter->setPen(Qt::NoPen);
|
||||
|
||||
// draw bars
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
auto b = i == 0 ? barL : barR;
|
||||
|
||||
// bg
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(QColor(0, 0, 0, 127));
|
||||
painter->drawRect(b);
|
||||
|
||||
// level
|
||||
QRectF bc(QPoint(), QSizeF(b.width(), 0));
|
||||
bc.moveCenter(b.center());
|
||||
bc.adjust(0, std::clamp(lv[i][1], -1.0, 1.0) * oh, 0, std::clamp(lv[i][0], -1.0, 1.0) * oh);
|
||||
bc.adjust(0, dval(-lv[i][1]) * oh, 0, dval(-lv[i][0]) * oh);
|
||||
|
||||
if (std::abs(lv[i][0]) > 1.0 || std::abs(lv[i][1]) > 1.0) painter->setBrush(QColor(255, 255, 63));
|
||||
else painter->setBrush(QColor(63, 255, 63));
|
||||
painter->drawRect(bc);
|
||||
|
||||
// center tick
|
||||
QRectF ln(QPoint(), QSizeF(b.width(), 1));
|
||||
ln.moveCenter(b.center());
|
||||
painter->setBrush(QColor(0, 0, 0));
|
||||
painter->setBrush(QColor(0, 0, 0, 127));
|
||||
painter->drawRect(ln.adjusted(0, -1, 0, 1));
|
||||
painter->setBrush(QColor(255, 255, 255, 191));
|
||||
painter->drawRect(ln);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <QContiguousCache>
|
||||
|
||||
#include "data/node.h"
|
||||
#include "data/audioframe.h"
|
||||
|
||||
namespace Xybrid::Gadgets {
|
||||
class QuickLevel : public Data::Node {
|
||||
QContiguousCache<Data::AudioFrame> buf;
|
||||
|
||||
std::array<std::array<double, 2>, 2> lv;
|
||||
public:
|
||||
// time across which the displayed levels are calculated
|
||||
static const constexpr double SPAN_TIME = 1.0/30;
|
||||
static const constexpr double DISPLAY_EXPONENT = 1;
|
||||
|
||||
QuickLevel();
|
||||
~QuickLevel() = default;
|
||||
~QuickLevel() override = default;
|
||||
|
||||
void init() override;
|
||||
void reset() override;
|
||||
void release() override;
|
||||
void process() override;
|
||||
|
||||
void onPortDisconnected(Data::Port::Type, Data::Port::DataType, uint8_t, std::weak_ptr<Data::Port>) override;
|
||||
|
||||
void onGadgetCreated() override;
|
||||
void drawCustomChrome(QPainter*, const QStyleOptionGraphicsItem*) override;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue