xybrid/xybrid/nodes/gadget/transpose.cpp

97 lines
2.7 KiB
C++

#include "transpose.h"
using Xybrid::Gadgets::Transpose;
using namespace Xybrid::Data;
#include "util/strings.h"
#include "data/porttypes.h"
#include "config/pluginregistry.h"
using namespace Xybrid::Config;
#include "audio/audioengine.h"
using namespace Xybrid::Audio;
#include "ui/patchboard/nodeobject.h"
#include "ui/gadgets/layoutgadget.h"
#include "ui/gadgets/knobgadget.h"
using namespace Xybrid::UI;
#include <cmath>
#include <QCborMap>
// clazy:excludeall=non-pod-global-static
RegisterPlugin(Transpose, {
i->id = "gadget:transpose";
i->displayName = "Transpose";
i->category = "Gadget";
})
Transpose::Transpose() {
}
void Transpose::init() {
addPort(Port::Input, Port::Command, 0);
addPort(Port::Output, Port::Command, 0);
}
void Transpose::process() {
int off = octave.load()*12 + amount.load();
auto in = std::static_pointer_cast<CommandPort>(port(Port::Input, Port::Command, 0));
auto out = std::static_pointer_cast<CommandPort>(port(Port::Output, Port::Command, 0));
if (off == 0) { // a
if (out->passthroughTo.expired()) out->passthroughTo = in;
return;
}
if (!out->passthroughTo.expired()) out->passthroughTo.reset();
in->pull();
out->pull();
out->data = reinterpret_cast<uint8_t*>(audioEngine->tickAlloc(in->size));
out->size = in->size;
memcpy(out->data, in->data, in->size); // precopy
size_t mi = 0;
while (out->size >= mi+5) {
int16_t& n = reinterpret_cast<int16_t&>(out->data[mi+2]);
if (n > -1) {
int nn = n;
nn += off;
if (nn < 0 || nn > 32767) nn = -1;
n = static_cast<int16_t>(nn);
}
mi += 5 + out->data[mi+4]*2;
}
}
void Transpose::saveData(QCborMap& m) const {
m[qs("amount")] = QCborValue(amount);
m[qs("octave")] = QCborValue(octave);
}
void Transpose::loadData(const QCborMap& m) {
auto oct = m.value("octave");
if (oct.isUndefined()) { // convert from single value
int a = static_cast<int>(m.value("amount").toInteger(0));
int s = a < 0 ? -1 : 1;
a = std::abs(a);
octave = (a-(a%12))/12*s;
amount = a%12 * s;
return;
}
octave = static_cast<int>(oct.toInteger(0));
amount = static_cast<int>(m.value("amount").toInteger(0));
}
void Transpose::onGadgetCreated() {
if (!obj) return;
obj->showPluginName = false;
auto l = (new LayoutGadget(obj))->setMetrics(8, 10);
(new KnobGadget(l))->bind(amount)->setLabel("Transpose")->setTextFunc(KnobGadget::textOffset)->setRange(-12, 12, 1, KnobGadget::MedStep);
(new KnobGadget(l))->bind(octave)->setLabel("Octave")->setTextFunc(KnobGadget::textOffset)->setRange(-5, 5, 1, KnobGadget::BigStep);
}