diff --git a/notes b/notes index 123e1dd..239b111 100644 --- a/notes +++ b/notes @@ -37,6 +37,9 @@ TODO { revert-to-saved menu action + - ringmod (easy!) + splice-between behavior when trying to hook up a command input to something with both a command input and output while already connected + distortion effect uh... maybe save/load samples as s16 instead of f32 @@ -54,6 +57,7 @@ TODO { } editing song info should probably be an UndoStack action + editing song *tempo* ABSOLUTELY should figure out what to actually do with directory config @@ -75,17 +79,6 @@ TODO { maybe interpolate between resampler LUT levels bugs to fix { - - font fuckiness with additional windows - - x connecting a CapaXitor up for the first time during playback deadlocks audio engine - x PLAYBACK BREAKS AFTER FIRST PLAY??? { - doesn't happen in Lovely Storm; only where Capaxitor is used?? - resolves itself after project switch - does NOT break preview mode?? - seems to be only with the Maybe sample??? idk - } - x things can apparently be hooked up cyclically, which completely breaks the queue - pattern switching is slow when changing (especially increasing) number of rows; set fixed page size to avoid reallocation? } diff --git a/xybrid/main.cpp b/xybrid/main.cpp index 50dbf07..8826655 100644 --- a/xybrid/main.cpp +++ b/xybrid/main.cpp @@ -23,6 +23,7 @@ int main(int argc, char *argv[]) { qRegisterMetaType(); + // enable antialiasing on accelerated graphicsview QSurfaceFormat fmt; fmt.setSamples(10); diff --git a/xybrid/nodes/effect/ringmod.cpp b/xybrid/nodes/effect/ringmod.cpp new file mode 100644 index 0000000..68755d1 --- /dev/null +++ b/xybrid/nodes/effect/ringmod.cpp @@ -0,0 +1,80 @@ +#include "ringmod.h" + +using Xybrid::Effects::RingMod; +using namespace Xybrid::Data; + +#include "util/strings.h" + +#include "nodelib/basics.h" +using namespace Xybrid::NodeLib; + +#include "data/audioframe.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/togglegadget.h" +#include "ui/gadgets/knobgadget.h" +using namespace Xybrid::UI; + +#include + +#include + +RegisterPlugin(RingMod, { + i->id = "fx:ringmod"; + i->displayName = "Ring Mod"; + i->category = "Effect"; +}) + +RingMod::RingMod() { } + +void RingMod::init() { + addPort(Port::Input, Port::Audio, 0)->name = "carrier"; + addPort(Port::Input, Port::Audio, 1)->name = "modulator"; + + addPort(Port::Output, Port::Audio, 0); +} + +void RingMod::reset() { + // +} + +void RingMod::process() { + auto c = std::static_pointer_cast(port(Port::Input, Port::Audio, 0)); + auto m = std::static_pointer_cast(port(Port::Input, Port::Audio, 1)); + auto out = std::static_pointer_cast(port(Port::Output, Port::Audio, 0)); + c->pull(); + m->pull(); + out->pull(); + + auto ts = audioEngine->curTickSize(); + for (size_t f = 0; f < ts; f++) { + AudioFrame fc = (*c)[f]; + AudioFrame fm = (*m)[f]; + + (*out)[f] = (fc*fm * mix) + (fc * (1.0-mix)); + } +} + +void RingMod::saveData(QCborMap& m) const { + m[qs("mix")] = mix; +} + +void RingMod::loadData(const QCborMap& m) { + mix = m.value("mix").toDouble(mix); +} + +void RingMod::onGadgetCreated() { + if (!obj) return; + auto l = new LayoutGadget(obj); + + //l->setMetrics(12); + KnobGadget::autoPercent(l, mix)->setLabel(qs("Mix"))->setDefault(1.0); +} diff --git a/xybrid/nodes/effect/ringmod.h b/xybrid/nodes/effect/ringmod.h new file mode 100644 index 0000000..7b69854 --- /dev/null +++ b/xybrid/nodes/effect/ringmod.h @@ -0,0 +1,23 @@ +#pragma once + +#include "data/node.h" + +namespace Xybrid::Effects { + class RingMod : public Data::Node { + double mix = 1.0; + + public: + RingMod(); + ~RingMod() override = default; + + void init() override; + void reset() override; + //void release() override; + void process() override; + + void saveData(QCborMap&) const override; + void loadData(const QCborMap&) override; + + void onGadgetCreated() override; + }; +}