xybrid/xybrid/gadgets/testsynth.cpp

94 lines
2.6 KiB
C++

#include "testsynth.h"
using Xybrid::Gadgets::TestSynth;
using namespace Xybrid::Data;
#include "data/porttypes.h"
#include "config/pluginregistry.h"
using namespace Xybrid::Config;
#include "audio/audioengine.h"
using namespace Xybrid::Audio;
#include <cmath>
#include <QDebug>
namespace {
bool _ = PluginRegistry::enqueueRegistration([] {
auto i = std::make_shared<PluginInfo>();
i->id = "plug:testsynth";
i->displayName = "The Testron";
i->category = "Instrument";
//i->hidden = true;
i->createInstance = []{ return std::make_shared<TestSynth>(); };
PluginRegistry::registerPlugin(i);
//inf = i;
});
}
TestSynth::TestSynth() {
//
}
void TestSynth::init() {
addPort(Port::Input, Port::Command, 0);
addPort(Port::Output, Port::Audio, 0);
}
void TestSynth::reset() {
osc = 0.0;
osc2 = 0.0;
cvol = 0.0;
tvol = 0.0;
noteId = 0;
}
void TestSynth::process() {
auto cp = std::static_pointer_cast<CommandPort>(port(Port::Input, Port::Command, 0));
cp->pull();
auto p = std::static_pointer_cast<AudioPort>(port(Port::Output, Port::Audio, 0));
p->pull();
size_t mi = 0;
while (cp->dataSize >= mi+5) {
uint16_t id = reinterpret_cast<uint16_t&>(cp->data[mi]);
int16_t n = reinterpret_cast<int16_t&>(cp->data[mi+2]);
if (n > -1) {
noteId = id;
note = n;
tvol = 1.0;
} else if (n < -1 && id == noteId) { // note off
tvol = 0.0;
}
mi += 5 + cp->data[mi+4];
}
const double PI = std::atan(1)*4;
const double SEMI = std::pow(2.0, 1.0/12.0);
size_t ts = audioEngine->curTickSize();
for (size_t s = 0; s < ts; s++) {
if (tvol > cvol) cvol += 64.0 / audioEngine->curSampleRate();
else if (tvol < cvol) cvol -= 16.0 / audioEngine->curSampleRate();
cvol = std::clamp(cvol, 0.0, 1.0);
if (cvol == 0.0) { osc = osc2 = 0.0; }
float oscV = static_cast<float>((std::sin(osc * PI*2) + std::sin(osc2 * PI*2) * std::pow(.75, 4)) * std::pow(cvol*.5, 4));
double enote = note + std::sin(lfo * PI*2) * 0.1;
double freq = 440.0 * std::pow(SEMI, enote - (45+12));
osc += freq / audioEngine->curSampleRate();
osc = std::fmod(osc, 1.0);
osc2 += (freq * .5) / audioEngine->curSampleRate();
osc2 = std::fmod(osc2, 1.0);
lfo += 3.0 / audioEngine->curSampleRate();
lfo = std::fmod(lfo, 1.0);
p->bufL[s] = oscV;
p->bufR[s] = oscV;
}
//audioEngine->curSampleRate()
}