diff --git a/plugins/plugins.cpp b/plugins/plugins.cpp index 7788a59..e3c3d20 100644 --- a/plugins/plugins.cpp +++ b/plugins/plugins.cpp @@ -545,7 +545,7 @@ namespace core { extern Model* modelAudio2; extern Model* modelAudio8; extern Model* modelAudio16; -extern Model* modelMIDI_CV; +extern Model* modelMIDI_CV_Cardinal; extern Model* modelMIDICC_CV; extern Model* modelMIDI_Gate; extern Model* modelMIDIMap; @@ -648,7 +648,7 @@ static void initStatic__Core() p->addModel(rack::core::modelAudio2); p->addModel(rack::core::modelAudio8); p->addModel(rack::core::modelAudio16); - p->addModel(rack::core::modelMIDI_CV); + p->addModel(rack::core::modelMIDI_CV_Cardinal); p->addModel(rack::core::modelMIDICC_CV); p->addModel(rack::core::modelMIDI_Gate); p->addModel(rack::core::modelMIDIMap); diff --git a/src/Makefile b/src/Makefile index 1565c18..098bed9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -91,6 +91,7 @@ RACK_FILES += CardinalModuleWidget.cpp RACK_FILES += override/blendish.c RACK_FILES += override/Engine.cpp RACK_FILES += override/MenuBar.cpp +RACK_FILES += override/MIDI_CV.cpp RACK_FILES += override/Scene.cpp RACK_FILES += override/asset.cpp RACK_FILES += override/context.cpp @@ -116,6 +117,7 @@ IGNORED_FILES += Rack/src/rtaudio.cpp IGNORED_FILES += Rack/src/rtmidi.cpp IGNORED_FILES += Rack/src/app/MenuBar.cpp IGNORED_FILES += Rack/src/app/Scene.cpp +IGNORED_FILES += Rack/src/core/MIDI_CV.cpp IGNORED_FILES += Rack/src/engine/Engine.cpp IGNORED_FILES += Rack/src/window/Window.cpp @@ -173,6 +175,11 @@ $(BUILD_DIR)/%.c.o: %.c @echo "Compiling $<" $(SILENT)$(CC) $< $(BUILD_C_FLAGS) -c -o $@ +$(BUILD_DIR)/override/MIDI_CV.cpp.o: override/MIDI_CV.cpp + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling $<" + $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -UPRIVATE -c -o $@ + $(BUILD_DIR)/Rack/src/core/Blank.cpp.o: Rack/src/core/Blank.cpp -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" @echo "Compiling $<" diff --git a/src/override/MIDI_CV.cpp b/src/override/MIDI_CV.cpp new file mode 100644 index 0000000..c34caad --- /dev/null +++ b/src/override/MIDI_CV.cpp @@ -0,0 +1,154 @@ +/* + * 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"); + +} +}