@@ -6,12 +6,14 @@ | |||||
namespace rack { | namespace rack { | ||||
struct MidiIO; | |||||
namespace midi { | |||||
struct IO; | |||||
} | |||||
struct MidiWidget : LedDisplay { | struct MidiWidget : LedDisplay { | ||||
/** Not owned */ | /** Not owned */ | ||||
MidiIO *midiIO = NULL; | |||||
midi::IO *midiIO = NULL; | |||||
LedDisplayChoice *driverChoice; | LedDisplayChoice *driverChoice; | ||||
LedDisplaySeparator *driverSeparator; | LedDisplaySeparator *driverSeparator; | ||||
LedDisplayChoice *deviceChoice; | LedDisplayChoice *deviceChoice; | ||||
@@ -7,18 +7,18 @@ | |||||
namespace rack { | namespace rack { | ||||
struct BridgeMidiInputDevice : MidiInputDevice { | |||||
struct BridgeMidiInputDevice : midi::InputDevice { | |||||
}; | }; | ||||
struct BridgeMidiDriver : MidiDriver { | |||||
struct BridgeMidiDriver : midi::Driver { | |||||
BridgeMidiInputDevice devices[16]; | BridgeMidiInputDevice devices[16]; | ||||
std::string getName() override {return "Bridge";} | std::string getName() override {return "Bridge";} | ||||
std::vector<int> getInputDeviceIds() override; | std::vector<int> getInputDeviceIds() override; | ||||
std::string getInputDeviceName(int deviceId) override; | std::string getInputDeviceName(int deviceId) override; | ||||
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
void unsubscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
}; | }; | ||||
@@ -7,7 +7,7 @@ namespace rack { | |||||
namespace gamepad { | namespace gamepad { | ||||
struct InputDevice : MidiInputDevice { | |||||
struct InputDevice : midi::InputDevice { | |||||
int deviceId; | int deviceId; | ||||
std::vector<uint8_t> ccs; | std::vector<uint8_t> ccs; | ||||
std::vector<bool> states; | std::vector<bool> states; | ||||
@@ -15,15 +15,15 @@ struct InputDevice : MidiInputDevice { | |||||
}; | }; | ||||
struct Driver : MidiDriver { | |||||
struct Driver : midi::Driver { | |||||
InputDevice devices[16]; | InputDevice devices[16]; | ||||
Driver(); | Driver(); | ||||
std::string getName() override {return "Gamepad";} | std::string getName() override {return "Gamepad";} | ||||
std::vector<int> getInputDeviceIds() override; | std::vector<int> getInputDeviceIds() override; | ||||
std::string getInputDeviceName(int deviceId) override; | std::string getInputDeviceName(int deviceId) override; | ||||
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
void unsubscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
}; | }; | ||||
@@ -8,7 +8,7 @@ namespace rack { | |||||
namespace keyboard { | namespace keyboard { | ||||
struct InputDevice : MidiInputDevice { | |||||
struct InputDevice : midi::InputDevice { | |||||
int octave = 5; | int octave = 5; | ||||
std::map<int, int> pressedNotes; | std::map<int, int> pressedNotes; | ||||
void onKeyPress(int key); | void onKeyPress(int key); | ||||
@@ -16,14 +16,14 @@ struct InputDevice : MidiInputDevice { | |||||
}; | }; | ||||
struct Driver : MidiDriver { | |||||
struct Driver : midi::Driver { | |||||
InputDevice device; | InputDevice device; | ||||
std::string getName() override {return "Computer keyboard";} | std::string getName() override {return "Computer keyboard";} | ||||
std::vector<int> getInputDeviceIds() override; | std::vector<int> getInputDeviceIds() override; | ||||
std::string getInputDeviceName(int deviceId) override; | std::string getInputDeviceName(int deviceId) override; | ||||
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
void unsubscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
}; | }; | ||||
@@ -7,9 +7,10 @@ | |||||
namespace rack { | namespace rack { | ||||
namespace midi { | |||||
struct MidiMessage { | |||||
struct Message { | |||||
uint8_t cmd = 0x00; | uint8_t cmd = 0x00; | ||||
uint8_t data1 = 0x00; | uint8_t data1 = 0x00; | ||||
uint8_t data2 = 0x00; | uint8_t data2 = 0x00; | ||||
@@ -29,50 +30,50 @@ struct MidiMessage { | |||||
}; | }; | ||||
//////////////////// | //////////////////// | ||||
// MidiDevice | |||||
// Device | |||||
//////////////////// | //////////////////// | ||||
struct MidiDevice { | |||||
virtual ~MidiDevice() {} | |||||
struct Device { | |||||
virtual ~Device() {} | |||||
}; | }; | ||||
struct MidiInput; | |||||
struct Input; | |||||
struct MidiInputDevice : MidiDevice { | |||||
std::set<MidiInput*> subscribed; | |||||
void subscribe(MidiInput *midiInput); | |||||
void unsubscribe(MidiInput *midiInput); | |||||
void onMessage(MidiMessage message); | |||||
struct InputDevice : Device { | |||||
std::set<Input*> subscribed; | |||||
void subscribe(Input *input); | |||||
void unsubscribe(Input *input); | |||||
void onMessage(Message message); | |||||
}; | }; | ||||
struct MidiOutputDevice : MidiDevice { | |||||
struct OutputDevice : Device { | |||||
// TODO | // TODO | ||||
}; | }; | ||||
//////////////////// | //////////////////// | ||||
// MidiDriver | |||||
// Driver | |||||
//////////////////// | //////////////////// | ||||
struct MidiDriver { | |||||
virtual ~MidiDriver() {} | |||||
struct Driver { | |||||
virtual ~Driver() {} | |||||
virtual std::string getName() {return "";} | virtual std::string getName() {return "";} | ||||
virtual std::vector<int> getInputDeviceIds() {return {};} | virtual std::vector<int> getInputDeviceIds() {return {};} | ||||
virtual std::string getInputDeviceName(int deviceId) {return "";} | virtual std::string getInputDeviceName(int deviceId) {return "";} | ||||
virtual MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) {return NULL;} | |||||
virtual void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {} | |||||
virtual InputDevice *subscribeInputDevice(int deviceId, Input *input) {return NULL;} | |||||
virtual void unsubscribeInputDevice(int deviceId, Input *input) {} | |||||
// virtual std::vector<int> getOutputDeviceIds() = 0; | // virtual std::vector<int> getOutputDeviceIds() = 0; | ||||
// virtual std::string getOutputDeviceName(int deviceId) = 0; | // virtual std::string getOutputDeviceName(int deviceId) = 0; | ||||
// virtual MidiOutputDevice *subscribeOutputDevice(int deviceId, MidiOutput *midiOutput) = 0; | |||||
// virtual void unsubscribeOutputDevice(int deviceId, MidiOutput *midiOutput) = 0; | |||||
// virtual OutputDevice *subscribeOutputDevice(int deviceId, Output *midiOutput) = 0; | |||||
// virtual void unsubscribeOutputDevice(int deviceId, Output *midiOutput) = 0; | |||||
}; | }; | ||||
//////////////////// | //////////////////// | ||||
// MidiIO | |||||
// IO | |||||
//////////////////// | //////////////////// | ||||
struct MidiIO { | |||||
struct IO { | |||||
int driverId = -1; | int driverId = -1; | ||||
int deviceId = -1; | int deviceId = -1; | ||||
/* For MIDI output, the channel to output messages. | /* For MIDI output, the channel to output messages. | ||||
@@ -82,9 +83,9 @@ struct MidiIO { | |||||
*/ | */ | ||||
int channel = -1; | int channel = -1; | ||||
/** Not owned */ | /** Not owned */ | ||||
MidiDriver *driver = NULL; | |||||
Driver *driver = NULL; | |||||
virtual ~MidiIO(); | |||||
virtual ~IO(); | |||||
std::vector<int> getDriverIds(); | std::vector<int> getDriverIds(); | ||||
std::string getDriverName(int driverId); | std::string getDriverName(int driverId); | ||||
@@ -100,36 +101,38 @@ struct MidiIO { | |||||
}; | }; | ||||
struct MidiInput : MidiIO { | |||||
MidiInput(); | |||||
~MidiInput(); | |||||
struct Input : IO { | |||||
Input(); | |||||
~Input(); | |||||
std::vector<int> getDeviceIds() override; | std::vector<int> getDeviceIds() override; | ||||
std::string getDeviceName(int deviceId) override; | std::string getDeviceName(int deviceId) override; | ||||
void setDeviceId(int deviceId) override; | void setDeviceId(int deviceId) override; | ||||
virtual void onMessage(MidiMessage message) {} | |||||
virtual void onMessage(Message message) {} | |||||
}; | }; | ||||
struct MidiInputQueue : MidiInput { | |||||
struct InputQueue : Input { | |||||
int queueMaxSize = 8192; | int queueMaxSize = 8192; | ||||
std::queue<MidiMessage> queue; | |||||
void onMessage(MidiMessage message) override; | |||||
/** If a MidiMessage is available, writes `message` and return true */ | |||||
bool shift(MidiMessage *message); | |||||
std::queue<Message> queue; | |||||
void onMessage(Message message) override; | |||||
/** If a Message is available, writes `message` and return true */ | |||||
bool shift(Message *message); | |||||
}; | }; | ||||
struct MidiOutput : MidiIO { | |||||
MidiOutput(); | |||||
~MidiOutput(); | |||||
struct Output : IO { | |||||
Output(); | |||||
~Output(); | |||||
void setDeviceId(int deviceId) override; | void setDeviceId(int deviceId) override; | ||||
}; | }; | ||||
void midiDestroy(); | |||||
void init(); | |||||
void destroy(); | |||||
/** Registers a new MIDI driver. Takes pointer ownership. */ | /** Registers a new MIDI driver. Takes pointer ownership. */ | ||||
void midiDriverAdd(int driverId, MidiDriver *driver); | |||||
void addDriver(int driverId, Driver *driver); | |||||
} // namespace midi | |||||
} // namespace rack | } // namespace rack |
@@ -14,7 +14,7 @@ | |||||
namespace rack { | namespace rack { | ||||
struct RtMidiInputDevice : MidiInputDevice { | |||||
struct RtMidiInputDevice : midi::InputDevice { | |||||
RtMidiIn *rtMidiIn; | RtMidiIn *rtMidiIn; | ||||
RtMidiInputDevice(int driverId, int deviceId); | RtMidiInputDevice(int driverId, int deviceId); | ||||
@@ -22,7 +22,7 @@ struct RtMidiInputDevice : MidiInputDevice { | |||||
}; | }; | ||||
struct RtMidiDriver : MidiDriver { | |||||
struct RtMidiDriver : midi::Driver { | |||||
int driverId; | int driverId; | ||||
/** Just for querying MIDI driver information */ | /** Just for querying MIDI driver information */ | ||||
RtMidiIn *rtMidiIn; | RtMidiIn *rtMidiIn; | ||||
@@ -34,8 +34,8 @@ struct RtMidiDriver : MidiDriver { | |||||
std::string getName() override; | std::string getName() override; | ||||
std::vector<int> getInputDeviceIds() override; | std::vector<int> getInputDeviceIds() override; | ||||
std::string getInputDeviceName(int deviceId) override; | std::string getInputDeviceName(int deviceId) override; | ||||
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override; | |||||
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
void unsubscribeInputDevice(int deviceId, midi::Input *input) override; | |||||
}; | }; | ||||
@@ -18,7 +18,7 @@ struct MIDICCToCVInterface : Module { | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
MidiInputQueue midiInput; | |||||
midi::InputQueue midiInput; | |||||
int8_t ccs[128]; | int8_t ccs[128]; | ||||
ExponentialFilter ccFilters[16]; | ExponentialFilter ccFilters[16]; | ||||
@@ -41,7 +41,7 @@ struct MIDICCToCVInterface : Module { | |||||
} | } | ||||
void step() override { | void step() override { | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
while (midiInput.shift(&msg)) { | while (midiInput.shift(&msg)) { | ||||
processMessage(msg); | processMessage(msg); | ||||
} | } | ||||
@@ -55,7 +55,7 @@ struct MIDICCToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
void processMessage(MidiMessage msg) { | |||||
void processMessage(midi::Message msg) { | |||||
switch (msg.status()) { | switch (msg.status()) { | ||||
// cc | // cc | ||||
case 0xb: { | case 0xb: { | ||||
@@ -32,7 +32,7 @@ struct MIDIToCVInterface : Module { | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
MidiInputQueue midiInput; | |||||
midi::InputQueue midiInput; | |||||
uint8_t mod = 0; | uint8_t mod = 0; | ||||
ExponentialFilter modFilter; | ExponentialFilter modFilter; | ||||
@@ -142,7 +142,7 @@ struct MIDIToCVInterface : Module { | |||||
} | } | ||||
void step() override { | void step() override { | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
while (midiInput.shift(&msg)) { | while (midiInput.shift(&msg)) { | ||||
processMessage(msg); | processMessage(msg); | ||||
} | } | ||||
@@ -167,7 +167,7 @@ struct MIDIToCVInterface : Module { | |||||
outputs[CONTINUE_OUTPUT].value = continuePulse.process(deltaTime) ? 10.f : 0.f; | outputs[CONTINUE_OUTPUT].value = continuePulse.process(deltaTime) ? 10.f : 0.f; | ||||
} | } | ||||
void processMessage(MidiMessage msg) { | |||||
void processMessage(midi::Message msg) { | |||||
// DEBUG("MIDI: %01x %01x %02x %02x", msg.status(), msg.channel(), msg.note(), msg.value()); | // DEBUG("MIDI: %01x %01x %02x %02x", msg.status(), msg.channel(), msg.note(), msg.value()); | ||||
switch (msg.status()) { | switch (msg.status()) { | ||||
@@ -206,7 +206,7 @@ struct MIDIToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
void processCC(MidiMessage msg) { | |||||
void processCC(midi::Message msg) { | |||||
switch (msg.note()) { | switch (msg.note()) { | ||||
// mod | // mod | ||||
case 0x01: { | case 0x01: { | ||||
@@ -223,7 +223,7 @@ struct MIDIToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
void processSystem(MidiMessage msg) { | |||||
void processSystem(midi::Message msg) { | |||||
switch (msg.channel()) { | switch (msg.channel()) { | ||||
// Timing | // Timing | ||||
case 0x8: { | case 0x8: { | ||||
@@ -18,7 +18,7 @@ struct MIDITriggerToCVInterface : Module { | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
MidiInputQueue midiInput; | |||||
midi::InputQueue midiInput; | |||||
bool gates[16]; | bool gates[16]; | ||||
float gateTimes[16]; | float gateTimes[16]; | ||||
@@ -67,7 +67,7 @@ struct MIDITriggerToCVInterface : Module { | |||||
} | } | ||||
void step() override { | void step() override { | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
while (midiInput.shift(&msg)) { | while (midiInput.shift(&msg)) { | ||||
processMessage(msg); | processMessage(msg); | ||||
} | } | ||||
@@ -88,7 +88,7 @@ struct MIDITriggerToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
void processMessage(MidiMessage msg) { | |||||
void processMessage(midi::Message msg) { | |||||
switch (msg.status()) { | switch (msg.status()) { | ||||
// note off | // note off | ||||
case 0x8: { | case 0x8: { | ||||
@@ -23,7 +23,7 @@ struct QuadMIDIToCVInterface : Module { | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
MidiInputQueue midiInput; | |||||
midi::InputQueue midiInput; | |||||
enum PolyMode { | enum PolyMode { | ||||
ROTATE_MODE, | ROTATE_MODE, | ||||
@@ -243,7 +243,7 @@ struct QuadMIDIToCVInterface : Module { | |||||
} | } | ||||
void step() override { | void step() override { | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
while (midiInput.shift(&msg)) { | while (midiInput.shift(&msg)) { | ||||
processMessage(msg); | processMessage(msg); | ||||
} | } | ||||
@@ -258,7 +258,7 @@ struct QuadMIDIToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
void processMessage(MidiMessage msg) { | |||||
void processMessage(midi::Message msg) { | |||||
switch (msg.status()) { | switch (msg.status()) { | ||||
// note off | // note off | ||||
case 0x8: { | case 0x8: { | ||||
@@ -286,7 +286,7 @@ struct QuadMIDIToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
void processCC(MidiMessage msg) { | |||||
void processCC(midi::Message msg) { | |||||
switch (msg.note()) { | switch (msg.note()) { | ||||
// sustain | // sustain | ||||
case 0x40: { | case 0x40: { | ||||
@@ -7,7 +7,7 @@ namespace rack { | |||||
struct MidiDriverItem : MenuItem { | struct MidiDriverItem : MenuItem { | ||||
MidiIO *midiIO; | |||||
midi::IO *midiIO; | |||||
int driverId; | int driverId; | ||||
void onAction(event::Action &e) override { | void onAction(event::Action &e) override { | ||||
midiIO->setDriverId(driverId); | midiIO->setDriverId(driverId); | ||||
@@ -41,7 +41,7 @@ struct MidiDriverChoice : LedDisplayChoice { | |||||
}; | }; | ||||
struct MidiDeviceItem : MenuItem { | struct MidiDeviceItem : MenuItem { | ||||
MidiIO *midiIO; | |||||
midi::IO *midiIO; | |||||
int deviceId; | int deviceId; | ||||
void onAction(event::Action &e) override { | void onAction(event::Action &e) override { | ||||
midiIO->setDeviceId(deviceId); | midiIO->setDeviceId(deviceId); | ||||
@@ -83,7 +83,7 @@ struct MidiDeviceChoice : LedDisplayChoice { | |||||
}; | }; | ||||
struct MidiChannelItem : MenuItem { | struct MidiChannelItem : MenuItem { | ||||
MidiIO *midiIO; | |||||
midi::IO *midiIO; | |||||
int channel; | int channel; | ||||
void onAction(event::Action &e) override { | void onAction(event::Action &e) override { | ||||
midiIO->channel = channel; | midiIO->channel = channel; | ||||
@@ -147,7 +147,7 @@ struct BridgeClientConnection { | |||||
} break; | } break; | ||||
case MIDI_MESSAGE_COMMAND: { | case MIDI_MESSAGE_COMMAND: { | ||||
MidiMessage message; | |||||
midi::Message message; | |||||
if (!recv(&message, 3)) { | if (!recv(&message, 3)) { | ||||
return; | return; | ||||
} | } | ||||
@@ -203,7 +203,7 @@ struct BridgeClientConnection { | |||||
} | } | ||||
} | } | ||||
void processMidi(MidiMessage message) { | |||||
void processMidi(midi::Message message) { | |||||
if (!(0 <= port && port < BRIDGE_NUM_PORTS)) | if (!(0 <= port && port < BRIDGE_NUM_PORTS)) | ||||
return; | return; | ||||
if (!driver) | if (!driver) | ||||
@@ -387,19 +387,19 @@ std::string BridgeMidiDriver::getInputDeviceName(int deviceId) { | |||||
return string::f("Port %d", deviceId + 1); | return string::f("Port %d", deviceId + 1); | ||||
} | } | ||||
MidiInputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
midi::InputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (!(0 <= deviceId && deviceId < 16)) | if (!(0 <= deviceId && deviceId < 16)) | ||||
return NULL; | return NULL; | ||||
devices[deviceId].subscribe(midiInput); | |||||
devices[deviceId].subscribe(input); | |||||
return &devices[deviceId]; | return &devices[deviceId]; | ||||
} | } | ||||
void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (!(0 <= deviceId && deviceId < 16)) | if (!(0 <= deviceId && deviceId < 16)) | ||||
return; | return; | ||||
devices[deviceId].unsubscribe(midiInput); | |||||
devices[deviceId].unsubscribe(input); | |||||
} | } | ||||
@@ -408,7 +408,7 @@ void bridgeInit() { | |||||
serverThread = std::thread(serverRun); | serverThread = std::thread(serverRun); | ||||
driver = new BridgeMidiDriver; | driver = new BridgeMidiDriver; | ||||
midiDriverAdd(BRIDGE_DRIVER, driver); | |||||
midi::addDriver(BRIDGE_DRIVER, driver); | |||||
} | } | ||||
void bridgeDestroy() { | void bridgeDestroy() { | ||||
@@ -29,7 +29,7 @@ void InputDevice::step() { | |||||
ccs[i] = cc; | ccs[i] = cc; | ||||
// Send MIDI message | // Send MIDI message | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
// MIDI channel 1 | // MIDI channel 1 | ||||
msg.cmd = (0xb << 4) | 0; | msg.cmd = (0xb << 4) | 0; | ||||
msg.data1 = i; | msg.data1 = i; | ||||
@@ -45,7 +45,7 @@ void InputDevice::step() { | |||||
if (state != states[i]) { | if (state != states[i]) { | ||||
states[i] = state; | states[i] = state; | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
msg.cmd = ((state ? 0x9 : 0x8) << 4); | msg.cmd = ((state ? 0x9 : 0x8) << 4); | ||||
msg.data1 = i; | msg.data1 = i; | ||||
msg.data2 = 127; | msg.data2 = 127; | ||||
@@ -82,25 +82,25 @@ std::string Driver::getInputDeviceName(int deviceId) { | |||||
return string::f(" %d (unavailable)", deviceId + 1); | return string::f(" %d (unavailable)", deviceId + 1); | ||||
} | } | ||||
MidiInputDevice *Driver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
midi::InputDevice *Driver::subscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (!(0 <= deviceId && deviceId < 16)) | if (!(0 <= deviceId && deviceId < 16)) | ||||
return NULL; | return NULL; | ||||
devices[deviceId].subscribe(midiInput); | |||||
devices[deviceId].subscribe(input); | |||||
return &devices[deviceId]; | return &devices[deviceId]; | ||||
} | } | ||||
void Driver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
void Driver::unsubscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (!(0 <= deviceId && deviceId < 16)) | if (!(0 <= deviceId && deviceId < 16)) | ||||
return; | return; | ||||
devices[deviceId].unsubscribe(midiInput); | |||||
devices[deviceId].unsubscribe(input); | |||||
} | } | ||||
void init() { | void init() { | ||||
driver = new Driver; | driver = new Driver; | ||||
midiDriverAdd(DRIVER, driver); | |||||
midi::addDriver(DRIVER, driver); | |||||
} | } | ||||
void step() { | void step() { | ||||
@@ -69,7 +69,7 @@ void InputDevice::onKeyPress(int key) { | |||||
if (note > 127) | if (note > 127) | ||||
return; | return; | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
msg.cmd = 0x9 << 4; | msg.cmd = 0x9 << 4; | ||||
msg.data1 = note; | msg.data1 = note; | ||||
msg.data2 = 127; | msg.data2 = 127; | ||||
@@ -82,7 +82,7 @@ void InputDevice::onKeyRelease(int key) { | |||||
auto it = pressedNotes.find(key); | auto it = pressedNotes.find(key); | ||||
if (it != pressedNotes.end()) { | if (it != pressedNotes.end()) { | ||||
int note = it->second; | int note = it->second; | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
msg.cmd = 0x8 << 4; | msg.cmd = 0x8 << 4; | ||||
msg.data1 = note; | msg.data1 = note; | ||||
msg.data2 = 127; | msg.data2 = 127; | ||||
@@ -103,25 +103,25 @@ std::string Driver::getInputDeviceName(int deviceId) { | |||||
return ""; | return ""; | ||||
} | } | ||||
MidiInputDevice *Driver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
midi::InputDevice *Driver::subscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (deviceId != 0) | if (deviceId != 0) | ||||
return NULL; | return NULL; | ||||
device.subscribe(midiInput); | |||||
device.subscribe(input); | |||||
return &device; | return &device; | ||||
} | } | ||||
void Driver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
void Driver::unsubscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (deviceId != 0) | if (deviceId != 0) | ||||
return; | return; | ||||
device.unsubscribe(midiInput); | |||||
device.unsubscribe(input); | |||||
} | } | ||||
void init() { | void init() { | ||||
driver = new Driver; | driver = new Driver; | ||||
midiDriverAdd(DRIVER, driver); | |||||
midi::addDriver(DRIVER, driver); | |||||
} | } | ||||
void press(int key) { | void press(int key) { | ||||
@@ -65,6 +65,7 @@ int main(int argc, char *argv[]) { | |||||
asset::init(devMode); | asset::init(devMode); | ||||
logger::init(devMode); | logger::init(devMode); | ||||
tagsInit(); | tagsInit(); | ||||
midi::init(); | |||||
rtmidiInit(); | rtmidiInit(); | ||||
bridgeInit(); | bridgeInit(); | ||||
keyboard::init(); | keyboard::init(); | ||||
@@ -130,7 +131,7 @@ int main(int argc, char *argv[]) { | |||||
plugin::destroy(); | plugin::destroy(); | ||||
ui::destroy(); | ui::destroy(); | ||||
bridgeDestroy(); | bridgeDestroy(); | ||||
midiDestroy(); | |||||
midi::destroy(); | |||||
logger::destroy(); | logger::destroy(); | ||||
return 0; | return 0; | ||||
@@ -4,52 +4,53 @@ | |||||
namespace rack { | namespace rack { | ||||
namespace midi { | |||||
static std::vector<int> driverIds; | static std::vector<int> driverIds; | ||||
static std::map<int, MidiDriver*> drivers; | |||||
static std::map<int, Driver*> drivers; | |||||
//////////////////// | //////////////////// | ||||
// MidiDevice | |||||
// Device | |||||
//////////////////// | //////////////////// | ||||
void MidiInputDevice::subscribe(MidiInput *midiInput) { | |||||
subscribed.insert(midiInput); | |||||
void InputDevice::subscribe(Input *input) { | |||||
subscribed.insert(input); | |||||
} | } | ||||
void MidiInputDevice::unsubscribe(MidiInput *midiInput) { | |||||
// Remove MidiInput from subscriptions | |||||
auto it = subscribed.find(midiInput); | |||||
void InputDevice::unsubscribe(Input *input) { | |||||
// Remove Input from subscriptions | |||||
auto it = subscribed.find(input); | |||||
if (it != subscribed.end()) | if (it != subscribed.end()) | ||||
subscribed.erase(it); | subscribed.erase(it); | ||||
} | } | ||||
void MidiInputDevice::onMessage(MidiMessage message) { | |||||
for (MidiInput *midiInput : subscribed) { | |||||
midiInput->onMessage(message); | |||||
void InputDevice::onMessage(Message message) { | |||||
for (Input *input : subscribed) { | |||||
input->onMessage(message); | |||||
} | } | ||||
} | } | ||||
//////////////////// | //////////////////// | ||||
// MidiDriver | |||||
// Driver | |||||
//////////////////// | //////////////////// | ||||
//////////////////// | //////////////////// | ||||
// MidiIO | |||||
// IO | |||||
//////////////////// | //////////////////// | ||||
MidiIO::~MidiIO() { | |||||
IO::~IO() { | |||||
// Because of polymorphic destruction, descendants must call this in their own destructor | // Because of polymorphic destruction, descendants must call this in their own destructor | ||||
// setDriverId(-1); | // setDriverId(-1); | ||||
} | } | ||||
std::vector<int> MidiIO::getDriverIds() { | |||||
std::vector<int> IO::getDriverIds() { | |||||
return driverIds; | return driverIds; | ||||
} | } | ||||
std::string MidiIO::getDriverName(int driverId) { | |||||
std::string IO::getDriverName(int driverId) { | |||||
auto it = drivers.find(driverId); | auto it = drivers.find(driverId); | ||||
if (it == drivers.end()) | if (it == drivers.end()) | ||||
return ""; | return ""; | ||||
@@ -57,7 +58,7 @@ std::string MidiIO::getDriverName(int driverId) { | |||||
return it->second->getName(); | return it->second->getName(); | ||||
} | } | ||||
void MidiIO::setDriverId(int driverId) { | |||||
void IO::setDriverId(int driverId) { | |||||
// Destroy driver | // Destroy driver | ||||
setDeviceId(-1); | setDeviceId(-1); | ||||
if (driver) { | if (driver) { | ||||
@@ -73,14 +74,14 @@ void MidiIO::setDriverId(int driverId) { | |||||
} | } | ||||
} | } | ||||
std::string MidiIO::getChannelName(int channel) { | |||||
std::string IO::getChannelName(int channel) { | |||||
if (channel == -1) | if (channel == -1) | ||||
return "All channels"; | return "All channels"; | ||||
else | else | ||||
return string::f("Channel %d", channel + 1); | return string::f("Channel %d", channel + 1); | ||||
} | } | ||||
json_t *MidiIO::toJson() { | |||||
json_t *IO::toJson() { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_object_set_new(rootJ, "driver", json_integer(driverId)); | json_object_set_new(rootJ, "driver", json_integer(driverId)); | ||||
std::string deviceName = getDeviceName(deviceId); | std::string deviceName = getDeviceName(deviceId); | ||||
@@ -90,7 +91,7 @@ json_t *MidiIO::toJson() { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void MidiIO::fromJson(json_t *rootJ) { | |||||
void IO::fromJson(json_t *rootJ) { | |||||
json_t *driverJ = json_object_get(rootJ, "driver"); | json_t *driverJ = json_object_get(rootJ, "driver"); | ||||
if (driverJ) | if (driverJ) | ||||
setDriverId(json_integer_value(driverJ)); | setDriverId(json_integer_value(driverJ)); | ||||
@@ -113,34 +114,34 @@ void MidiIO::fromJson(json_t *rootJ) { | |||||
} | } | ||||
//////////////////// | //////////////////// | ||||
// MidiInput | |||||
// Input | |||||
//////////////////// | //////////////////// | ||||
MidiInput::MidiInput() { | |||||
Input::Input() { | |||||
if (driverIds.size() >= 1) { | if (driverIds.size() >= 1) { | ||||
setDriverId(driverIds[0]); | setDriverId(driverIds[0]); | ||||
} | } | ||||
} | } | ||||
MidiInput::~MidiInput() { | |||||
Input::~Input() { | |||||
setDriverId(-1); | setDriverId(-1); | ||||
} | } | ||||
std::vector<int> MidiInput::getDeviceIds() { | |||||
std::vector<int> Input::getDeviceIds() { | |||||
if (driver) { | if (driver) { | ||||
return driver->getInputDeviceIds(); | return driver->getInputDeviceIds(); | ||||
} | } | ||||
return {}; | return {}; | ||||
} | } | ||||
std::string MidiInput::getDeviceName(int deviceId) { | |||||
std::string Input::getDeviceName(int deviceId) { | |||||
if (driver) { | if (driver) { | ||||
return driver->getInputDeviceName(deviceId); | return driver->getInputDeviceName(deviceId); | ||||
} | } | ||||
return ""; | return ""; | ||||
} | } | ||||
void MidiInput::setDeviceId(int deviceId) { | |||||
void Input::setDeviceId(int deviceId) { | |||||
// Destroy device | // Destroy device | ||||
if (driver && this->deviceId >= 0) { | if (driver && this->deviceId >= 0) { | ||||
driver->unsubscribeInputDevice(this->deviceId, this); | driver->unsubscribeInputDevice(this->deviceId, this); | ||||
@@ -154,7 +155,7 @@ void MidiInput::setDeviceId(int deviceId) { | |||||
} | } | ||||
} | } | ||||
void MidiInputQueue::onMessage(MidiMessage message) { | |||||
void InputQueue::onMessage(Message message) { | |||||
// Filter channel | // Filter channel | ||||
if (channel >= 0) { | if (channel >= 0) { | ||||
if (message.status() != 0xf && message.channel() != channel) | if (message.status() != 0xf && message.channel() != channel) | ||||
@@ -166,7 +167,7 @@ void MidiInputQueue::onMessage(MidiMessage message) { | |||||
queue.push(message); | queue.push(message); | ||||
} | } | ||||
bool MidiInputQueue::shift(MidiMessage *message) { | |||||
bool InputQueue::shift(Message *message) { | |||||
if (!message) | if (!message) | ||||
return false; | return false; | ||||
if (!queue.empty()) { | if (!queue.empty()) { | ||||
@@ -178,17 +179,17 @@ bool MidiInputQueue::shift(MidiMessage *message) { | |||||
} | } | ||||
//////////////////// | //////////////////// | ||||
// MidiOutput | |||||
// Output | |||||
//////////////////// | //////////////////// | ||||
MidiOutput::MidiOutput() { | |||||
Output::Output() { | |||||
} | } | ||||
MidiOutput::~MidiOutput() { | |||||
Output::~Output() { | |||||
setDriverId(-1); | setDriverId(-1); | ||||
} | } | ||||
void MidiOutput::setDeviceId(int deviceId) { | |||||
void Output::setDeviceId(int deviceId) { | |||||
// TODO | // TODO | ||||
} | } | ||||
@@ -196,7 +197,10 @@ void MidiOutput::setDeviceId(int deviceId) { | |||||
// midi | // midi | ||||
//////////////////// | //////////////////// | ||||
void midiDestroy() { | |||||
void init() { | |||||
} | |||||
void destroy() { | |||||
driverIds.clear(); | driverIds.clear(); | ||||
for (auto &pair : drivers) { | for (auto &pair : drivers) { | ||||
delete pair.second; | delete pair.second; | ||||
@@ -204,11 +208,12 @@ void midiDestroy() { | |||||
drivers.clear(); | drivers.clear(); | ||||
} | } | ||||
void midiDriverAdd(int driverId, MidiDriver *driver) { | |||||
void addDriver(int driverId, Driver *driver) { | |||||
assert(driver); | assert(driver); | ||||
driverIds.push_back(driverId); | driverIds.push_back(driverId); | ||||
drivers[driverId] = driver; | drivers[driverId] = driver; | ||||
} | } | ||||
} // namespace midi | |||||
} // namespace rack | } // namespace rack |
@@ -11,7 +11,7 @@ static void midiInputCallback(double timeStamp, std::vector<unsigned char> *mess | |||||
RtMidiInputDevice *midiInputDevice = (RtMidiInputDevice*) userData; | RtMidiInputDevice *midiInputDevice = (RtMidiInputDevice*) userData; | ||||
if (!midiInputDevice) return; | if (!midiInputDevice) return; | ||||
MidiMessage msg; | |||||
midi::Message msg; | |||||
if (message->size() >= 1) | if (message->size() >= 1) | ||||
msg.cmd = (*message)[0]; | msg.cmd = (*message)[0]; | ||||
if (message->size() >= 2) | if (message->size() >= 2) | ||||
@@ -77,7 +77,7 @@ std::string RtMidiDriver::getInputDeviceName(int deviceId) { | |||||
return ""; | return ""; | ||||
} | } | ||||
MidiInputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
midi::InputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, midi::Input *input) { | |||||
if (!(0 <= deviceId && deviceId < (int) rtMidiIn->getPortCount())) | if (!(0 <= deviceId && deviceId < (int) rtMidiIn->getPortCount())) | ||||
return NULL; | return NULL; | ||||
RtMidiInputDevice *device = devices[deviceId]; | RtMidiInputDevice *device = devices[deviceId]; | ||||
@@ -85,16 +85,16 @@ MidiInputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, MidiInput *mid | |||||
devices[deviceId] = device = new RtMidiInputDevice(driverId, deviceId); | devices[deviceId] = device = new RtMidiInputDevice(driverId, deviceId); | ||||
} | } | ||||
device->subscribe(midiInput); | |||||
device->subscribe(input); | |||||
return device; | return device; | ||||
} | } | ||||
void RtMidiDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) { | |||||
void RtMidiDriver::unsubscribeInputDevice(int deviceId, midi::Input *input) { | |||||
auto it = devices.find(deviceId); | auto it = devices.find(deviceId); | ||||
if (it == devices.end()) | if (it == devices.end()) | ||||
return; | return; | ||||
RtMidiInputDevice *device = it->second; | RtMidiInputDevice *device = it->second; | ||||
device->unsubscribe(midiInput); | |||||
device->unsubscribe(input); | |||||
// Destroy device if nothing is subscribed anymore | // Destroy device if nothing is subscribed anymore | ||||
if (device->subscribed.empty()) { | if (device->subscribed.empty()) { | ||||
@@ -109,8 +109,8 @@ void rtmidiInit() { | |||||
RtMidi::getCompiledApi(rtApis); | RtMidi::getCompiledApi(rtApis); | ||||
for (RtMidi::Api api : rtApis) { | for (RtMidi::Api api : rtApis) { | ||||
int driverId = (int) api; | int driverId = (int) api; | ||||
MidiDriver *driver = new RtMidiDriver(driverId); | |||||
midiDriverAdd(driverId, driver); | |||||
midi::Driver *driver = new RtMidiDriver(driverId); | |||||
midi::addDriver(driverId, driver); | |||||
} | } | ||||
} | } | ||||