@@ -106,6 +106,14 @@ | |||||
"Visual" | "Visual" | ||||
] | ] | ||||
}, | }, | ||||
{ | |||||
"slug": "ExpanderInputMIDI", | |||||
"name": "ExpanderInputMIDI", | |||||
"description": "MIDI input expander for Carla Plugin Host or Ildaeil", | |||||
"tags": [ | |||||
"Expander" | |||||
] | |||||
}, | |||||
{ | { | ||||
"slug": "AudioFile", | "slug": "AudioFile", | ||||
"name": "Audio File", | "name": "Audio File", | ||||
@@ -0,0 +1,35 @@ | |||||
/* | |||||
* DISTRHO Cardinal Plugin | |||||
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||||
* | |||||
* 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. | |||||
*/ | |||||
#pragma once | |||||
#include "plugin.hpp" | |||||
#include "CarlaNative.h" | |||||
template<int numInputs, int numOutputs> | |||||
struct CardinalExpander : Module { | |||||
static const constexpr int kNumInputs = numInputs; | |||||
static const constexpr int kNumOutputs = numOutputs; | |||||
}; | |||||
struct CardinalExpanderFromCVToCarlaMIDI : CardinalExpander<6, 0> { | |||||
static const constexpr uint MAX_MIDI_EVENTS = 128; | |||||
// continuously filled up, flushed on each new block frame | |||||
uint frame, midiEventCount; | |||||
NativeMidiEvent midiEvents[MAX_MIDI_EVENTS]; | |||||
}; |
@@ -0,0 +1,228 @@ | |||||
/* | |||||
* DISTRHO Cardinal Plugin | |||||
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||||
* | |||||
* 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. | |||||
*/ | |||||
#include "Expander.hpp" | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
struct CardinalExpanderForInputMIDI : CardinalExpanderFromCVToCarlaMIDI { | |||||
enum ParamIds { | |||||
NUM_PARAMS | |||||
}; | |||||
enum InputIds { | |||||
PITCH_INPUT, | |||||
GATE_INPUT, | |||||
VEL_INPUT, | |||||
AFT_INPUT, | |||||
PW_INPUT, | |||||
MW_INPUT, | |||||
NUM_INPUTS | |||||
}; | |||||
enum OutputIds { | |||||
NUM_OUTPUTS | |||||
}; | |||||
enum LightIds { | |||||
NUM_LIGHTS | |||||
}; | |||||
static const constexpr uint CHANNELS = 16; | |||||
int8_t vels[CHANNELS]; | |||||
int8_t notes[CHANNELS]; | |||||
bool gates[CHANNELS]; | |||||
int8_t keyPressures[CHANNELS]; | |||||
int8_t mw; | |||||
int16_t pw; | |||||
Module* lastConnectedModule = nullptr; | |||||
CardinalExpanderForInputMIDI() { | |||||
static_assert(NUM_INPUTS == kNumInputs, "Invalid input configuration"); | |||||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||||
configInput(PITCH_INPUT, "Pitch (1V/oct)"); | |||||
configInput(GATE_INPUT, "Gate"); | |||||
configInput(VEL_INPUT, "Velocity"); | |||||
configInput(AFT_INPUT, "Aftertouch"); | |||||
configInput(PW_INPUT, "Pitch wheel"); | |||||
configInput(MW_INPUT, "Mod wheel"); | |||||
onReset(); | |||||
} | |||||
/** Must be called before setNoteGate(). */ | |||||
void setVelocity(int8_t vel, int c) { | |||||
vels[c] = vel; | |||||
} | |||||
void setNoteGate(int8_t note, bool gate, int c) { | |||||
if (midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
bool changedNote = gate && gates[c] && (note != notes[c]); | |||||
bool enabledGate = gate && !gates[c]; | |||||
bool disabledGate = !gate && gates[c]; | |||||
if (changedNote || disabledGate) { | |||||
// Note off | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0x80; | |||||
m.data[1] = notes[c]; | |||||
m.data[2] = vels[c]; | |||||
} | |||||
if (changedNote || enabledGate) { | |||||
// Note on | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0x90; | |||||
m.data[1] = note; | |||||
m.data[2] = vels[c]; | |||||
} | |||||
notes[c] = note; | |||||
gates[c] = gate; | |||||
} | |||||
void setKeyPressure(int8_t val, int c) { | |||||
if (keyPressures[c] == val || midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
keyPressures[c] = val; | |||||
// Polyphonic key pressure | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0xa0; | |||||
m.data[1] = notes[c]; | |||||
m.data[2] = val; | |||||
} | |||||
void setModWheel(int8_t mw) { | |||||
if (this->mw == mw || midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
this->mw = mw; | |||||
// Modulation Wheel (CC1) | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0xb0; | |||||
m.data[1] = 1; | |||||
m.data[2] = mw; | |||||
} | |||||
void setPitchWheel(int16_t pw) { | |||||
if (this->pw == pw || midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
this->pw = pw; | |||||
// Pitch Wheel | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0xe0; | |||||
m.data[1] = pw & 0x7f; | |||||
m.data[2] = (pw >> 7) & 0x7f; | |||||
} | |||||
void onReset() override | |||||
{ | |||||
for (uint c = 0; c < CHANNELS; c++) { | |||||
vels[c] = 100; | |||||
notes[c] = 60; | |||||
gates[c] = false; | |||||
keyPressures[c] = -1; | |||||
} | |||||
mw = -1; | |||||
pw = 0x2000; | |||||
midiEventCount = 0; | |||||
frame = UINT_MAX; | |||||
lastConnectedModule = nullptr; | |||||
} | |||||
void process(const ProcessArgs& args) override | |||||
{ | |||||
// only do stuff if there is something close to us | |||||
if (rightExpander.module == nullptr) | |||||
{ | |||||
// something was connected before, but not anymore, reset | |||||
if (frame != UINT_MAX) | |||||
onReset(); | |||||
return; | |||||
} | |||||
else if (lastConnectedModule != nullptr && lastConnectedModule != rightExpander.module) | |||||
{ | |||||
// whatever we were connected to has changed, reset | |||||
lastConnectedModule = rightExpander.module; | |||||
if (frame != UINT_MAX) | |||||
onReset(); | |||||
return; | |||||
} | |||||
// wait until expanding side is ready | |||||
if (frame == UINT_MAX) | |||||
return; | |||||
for (int c = 0; c < inputs[PITCH_INPUT].getChannels(); c++) { | |||||
int vel = (int) std::round(inputs[VEL_INPUT].getNormalPolyVoltage(10.f * 100 / 127, c) / 10.f * 127); | |||||
vel = clamp(vel, 0, 127); | |||||
setVelocity(vel, c); | |||||
int note = (int) std::round(inputs[PITCH_INPUT].getVoltage(c) * 12.f + 60.f); | |||||
note = clamp(note, 0, 127); | |||||
bool gate = inputs[GATE_INPUT].getPolyVoltage(c) >= 1.f; | |||||
setNoteGate(note, gate, c); | |||||
int aft = (int) std::round(inputs[AFT_INPUT].getPolyVoltage(c) / 10.f * 127); | |||||
aft = clamp(aft, 0, 127); | |||||
setKeyPressure(aft, c); | |||||
} | |||||
int pw = (int) std::round((inputs[PW_INPUT].getVoltage() + 5.f) / 10.f * 0x4000); | |||||
pw = clamp(pw, 0, 0x3fff); | |||||
setPitchWheel(pw); | |||||
int mw = (int) std::round(inputs[MW_INPUT].getVoltage() / 10.f * 127); | |||||
mw = clamp(mw, 0, 127); | |||||
setModWheel(mw); | |||||
++frame; | |||||
} | |||||
}; | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
struct CardinalExpanderForInputMIDIWidget : ModuleWidget { | |||||
CardinalExpanderForInputMIDIWidget(CardinalExpanderForInputMIDI* const module) | |||||
{ | |||||
setModule(module); | |||||
box.size.x = RACK_GRID_WIDTH * 2; | |||||
addChild(createWidget<ScrewBlack>(Vec(0, 0))); | |||||
addChild(createWidget<ScrewBlack>(Vec(0, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||||
addChild(createWidget<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0))); | |||||
addChild(createWidget<ScrewBlack>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||||
for (int i=0; i<6; ++i) | |||||
addInput(createInput<PJ301MPort>(Vec(15, 50 + 29 * i), module, i)); | |||||
} | |||||
}; | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
Model* modelExpanderInputMIDI = createModel<CardinalExpanderForInputMIDI, CardinalExpanderForInputMIDIWidget>("ExpanderInputMIDI"); | |||||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -26,6 +26,7 @@ | |||||
*/ | */ | ||||
#include "plugincontext.hpp" | #include "plugincontext.hpp" | ||||
#include "Expander.hpp" | |||||
#ifndef HEADLESS | #ifndef HEADLESS | ||||
# include "ImGuiWidget.hpp" | # include "ImGuiWidget.hpp" | ||||
@@ -75,122 +76,6 @@ namespace ildaeil { | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
/** Converts gates and CV to MIDI messages. */ | |||||
struct IldaeilMidiGenerator { | |||||
static const constexpr uint CHANNELS = 16; | |||||
static const constexpr uint MAX_MIDI_EVENTS = 128; | |||||
int8_t vels[CHANNELS]; | |||||
int8_t notes[CHANNELS]; | |||||
bool gates[CHANNELS]; | |||||
int8_t keyPressures[CHANNELS]; | |||||
int8_t mw; | |||||
int16_t pw; | |||||
uint32_t frame; | |||||
// generated output | |||||
uint midiEventCount; | |||||
NativeMidiEvent midiEvents[MAX_MIDI_EVENTS]; | |||||
IldaeilMidiGenerator() { | |||||
reset(); | |||||
} | |||||
void reset() { | |||||
for (uint c = 0; c < CHANNELS; c++) { | |||||
vels[c] = 100; | |||||
notes[c] = 60; | |||||
gates[c] = false; | |||||
keyPressures[c] = -1; | |||||
} | |||||
mw = -1; | |||||
pw = 0x2000; | |||||
frame = 0; | |||||
midiEventCount = 0; | |||||
} | |||||
void setFrame(uint32_t frame) { | |||||
this->frame = frame; | |||||
if (frame == 0) | |||||
midiEventCount = 0; | |||||
} | |||||
/** Must be called before setNoteGate(). */ | |||||
void setVelocity(int8_t vel, int c) { | |||||
vels[c] = vel; | |||||
} | |||||
void setNoteGate(int8_t note, bool gate, int c) { | |||||
if (midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
bool changedNote = gate && gates[c] && (note != notes[c]); | |||||
bool enabledGate = gate && !gates[c]; | |||||
bool disabledGate = !gate && gates[c]; | |||||
if (changedNote || disabledGate) { | |||||
// Note off | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0x80; | |||||
m.data[1] = notes[c]; | |||||
m.data[2] = vels[c]; | |||||
} | |||||
if (changedNote || enabledGate) { | |||||
// Note on | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0x90; | |||||
m.data[1] = note; | |||||
m.data[2] = vels[c]; | |||||
} | |||||
notes[c] = note; | |||||
gates[c] = gate; | |||||
} | |||||
void setKeyPressure(int8_t val, int c) { | |||||
if (keyPressures[c] == val || midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
keyPressures[c] = val; | |||||
// Polyphonic key pressure | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0xa0; | |||||
m.data[1] = notes[c]; | |||||
m.data[2] = val; | |||||
} | |||||
void setModWheel(int8_t mw) { | |||||
if (this->mw == mw || midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
this->mw = mw; | |||||
// Modulation Wheel (CC1) | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0xb0; | |||||
m.data[1] = 1; | |||||
m.data[2] = mw; | |||||
} | |||||
void setPitchWheel(int16_t pw) { | |||||
if (this->pw == pw || midiEventCount == MAX_MIDI_EVENTS) | |||||
return; | |||||
this->pw = pw; | |||||
// Pitch Wheel | |||||
NativeMidiEvent& m(midiEvents[midiEventCount++]); | |||||
m.time = frame; | |||||
m.port = 0; | |||||
m.size = 3; | |||||
m.data[0] = 0xe0; | |||||
m.data[1] = pw & 0x7f; | |||||
m.data[2] = (pw >> 7) & 0x7f; | |||||
} | |||||
}; | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
using namespace CarlaBackend; | using namespace CarlaBackend; | ||||
@@ -227,12 +112,6 @@ struct IldaeilModule : Module { | |||||
enum InputIds { | enum InputIds { | ||||
INPUT1, | INPUT1, | ||||
INPUT2, | INPUT2, | ||||
PITCH_INPUT, | |||||
GATE_INPUT, | |||||
VEL_INPUT, | |||||
AFT_INPUT, | |||||
PW_INPUT, | |||||
MW_INPUT, | |||||
NUM_INPUTS | NUM_INPUTS | ||||
}; | }; | ||||
enum OutputIds { | enum OutputIds { | ||||
@@ -268,8 +147,6 @@ struct IldaeilModule : Module { | |||||
unsigned audioDataFill = 0; | unsigned audioDataFill = 0; | ||||
int64_t lastBlockFrame = -1; | int64_t lastBlockFrame = -1; | ||||
IldaeilMidiGenerator midiGenerator; | |||||
IldaeilModule() | IldaeilModule() | ||||
: pcontext(static_cast<CardinalPluginContext*>(APP)) | : pcontext(static_cast<CardinalPluginContext*>(APP)) | ||||
{ | { | ||||
@@ -280,13 +157,6 @@ struct IldaeilModule : Module { | |||||
configInput(i, name); | configInput(i, name); | ||||
configOutput(i, name); | configOutput(i, name); | ||||
} | } | ||||
configInput(PITCH_INPUT, "Pitch (1V/oct)"); | |||||
configInput(GATE_INPUT, "Gate"); | |||||
configInput(VEL_INPUT, "Velocity"); | |||||
configInput(AFT_INPUT, "Aftertouch"); | |||||
configInput(PW_INPUT, "Pitch wheel"); | |||||
configInput(MW_INPUT, "Mod wheel"); | |||||
std::memset(audioDataOut1, 0, sizeof(audioDataOut1)); | std::memset(audioDataOut1, 0, sizeof(audioDataOut1)); | ||||
std::memset(audioDataOut2, 0, sizeof(audioDataOut2)); | std::memset(audioDataOut2, 0, sizeof(audioDataOut2)); | ||||
@@ -472,31 +342,6 @@ struct IldaeilModule : Module { | |||||
outputs[OUTPUT1].setVoltage(audioDataOut1[i] * 10.0f); | outputs[OUTPUT1].setVoltage(audioDataOut1[i] * 10.0f); | ||||
outputs[OUTPUT2].setVoltage(audioDataOut2[i] * 10.0f); | outputs[OUTPUT2].setVoltage(audioDataOut2[i] * 10.0f); | ||||
midiGenerator.setFrame(i); | |||||
for (int c = 0; c < inputs[PITCH_INPUT].getChannels(); c++) { | |||||
int vel = (int) std::round(inputs[VEL_INPUT].getNormalPolyVoltage(10.f * 100 / 127, c) / 10.f * 127); | |||||
vel = clamp(vel, 0, 127); | |||||
midiGenerator.setVelocity(vel, c); | |||||
int note = (int) std::round(inputs[PITCH_INPUT].getVoltage(c) * 12.f + 60.f); | |||||
note = clamp(note, 0, 127); | |||||
bool gate = inputs[GATE_INPUT].getPolyVoltage(c) >= 1.f; | |||||
midiGenerator.setNoteGate(note, gate, c); | |||||
int aft = (int) std::round(inputs[AFT_INPUT].getPolyVoltage(c) / 10.f * 127); | |||||
aft = clamp(aft, 0, 127); | |||||
midiGenerator.setKeyPressure(aft, c); | |||||
} | |||||
int pw = (int) std::round((inputs[PW_INPUT].getVoltage() + 5.f) / 10.f * 0x4000); | |||||
pw = clamp(pw, 0, 0x3fff); | |||||
midiGenerator.setPitchWheel(pw); | |||||
int mw = (int) std::round(inputs[MW_INPUT].getVoltage() / 10.f * 127); | |||||
mw = clamp(mw, 0, 127); | |||||
midiGenerator.setModWheel(mw); | |||||
if (audioDataFill == BUFFER_SIZE) | if (audioDataFill == BUFFER_SIZE) | ||||
{ | { | ||||
const int64_t blockFrame = pcontext->engine->getBlockFrame(); | const int64_t blockFrame = pcontext->engine->getBlockFrame(); | ||||
@@ -552,19 +397,30 @@ struct IldaeilModule : Module { | |||||
} | } | ||||
} | } | ||||
NativeMidiEvent* midiEvents; | |||||
uint midiEventCount; | |||||
if (CardinalExpanderFromCVToCarlaMIDI* const midiInExpander = leftExpander.module != nullptr && leftExpander.module->model == modelExpanderInputMIDI | |||||
? static_cast<CardinalExpanderFromCVToCarlaMIDI*>(leftExpander.module) | |||||
: nullptr) | |||||
{ | |||||
midiEvents = midiInExpander->midiEvents; | |||||
midiEventCount = midiInExpander->midiEventCount; | |||||
midiInExpander->midiEventCount = midiInExpander->frame = 0; | |||||
} | |||||
else | |||||
{ | |||||
midiEvents = nullptr; | |||||
midiEventCount = 0; | |||||
} | |||||
audioDataFill = 0; | audioDataFill = 0; | ||||
float* ins[2] = { audioDataIn1, audioDataIn2 }; | float* ins[2] = { audioDataIn1, audioDataIn2 }; | ||||
float* outs[2] = { audioDataOut1, audioDataOut2 }; | float* outs[2] = { audioDataOut1, audioDataOut2 }; | ||||
fCarlaPluginDescriptor->process(fCarlaPluginHandle, ins, outs, BUFFER_SIZE, | |||||
midiGenerator.midiEvents, midiGenerator.midiEventCount); | |||||
fCarlaPluginDescriptor->process(fCarlaPluginHandle, ins, outs, BUFFER_SIZE, midiEvents, midiEventCount); | |||||
} | } | ||||
} | } | ||||
void onReset() override | |||||
{ | |||||
midiGenerator.reset(); | |||||
} | |||||
void onSampleRateChange(const SampleRateChangeEvent& e) override | void onSampleRateChange(const SampleRateChangeEvent& e) override | ||||
{ | { | ||||
if (fCarlaPluginHandle == nullptr) | if (fCarlaPluginHandle == nullptr) | ||||
@@ -1688,13 +1544,6 @@ struct IldaeilModuleWidget : ModuleWidget { | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 30), module, IldaeilModule::INPUT2)); | addInput(createInput<PJ301MPort>(Vec(3, 54 + 30), module, IldaeilModule::INPUT2)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 60), module, IldaeilModule::OUTPUT1)); | addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 60), module, IldaeilModule::OUTPUT1)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 90), module, IldaeilModule::OUTPUT2)); | addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 90), module, IldaeilModule::OUTPUT2)); | ||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 135), module, IldaeilModule::PITCH_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 165), module, IldaeilModule::GATE_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 195), module, IldaeilModule::VEL_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 225), module, IldaeilModule::AFT_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 255), module, IldaeilModule::PW_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 285), module, IldaeilModule::MW_INPUT)); | |||||
} | } | ||||
void draw(const DrawArgs& args) override | void draw(const DrawArgs& args) override | ||||
@@ -1722,13 +1571,6 @@ struct IldaeilModuleWidget : ModuleWidget { | |||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::INPUT2)); | addInput(createInput<PJ301MPort>({}, module, IldaeilModule::INPUT2)); | ||||
addOutput(createOutput<PJ301MPort>({}, module, IldaeilModule::OUTPUT1)); | addOutput(createOutput<PJ301MPort>({}, module, IldaeilModule::OUTPUT1)); | ||||
addOutput(createOutput<PJ301MPort>({}, module, IldaeilModule::OUTPUT2)); | addOutput(createOutput<PJ301MPort>({}, module, IldaeilModule::OUTPUT2)); | ||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::PITCH_INPUT)); | |||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::GATE_INPUT)); | |||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::VEL_INPUT)); | |||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::AFT_INPUT)); | |||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::PW_INPUT)); | |||||
addInput(createInput<PJ301MPort>({}, module, IldaeilModule::MW_INPUT)); | |||||
} | } | ||||
}; | }; | ||||
#endif | #endif | ||||
@@ -30,6 +30,7 @@ extern Plugin* pluginInstance; | |||||
extern Model* modelAudioFile; | extern Model* modelAudioFile; | ||||
extern Model* modelCarla; | extern Model* modelCarla; | ||||
extern Model* modelCardinalBlank; | extern Model* modelCardinalBlank; | ||||
extern Model* modelExpanderInputMIDI; | |||||
extern Model* modelGlBars; | extern Model* modelGlBars; | ||||
extern Model* modelHostAudio2; | extern Model* modelHostAudio2; | ||||
extern Model* modelHostAudio8; | extern Model* modelHostAudio8; | ||||
@@ -187,6 +187,7 @@ PLUGIN_FILES = plugins.cpp | |||||
# Cardinal (built-in) | # Cardinal (built-in) | ||||
PLUGIN_FILES += Cardinal/src/Blank.cpp | PLUGIN_FILES += Cardinal/src/Blank.cpp | ||||
PLUGIN_FILES += Cardinal/src/Expanders.cpp | |||||
PLUGIN_FILES += Cardinal/src/glBars.cpp | PLUGIN_FILES += Cardinal/src/glBars.cpp | ||||
PLUGIN_FILES += Cardinal/src/HostAudio.cpp | PLUGIN_FILES += Cardinal/src/HostAudio.cpp | ||||
PLUGIN_FILES += Cardinal/src/HostCV.cpp | PLUGIN_FILES += Cardinal/src/HostCV.cpp | ||||
@@ -674,6 +674,7 @@ static void initStatic__Cardinal() | |||||
if (spl.ok()) | if (spl.ok()) | ||||
{ | { | ||||
p->addModel(modelCardinalBlank); | p->addModel(modelCardinalBlank); | ||||
p->addModel(modelExpanderInputMIDI); | |||||
p->addModel(modelGlBars); | p->addModel(modelGlBars); | ||||
p->addModel(modelHostAudio2); | p->addModel(modelHostAudio2); | ||||
p->addModel(modelHostAudio8); | p->addModel(modelHostAudio8); | ||||