| @@ -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); | |||||
| } | } | ||||
| } | } | ||||