/* * DISTRHO Cardinal Plugin * Copyright (C) 2021 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of * the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * For a full copy of the GNU General Public License see the LICENSE file. */ /** * This file is an edited version of VCVRack's MIDI_CV.cpp * Copyright (C) 2016-2021 VCV. * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. */ #include "../Rack/src/core/MIDI_CV.cpp" #include namespace rack { namespace core { static inline void nsvg__deletePaths(NSVGpath* path) { } struct MIDI_CVWidget_Cardinal : ModuleWidget { MIDI_CV* const module; MIDI_CVWidget_Cardinal(MIDI_CV* const m) : module(m) { setModule(module); std::shared_ptr svg(Svg::load(asset::system("res/Core/MIDI_CV.svg"))); // this section removes the CLK and CLK/N part of the svg for (NSVGshape *shape = svg->handle->shapes, *old = nullptr; shape != nullptr;) { if (std::strcmp(shape->id, "rect22") != 0 && std::strcmp(shape->id, "rect20") != 0 && std::strcmp(shape->id, "path97") != 0 && std::strcmp(shape->id, "path99") != 0 && std::strcmp(shape->id, "path101") != 0 && std::strcmp(shape->id, "path85") != 0 && std::strcmp(shape->id, "path87") != 0 && std::strcmp(shape->id, "path89") != 0 && std::strcmp(shape->id, "path91") != 0 && std::strcmp(shape->id, "path93") != 0) { old = shape; shape = shape->next; continue; } NSVGshape* const next = shape->next; for (NSVGpath* path = shape->paths; path != nullptr;) { NSVGpath* next = path->next; std::free(path->pts); std::free(path); path = next; } std::free(shape); shape = next; if (old != nullptr) old->next = next; else svg->handle->shapes = next; } setPanel(svg); addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addOutput(createOutputCentered(mm2px(Vec(7.905, 64.347)), module, MIDI_CV::PITCH_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(20.248, 64.347)), module, MIDI_CV::GATE_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(32.591, 64.347)), module, MIDI_CV::VELOCITY_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(7.905, 80.603)), module, MIDI_CV::AFTERTOUCH_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(20.248, 80.603)), module, MIDI_CV::PW_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(32.591, 80.603)), module, MIDI_CV::MOD_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(32.591, 96.859)), module, MIDI_CV::RETRIGGER_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(7.905, 113.115)), module, MIDI_CV::START_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(20.248, 113.115)), module, MIDI_CV::STOP_OUTPUT)); addOutput(createOutputCentered(mm2px(Vec(32.591, 112.975)), module, MIDI_CV::CONTINUE_OUTPUT)); MidiDisplay* display = createWidget(mm2px(Vec(0.0, 13.048))); display->box.size = mm2px(Vec(40.64, 29.012)); display->setMidiPort(m != nullptr ? &m->midiInput : nullptr); addChild(display); } void appendContextMenu(Menu* const menu) override { menu->addChild(new MenuSeparator); menu->addChild(createBoolPtrMenuItem("Smooth pitch/mod wheel", "", &module->smooth)); struct ChannelItem : MenuItem { MIDI_CV* module; Menu* createChildMenu() override { Menu* menu = new Menu; for (int c = 1; c <= 16; c++) { menu->addChild(createCheckMenuItem((c == 1) ? "Monophonic" : string::f("%d", c), "", [=]() {return module->channels == c;}, [=]() {module->setChannels(c);} )); } return menu; } }; ChannelItem* channelItem = new ChannelItem; channelItem->text = "Polyphony channels"; channelItem->rightText = string::f("%d", module->channels) + " " + RIGHT_ARROW; channelItem->module = module; menu->addChild(channelItem); menu->addChild(createIndexPtrSubmenuItem("Polyphony mode", { "Rotate", "Reuse", "Reset", "MPE", }, &module->polyMode)); menu->addChild(createMenuItem("Panic", "", [=]() {module->panic();} )); } }; Model* modelMIDI_CV_Cardinal = createModel("MIDIToCVInterface"); } }