Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
SLUG = com-soundchasing-stochasm
VERSION = 0.6.0

# FLAGS will be passed to both the C and C++ compiler
FLAGS +=
CFLAGS +=
Expand Down
25 changes: 25 additions & 0 deletions plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"slug": "com-soundchasing-stochasm",
"name": "Stochasm",
"version": "1.0.0",
"license": "MIT",
"brand": "Stochasm",
"author": "teletypist",
"authorEmail": "",
"authorUrl": "https://soundchasing.com",
"pluginUrl": "https://github.com/teletypist/stochasm",
"manualUrl": "https://github.com/teletypist/stochasm",
"sourceUrl": "https://github.com/teletypist/stochasm",
"donateUrl": "",
"changelogUrl": "",
"modules": [
{
"slug": "Resonator",
"name": "Resonator",
"description": "Bitstream Resonator",
"tags": [
"Oscillator"
]
}
]
}
86 changes: 49 additions & 37 deletions src/Resonator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,48 +67,59 @@ struct Resonator : Module {
float lPre = 0.f;


Resonator() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
void step() override;
Resonator() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam(Resonator::UPPER_CHAMBER, 0.0, 10.0, 5.0, "");
configParam(Resonator::UPPER_FILTER1, 0.0, 10.0, 5.0, "");
configParam(Resonator::UPPER_FILTER2, 0.0, 10.0, 5.0, "");
configParam(Resonator::UPPER_MANUAL, 0.0, 1.0, 0.0, "");
configParam(Resonator::LOWER_CHAMBER, 0.0, 10.0, 5.0, "");
configParam(Resonator::LOWER_FILTER1, 0.0, 10.0, 5.0, "");
configParam(Resonator::LOWER_FILTER2, 0.0, 10.0, 5.0, "");
configParam(Resonator::LOWER_MANUAL, 0.0, 1.0, 0.0, "");
}

void process(const ProcessArgs& args) override;

// For more advanced Module features, read Rack's engine.hpp header file
// - toJson, fromJson: serialization of internal data
// - dataToJson, dataFromJson: serialization of internal data
// - onSampleRateChange: event triggered by a change of sample rate
// - onReset, onRandomize, onCreate, onDelete: implements special behavior when user clicks these from the context menu
};


void Resonator::step() {
void Resonator::process(const ProcessArgs& args) {
int i;

uDelaySize = pow(2, clamp(params[UPPER_CHAMBER].value + inputs[UPPER_VOCT].value, 0.f, 10.f) +6);
lDelaySize = pow(2, clamp(params[LOWER_CHAMBER].value + inputs[LOWER_VOCT].value, 0.f, 10.f) +6);
uDelaySize = pow(2, clamp(params[UPPER_CHAMBER].getValue() + inputs[UPPER_VOCT].getVoltage(), 0.f, 10.f) +6);
lDelaySize = pow(2, clamp(params[LOWER_CHAMBER].getValue() + inputs[LOWER_VOCT].getVoltage(), 0.f, 10.f) +6);

uDelayIndex %= uDelaySize;
lDelayIndex %= lDelaySize;

int size;
size = (int)params[UPPER_FILTER1].value;
size = (int)params[UPPER_FILTER1].getValue();
if (size - uFilter1Size > 0)
uFilter1Size << (size - uFilter1Size);
else if (uFilter1Size - size > 0)
uFilter1Size >> (uFilter1Size - size);
uFilter1Size = size;

size = (int)params[UPPER_FILTER2].value;
size = (int)params[UPPER_FILTER2].getValue();
if (size - uFilter2Size > 0)
uFilter2Size << (size - uFilter2Size);
else if (uFilter2Size - size > 0)
uFilter2Size >> (uFilter2Size - size);
uFilter2Size = size;

size = (int)params[LOWER_FILTER1].value;
size = (int)params[LOWER_FILTER1].getValue();
if (size - lFilter1Size > 0)
lFilter1Size << (size - lFilter1Size);
else if (lFilter1Size - size > 0)
lFilter1Size >> (lFilter1Size - size);
lFilter1Size = size;

size = (int)params[LOWER_FILTER2].value;
size = (int)params[LOWER_FILTER2].getValue();
if (size - lFilter2Size > 0)
lFilter2Size << (size - lFilter2Size);
else if (lFilter2Size - size > 0)
Expand All @@ -135,7 +146,7 @@ void Resonator::step() {
lFilter2LFSR >>= 1;
lFilter2LFSR ^= (-lsb) & LFSR_TAPS_MAX_32;

if (params[UPPER_MANUAL].value > 0.f || inputs[UPPER_GATE].value > 1.7f)
if (params[UPPER_MANUAL].getValue() > 0.f || inputs[UPPER_GATE].getVoltage() > 1.7f)
{
//Determine out values
uDelayOut = (bool) uDelay[uDelayIndex];
Expand All @@ -158,7 +169,7 @@ void Resonator::step() {
uCurrent = uCurrent + IIR_FILTER_DECAY * (-uCurrent);
}

if (params[LOWER_MANUAL].value > 0.f || inputs[LOWER_GATE].value > 1.7f)
if (params[LOWER_MANUAL].getValue() > 0.f || inputs[LOWER_GATE].getVoltage() > 1.7f)
{
//Determine out values
lDelayOut = (bool) lDelay[lDelayIndex];
Expand Down Expand Up @@ -186,8 +197,8 @@ void Resonator::step() {

}

outputs[UPPER_OUT].value = uCurrent;
outputs[LOWER_OUT].value = lCurrent;
outputs[UPPER_OUT].setVoltage(uCurrent);
outputs[LOWER_OUT].setVoltage(lCurrent);
}


Expand All @@ -196,7 +207,8 @@ struct ResonatorWidget : ModuleWidget {
};


ResonatorWidget::ResonatorWidget(Resonator *module) : ModuleWidget(module) {
ResonatorWidget::ResonatorWidget(Resonator *module) {
setModule(module);

//Resonator *module = new Resonator();
//setModule(module);
Expand All @@ -206,38 +218,38 @@ ResonatorWidget::ResonatorWidget(Resonator *module) : ModuleWidget(module) {
{
SVGPanel *panel = new SVGPanel();
panel->box.size = box.size;
panel->setBackground(SVG::load(assetPlugin(plugin, "res/Resonator.svg")));
panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Resonator.svg")));
addChild(panel);
}

addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));

//Upper
addParam(ParamWidget::create<StochasmMintLargeKnob>(Vec(52, 30), module, Resonator::UPPER_CHAMBER, 0.0, 10.0, 5.0));
addParam(ParamWidget::create<StochasmMintKnob>(Vec(48, 104), module, Resonator::UPPER_FILTER1, 0.0, 10.0, 5.0));
addParam(ParamWidget::create<StochasmMintKnob>(Vec(85, 104), module, Resonator::UPPER_FILTER2, 0.0, 10.0, 5.0));
addParam(ParamWidget::create<MintMomentarySwitch>(Vec(11, 81), module, Resonator::UPPER_MANUAL, 0.0, 1.0, 0.0));
addParam(createParam<StochasmMintLargeKnob>(Vec(52, 30), module, Resonator::UPPER_CHAMBER));
addParam(createParam<StochasmMintKnob>(Vec(48, 104), module, Resonator::UPPER_FILTER1));
addParam(createParam<StochasmMintKnob>(Vec(85, 104), module, Resonator::UPPER_FILTER2));
addParam(createParam<MintMomentarySwitch>(Vec(11, 81), module, Resonator::UPPER_MANUAL));

addInput(Port::create<PJ301MPort>(Vec(12, 43), Port::INPUT, module, Resonator::UPPER_VOCT));
addInput(Port::create<PJ301MPort>(Vec(12, 120), Port::INPUT, module, Resonator::UPPER_GATE));
addInput(createInput<PJ301MPort>(Vec(12, 43), module, Resonator::UPPER_VOCT));
addInput(createInput<PJ301MPort>(Vec(12, 120), module, Resonator::UPPER_GATE));

addOutput(Port::create<PJ301MPort>(Vec(12, 159), Port::OUTPUT, module, Resonator::UPPER_OUT));
addOutput(Port::create<PJ301MPort>(Vec(86, 159), Port::OUTPUT, module, Resonator::UPPER_BITS));
addOutput(createOutput<PJ301MPort>(Vec(12, 159), module, Resonator::UPPER_OUT));
addOutput(createOutput<PJ301MPort>(Vec(86, 159), module, Resonator::UPPER_BITS));

//Lower
addParam(ParamWidget::create<StochasmMintLargeKnob>(Vec(52, 218), module, Resonator::LOWER_CHAMBER, 0.0, 10.0, 5.0));
addParam(ParamWidget::create<StochasmMintKnob>(Vec(48, 292), module, Resonator::LOWER_FILTER1, 0.0, 10.0, 5.0));
addParam(ParamWidget::create<StochasmMintKnob>(Vec(85, 292), module, Resonator::LOWER_FILTER2, 0.0, 10.0, 5.0));
addParam(ParamWidget::create<MintMomentarySwitch>(Vec(11, 269), module, Resonator::LOWER_MANUAL, 0.0, 1.0, 0.0));
addParam(createParam<StochasmMintLargeKnob>(Vec(52, 218), module, Resonator::LOWER_CHAMBER));
addParam(createParam<StochasmMintKnob>(Vec(48, 292), module, Resonator::LOWER_FILTER1));
addParam(createParam<StochasmMintKnob>(Vec(85, 292), module, Resonator::LOWER_FILTER2));
addParam(createParam<MintMomentarySwitch>(Vec(11, 269), module, Resonator::LOWER_MANUAL));

addInput(Port::create<PJ301MPort>(Vec(12, 230), Port::INPUT, module, Resonator::LOWER_VOCT));
addInput(Port::create<PJ301MPort>(Vec(12, 308), Port::INPUT, module, Resonator::LOWER_GATE));
addInput(createInput<PJ301MPort>(Vec(12, 230), module, Resonator::LOWER_VOCT));
addInput(createInput<PJ301MPort>(Vec(12, 308), module, Resonator::LOWER_GATE));

addOutput(Port::create<PJ301MPort>(Vec(12, 346), Port::OUTPUT, module, Resonator::LOWER_OUT));
addOutput(Port::create<PJ301MPort>(Vec(86, 346), Port::OUTPUT, module, Resonator::LOWER_BITS));
addOutput(createOutput<PJ301MPort>(Vec(12, 346), module, Resonator::LOWER_OUT));
addOutput(createOutput<PJ301MPort>(Vec(86, 346), module, Resonator::LOWER_BITS));

//addInput(createInput<PJ301MPort>(Vec(33, 186), module, Resonator::PITCH_INPUT));

Expand Down Expand Up @@ -268,4 +280,4 @@ Out, PJ301M -> (12, 346)
Bits, PJ301M -> (86, 346)
*/

Model *modelResonator = Model::create<Resonator, ResonatorWidget>("Stochasm", "Resonator", "Bitstream Resonator", OSCILLATOR_TAG);
Model *modelResonator = createModel<Resonator, ResonatorWidget>("Resonator");
16 changes: 6 additions & 10 deletions src/Stochasm.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
#include "Stochasm.hpp"


// The plugin-wide instance of the Plugin class
Plugin *plugin;
// The pluginInstance-wide instance of the Plugin class
Plugin *pluginInstance;

void init(rack::Plugin *p) {
plugin = p;
// The "slug" is the unique identifier for your plugin and must never change after release, so choose wisely.
pluginInstance = p;
// The "slug" is the unique identifier for your pluginInstance and must never change after release, so choose wisely.
// It must only contain letters, numbers, and characters "-" and "_". No spaces.
// To guarantee uniqueness, it is a good idea to prefix the slug by your name, alias, or company name if available, e.g. "MyCompany-MyPlugin".
// The ZIP package must only contain one folder, with the name equal to the plugin's slug.
p->slug = TOSTRING(SLUG);
p->version = TOSTRING(VERSION);
p->website = "https://soundchasing.com/uncertainty";
p->manual = "https://soundchasing.com/stochasm";
// The ZIP package must only contain one folder, with the name equal to the pluginInstance's slug.

// For each module, specify the ModuleWidget subclass, manufacturer slug (for saving in patches), manufacturer human-readable name, module slug, and module name
p->addModel(modelResonator);

// Any other plugin initialization may go here.
// Any other pluginInstance initialization may go here.
// As an alternative, consider lazy-loading assets and lookup tables when your module is created to reduce startup times of Rack.
}
28 changes: 16 additions & 12 deletions src/Stochasm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using namespace rack;


extern Plugin *plugin;
extern Plugin *pluginInstance;

extern Model *modelResonator;

////////////////////
// module widgets
Expand All @@ -21,40 +23,42 @@ struct StochasmKnob : SVGKnob {

struct StochasmMintKnob : StochasmKnob {
StochasmMintKnob() {
setSVG(SVG::load(assetPlugin(plugin, "res/MintKnob.svg")));
setSVG(APP->window->loadSvg(asset::plugin(pluginInstance, "res/MintKnob.svg")));
}
};

struct StochasmTangerineKnob : StochasmKnob {
StochasmTangerineKnob() {
setSVG(SVG::load(assetPlugin(plugin, "res/TangerineKnob.svg")));
setSVG(APP->window->loadSvg(asset::plugin(pluginInstance, "res/TangerineKnob.svg")));
}
};


struct StochasmMintLargeKnob : StochasmKnob {
StochasmMintLargeKnob() {
setSVG(SVG::load(assetPlugin(plugin, "res/MintKnobLarge.svg")));
setSVG(APP->window->loadSvg(asset::plugin(pluginInstance, "res/MintKnobLarge.svg")));
}
};

struct StochasmTangerineLargeKnob : StochasmKnob {
StochasmTangerineLargeKnob() {
setSVG(SVG::load(assetPlugin(plugin, "res/TangerineKnobLarge.svg")));
setSVG(APP->window->loadSvg(asset::plugin(pluginInstance, "res/TangerineKnobLarge.svg")));
}
};

struct MintMomentarySwitch : SVGSwitch, MomentarySwitch {
struct MintMomentarySwitch : SVGSwitch {
MintMomentarySwitch() {
addFrame(SVG::load(assetPlugin(plugin, "res/MintMomentary0.svg")));
addFrame(SVG::load(assetPlugin(plugin, "res/MintMomentary1.svg")));
momentary = true;
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/MintMomentary0.svg")));
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/MintMomentary1.svg")));
}
};

struct TangerineMomentarySwitch : SVGSwitch, MomentarySwitch {
struct TangerineMomentarySwitch : SVGSwitch {
TangerineMomentarySwitch() {
addFrame(SVG::load(assetPlugin(plugin, "res/TangerineMomentary0.svg")));
addFrame(SVG::load(assetPlugin(plugin, "res/TangerineMomentary1.svg")));
momentary = true;
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/TangerineMomentary0.svg")));
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/TangerineMomentary1.svg")));
}
};

Expand All @@ -63,4 +67,4 @@ struct TangerineMomentarySwitch : SVGSwitch, MomentarySwitch {
struct ResonatorWidget : ModuleWidget {
ResonatorWidget();
};
*/
*/