diff --git a/src/Peaks.cpp b/src/Peaks.cpp index 011166c..9ae3629 100644 --- a/src/Peaks.cpp +++ b/src/Peaks.cpp @@ -1,13 +1,12 @@ -#include -#include +#include "plugin.hpp" -#include "dsp/digital.hpp" -#include "dsp/samplerate.hpp" -#include "dsp/ringbuffer.hpp" +//#include "dsp/digital.hpp" +//#include "dsp/samplerate.hpp" +//#include "dsp/ringbuffer.hpp" #include "peaks/processors.h" -#include "AudibleInstruments.hpp" +//#include "AudibleInstruments.hpp" enum SwitchIndex { @@ -109,12 +108,12 @@ struct Peaks : Module { int16_t output[kBlockSize]; int16_t brightness[kNumChannels] = {0, 0}; - SchmittTrigger switches_[2]; + dsp::SchmittTrigger switches_[2]; peaks::GateFlags gate_flags[2] = {0, 0}; - SampleRateConverter<2> outputSrc; - DoubleRingBuffer, 256> outputBuffer; + dsp::SampleRateConverter<2> outputSrc; + dsp::DoubleRingBuffer, 256> outputBuffer; bool initNumberStation = false; @@ -134,7 +133,19 @@ struct Peaks : Module { size_t render_block_ = kNumBlocks / 2; - Peaks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { + Peaks() { + + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + + configParam(KNOB_1_PARAM, 0.0f, 65535.0f, 32678.0f, "Knob 1"); + configParam(KNOB_2_PARAM, 0.0f, 65535.0f, 32678.0f, "Knob 1"); + configParam(KNOB_3_PARAM, 0.0f, 65535.0f, 32678.0f, "Knob 1"); + configParam(KNOB_4_PARAM, 0.0f, 65535.0f, 32678.0f, "Knob 1"); + configButton(BUTTON_1_PARAM, "Mode"); + configButton(BUTTON_2_PARAM, "Mode"); + configButton(TRIG_1_PARAM, "Trigger 1"); + configButton(TRIG_2_PARAM, "Trigger 2"); + settings_.edit_mode = EDIT_MODE_TWIN; settings_.function[0] = FUNCTION_ENVELOPE; settings_.function[1] = FUNCTION_ENVELOPE; @@ -184,7 +195,7 @@ struct Peaks : Module { setFunction(1, function_[1]); } - json_t* toJson() override { + json_t* dataToJson() override { saveState(); @@ -206,7 +217,7 @@ struct Peaks : Module { return rootJ; } - void fromJson(json_t* rootJ) override { + void dataFromJson(json_t* rootJ) override { json_t* editModeJ = json_object_get(rootJ, "edit_mode"); if (editModeJ) { settings_.edit_mode = static_cast(json_integer_value(editModeJ)); @@ -240,7 +251,7 @@ struct Peaks : Module { init(); } - void step() override { + void process(const ProcessArgs& args) override { poll(); pollPots(); @@ -259,21 +270,21 @@ struct Peaks : Module { } uint32_t external_gate_inputs = 0; - external_gate_inputs |= (inputs[GATE_1_INPUT].value ? 1 : 0); - external_gate_inputs |= (inputs[GATE_2_INPUT].value ? 2 : 0); + external_gate_inputs |= (inputs[GATE_1_INPUT].getVoltage() ? 1 : 0); + external_gate_inputs |= (inputs[GATE_2_INPUT].getVoltage() ? 2 : 0); uint32_t buttons = 0; - buttons |= (params[TRIG_1_PARAM].value ? 1 : 0); - buttons |= (params[TRIG_2_PARAM].value ? 2 : 0); + buttons |= (params[TRIG_1_PARAM].getValue() ? 1 : 0); + buttons |= (params[TRIG_2_PARAM].getValue() ? 2 : 0); uint32_t gate_inputs = external_gate_inputs | buttons; // Prepare sample rate conversion. // Peaks is sampling at 48kHZ. - outputSrc.setRates(48000, engineGetSampleRate()); + outputSrc.setRates(48000, args.sampleRate); int inLen = kBlockSize; int outLen = outputBuffer.capacity(); - Frame<2> f[kBlockSize]; + dsp::Frame<2> f[kBlockSize]; // Process an entire block of data from the IOBuffer. for (size_t k = 0; k < kBlockSize; ++k) { @@ -301,12 +312,12 @@ struct Peaks : Module { // Update outputs. if (!outputBuffer.empty()) { - Frame<2> f = outputBuffer.shift(); + dsp::Frame<2> f = outputBuffer.shift(); // Peaks manual says output spec is 0..8V for envelopes and 10Vpp for audio/CV. // TODO Check the output values against an actual device. - outputs[OUT_1_OUTPUT].value = rescale(static_cast(f.samples[0]), 0.0f, 65535.f, -8.0f, 8.0f); - outputs[OUT_2_OUTPUT].value = rescale(static_cast(f.samples[1]), 0.0f, 65535.f, -8.0f, 8.0f); + outputs[OUT_1_OUTPUT].setVoltage(rescale(static_cast(f.samples[0]), 0.0f, 65535.f, -8.0f, 8.0f)); + outputs[OUT_2_OUTPUT].setVoltage(rescale(static_cast(f.samples[1]), 0.0f, 65535.f, -8.0f, 8.0f)); } } @@ -467,7 +478,7 @@ void Peaks::lockPots() { void Peaks::pollPots() { for (uint8_t i = 0; i < kNumAdcChannels; ++i) { - adc_lp_[i] = (int32_t(params[KNOB_1_PARAM + i].value) + adc_lp_[i] * 7) >> 3; + adc_lp_[i] = (int32_t(params[KNOB_1_PARAM + i].getValue()) + adc_lp_[i] * 7) >> 3; int32_t value = adc_lp_[i]; int32_t current_value = adc_value_[i]; if (value >= current_value + adc_threshold_[i] || @@ -530,7 +541,7 @@ long long Peaks::getSystemTimeMs() { void Peaks::poll() { for (uint8_t i = 0; i < 2; ++i) { - if (switches_[i].process(params[BUTTON_1_PARAM + i].value)) { + if (switches_[i].process(params[BUTTON_1_PARAM + i].getValue())) { press_time_[i] = getSystemTimeMs(); } @@ -618,80 +629,67 @@ void Peaks::refreshLeds() { b[1] = processors[1].number_station().gate() ? 255 : 0; } - lights[TRIG_1_LIGHT].value = rescale(static_cast(b[0]), 0.0f, 255.0f, 0.0f, 1.0f); - lights[TRIG_2_LIGHT].value = rescale(static_cast(b[1]), 0.0f, 255.0f, 0.0f, 1.0f); + const float deltaTime = APP->engine->getSampleTime(); + lights[TRIG_1_LIGHT].setSmoothBrightness(rescale(static_cast(b[0]), 0.0f, 255.0f, 0.0f, 1.0f), deltaTime); + lights[TRIG_2_LIGHT].setSmoothBrightness(rescale(static_cast(b[1]), 0.0f, 255.0f, 0.0f, 1.0f), deltaTime); } - struct PeaksWidget : ModuleWidget { - PeaksWidget(Peaks* module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/Peaks.svg"))); - - addChild(Widget::create(Vec(15, 0))); - addChild(Widget::create(Vec(15, 365))); - - addParam(ParamWidget::create(Vec(8.5, 52), module, Peaks::BUTTON_1_PARAM, 0.0f, 1.0f, 0.0f)); - addChild(ModuleLightWidget::create>(Vec(11.88, 74), module, Peaks::TWIN_MODE_LIGHT)); - addParam(ParamWidget::create(Vec(8.5, 89), module, Peaks::BUTTON_2_PARAM, 0.0f, 1.0f, 0.0f)); - addChild(ModuleLightWidget::create>(Vec(11.88, 111), module, Peaks::FUNC_1_LIGHT)); - addChild(ModuleLightWidget::create>(Vec(11.88, 126.75), module, Peaks::FUNC_2_LIGHT)); - addChild(ModuleLightWidget::create>(Vec(11.88, 142.5), module, Peaks::FUNC_3_LIGHT)); - addChild(ModuleLightWidget::create>(Vec(11.88, 158), module, Peaks::FUNC_4_LIGHT)); - - addParam(ParamWidget::create(Vec(61, 51), module, Peaks::KNOB_1_PARAM, 0.0f, 65535.0f, 16384.0f)); - addParam(ParamWidget::create(Vec(61, 115), module, Peaks::KNOB_2_PARAM, 0.0f, 65535.0f, 16384.0f)); - addParam(ParamWidget::create(Vec(61, 179), module, Peaks::KNOB_3_PARAM, 0.0f, 65535.0f, 32678.0f)); - addParam(ParamWidget::create(Vec(61, 244), module, Peaks::KNOB_4_PARAM, 0.0f, 65535.0f, 32678.0f)); - - addParam(ParamWidget::create(Vec(11, 188), module, Peaks::TRIG_1_PARAM, 0.0f, 1.0f, 0.0f)); - addParam(ParamWidget::create(Vec(11, 273), module, Peaks::TRIG_2_PARAM, 0.0f, 1.0f, 0.0f)); - addChild(ModuleLightWidget::create>(Vec(11, 188).plus(mm2px(Vec(0.75, 0.75))), module, Peaks::TRIG_1_LIGHT)); - addChild(ModuleLightWidget::create>(Vec(11, 273).plus(mm2px(Vec(0.75, 0.75))), module, Peaks::TRIG_2_LIGHT)); - - addInput(Port::create(Vec(10, 230), Port::INPUT, module, Peaks::GATE_1_INPUT)); - addInput(Port::create(Vec(10, 315), Port::INPUT, module, Peaks::GATE_2_INPUT)); - - addOutput(Port::create(Vec(53, 315), Port::OUTPUT, module, Peaks::OUT_1_OUTPUT)); - addOutput(Port::create(Vec(86, 315), Port::OUTPUT, module, Peaks::OUT_2_OUTPUT)); + PeaksWidget(Peaks* module) { + setModule(module); + setPanel(Svg::load(asset::plugin(pluginInstance, "res/Peaks.svg"))); + + addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); + addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); + + addParam(createParam((Vec(8.5, 52)), module, Peaks::BUTTON_1_PARAM)); + addParam(createParam((Vec(8.5, 89)), module, Peaks::BUTTON_2_PARAM)); + + addParam(createParamCentered(Vec(21, 200), module, Peaks::TRIG_1_PARAM)); + addParam(createParamCentered(Vec(21, 285), module, Peaks::TRIG_2_PARAM)); + + addChild(createLightCentered>(Vec(21, 200), module, Peaks::TRIG_1_LIGHT)); + addChild(createLightCentered>(Vec(21, 285), module, Peaks::TRIG_2_LIGHT)); + addChild(createLight>(Vec(11.88, 74), module, Peaks::TWIN_MODE_LIGHT)); + addChild(createLight>(Vec(11.88, 111), module, Peaks::FUNC_1_LIGHT)); + addChild(createLight>(Vec(11.88, 126.75), module, Peaks::FUNC_2_LIGHT)); + addChild(createLight>(Vec(11.88, 142.5), module, Peaks::FUNC_3_LIGHT)); + addChild(createLight>(Vec(11.88, 158), module, Peaks::FUNC_4_LIGHT)); + + addParam(createParam(Vec(61, 51), module, Peaks::KNOB_1_PARAM)); + addParam(createParam(Vec(61, 115), module, Peaks::KNOB_2_PARAM)); + addParam(createParam(Vec(61, 179), module, Peaks::KNOB_3_PARAM)); + addParam(createParam(Vec(61, 244), module, Peaks::KNOB_4_PARAM)); + + + addInput(createInput((Vec(10, 230)), module, Peaks::GATE_1_INPUT)); + addInput(createInput((Vec(10, 315)), module, Peaks::GATE_2_INPUT)); + + addOutput(createOutput((Vec(53., 315.)), module, Peaks::OUT_1_OUTPUT)); + addOutput(createOutput((Vec(86., 315.)), module, Peaks::OUT_2_OUTPUT)); } - Menu* createContextMenu() override { - Menu* menu = ModuleWidget::createContextMenu(); - Peaks* peaks = dynamic_cast(this->module); + void appendContextMenu(Menu* menu) override { - struct SnapModeItem : MenuItem { - Peaks* peaks; - void onAction(EventAction& e) override { - peaks->snap_mode_ = !peaks->snap_mode_; - } - void step() override { - rightText = (peaks->snap_mode_) ? "✔" : ""; - MenuItem::step(); - } - }; + menu->addChild(new MenuSeparator); + Peaks *peaks = dynamic_cast(this->module); - struct NumberStationItem : MenuItem { - Peaks* peaks; - void onAction(EventAction& e) override { - peaks->initNumberStation = true; - } - void step() override { - rightText = (peaks->processors[0].function() == peaks::PROCESSOR_FUNCTION_NUMBER_STATION) ? "✔" : ""; - MenuItem::step(); - } - }; menu->addChild(construct()); - menu->addChild(construct(&SnapModeItem::text, "Snap Mode", &SnapModeItem::peaks, peaks)); + + menu->addChild(createBoolPtrMenuItem("Snap mode", "", &peaks->snap_mode_)); menu->addChild(construct()); menu->addChild(construct(&MenuLabel::text, "Secret Modes")); - menu->addChild(construct(&NumberStationItem::text, "Number Station", &NumberStationItem::peaks, peaks)); - return menu; + menu->addChild(createBoolMenuItem("Number station", "", + [=]() {return peaks->processors[0].function() == peaks::PROCESSOR_FUNCTION_NUMBER_STATION;}, + [=](bool val) {peaks->initNumberStation = true;} + )); } + }; -Model* modelPeaks = Model::create("Audible Instruments", "Peaks", "Percussive Synthesizer", UTILITY_TAG, LFO_TAG, DRUM_TAG); +Model* modelPeaks = createModel("Peaks");