96 lines
2.6 KiB
C++
96 lines
2.6 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>
|
|
|
|
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);
|
|
}
|