Browse Source

Implement midi::Output. Tweak midi API a bit

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
d7186474d3
10 changed files with 119 additions and 58 deletions
  1. +2
    -2
      include/bridge.hpp
  2. +2
    -2
      include/gamepad.hpp
  3. +2
    -2
      include/keyboard.hpp
  4. +43
    -23
      include/midi.hpp
  5. +2
    -2
      include/rtmidi.hpp
  6. +2
    -2
      src/bridge.cpp
  7. +2
    -2
      src/gamepad.cpp
  8. +2
    -2
      src/keyboard.cpp
  9. +60
    -19
      src/midi.cpp
  10. +2
    -2
      src/rtmidi.cpp

+ 2
- 2
include/bridge.hpp View File

@@ -17,8 +17,8 @@ struct BridgeMidiDriver : midi::Driver {

std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override;
void unsubscribeInputDevice(int deviceId, midi::Input *input) override;
midi::InputDevice *subscribeInput(int deviceId, midi::Input *input) override;
void unsubscribeInput(int deviceId, midi::Input *input) override;
};




+ 2
- 2
include/gamepad.hpp View File

@@ -22,8 +22,8 @@ struct Driver : midi::Driver {
std::string getName() override {return "Gamepad";}
std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override;
void unsubscribeInputDevice(int deviceId, midi::Input *input) override;
midi::InputDevice *subscribeInput(int deviceId, midi::Input *input) override;
void unsubscribeInput(int deviceId, midi::Input *input) override;
};




+ 2
- 2
include/keyboard.hpp View File

@@ -22,8 +22,8 @@ struct Driver : midi::Driver {

std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override;
void unsubscribeInputDevice(int deviceId, midi::Input *input) override;
midi::InputDevice *subscribeInput(int deviceId, midi::Input *input) override;
void unsubscribeInput(int deviceId, midi::Input *input) override;
};




+ 43
- 23
include/midi.hpp View File

@@ -29,6 +29,30 @@ struct Message {
}
};

////////////////////
// Driver
////////////////////

struct InputDevice;
struct Input;
struct OutputDevice;
struct Output;

struct Driver {
virtual ~Driver() {}
virtual std::string getName() {return "";}

virtual std::vector<int> getInputDeviceIds() {return {};}
virtual std::string getInputDeviceName(int deviceId) {return "";}
virtual InputDevice *subscribeInput(int deviceId, Input *input) {return NULL;}
virtual void unsubscribeInput(int deviceId, Input *input) {}

virtual std::vector<int> getOutputDeviceIds() {return {};}
virtual std::string getOutputDeviceName(int deviceId) {return "";}
virtual OutputDevice *subscribeOutput(int deviceId, Output *output) {return NULL;}
virtual void unsubscribeOutput(int deviceId, Output *output) {}
};

////////////////////
// Device
////////////////////
@@ -37,8 +61,6 @@ struct Device {
virtual ~Device() {}
};

struct Input;

struct InputDevice : Device {
std::set<Input*> subscribed;
void subscribe(Input *input);
@@ -47,26 +69,10 @@ struct InputDevice : Device {
};

struct OutputDevice : Device {
// TODO
};

////////////////////
// Driver
////////////////////

struct Driver {
virtual ~Driver() {}
virtual std::string getName() {return "";}

virtual std::vector<int> getInputDeviceIds() {return {};}
virtual std::string getInputDeviceName(int deviceId) {return "";}
virtual InputDevice *subscribeInputDevice(int deviceId, Input *input) {return NULL;}
virtual void unsubscribeInputDevice(int deviceId, Input *input) {}

// virtual std::vector<int> getOutputDeviceIds() = 0;
// virtual std::string getOutputDeviceName(int deviceId) = 0;
// virtual OutputDevice *subscribeOutputDevice(int deviceId, Output *midiOutput) = 0;
// virtual void unsubscribeOutputDevice(int deviceId, Output *midiOutput) = 0;
std::set<Output*> subscribed;
void subscribe(Output *input);
void unsubscribe(Output *input);
virtual void sendMessage(Message message) {}
};

////////////////////
@@ -85,7 +91,8 @@ struct IO {
/** Not owned */
Driver *driver = NULL;

virtual ~IO();
/** Remember to call setDriverId(-1) in subclass destructors. */
virtual ~IO() {}

std::vector<int> getDriverIds();
std::string getDriverName(int driverId);
@@ -96,12 +103,17 @@ struct IO {
virtual void setDeviceId(int deviceId) = 0;

std::string getChannelName(int channel);
void setChannel(int channel);

json_t *toJson();
void fromJson(json_t *rootJ);
};


struct Input : IO {
/** Not owned */
InputDevice *inputDevice = NULL;

Input();
~Input();

@@ -122,9 +134,17 @@ struct InputQueue : Input {


struct Output : IO {
/** Not owned */
OutputDevice *outputDevice = NULL;

Output();
~Output();

std::vector<int> getDeviceIds() override;
std::string getDeviceName(int deviceId) override;
void setDeviceId(int deviceId) override;

void sendMessage(Message message);
};




+ 2
- 2
include/rtmidi.hpp View File

@@ -34,8 +34,8 @@ struct RtMidiDriver : midi::Driver {
std::string getName() override;
std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
midi::InputDevice *subscribeInputDevice(int deviceId, midi::Input *input) override;
void unsubscribeInputDevice(int deviceId, midi::Input *input) override;
midi::InputDevice *subscribeInput(int deviceId, midi::Input *input) override;
void unsubscribeInput(int deviceId, midi::Input *input) override;
};




+ 2
- 2
src/bridge.cpp View File

@@ -386,7 +386,7 @@ std::string BridgeMidiDriver::getInputDeviceName(int deviceId) {
return string::f("Port %d", deviceId + 1);
}

midi::InputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, midi::Input *input) {
midi::InputDevice *BridgeMidiDriver::subscribeInput(int deviceId, midi::Input *input) {
if (!(0 <= deviceId && deviceId < 16))
return NULL;

@@ -394,7 +394,7 @@ midi::InputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, midi::In
return &devices[deviceId];
}

void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, midi::Input *input) {
void BridgeMidiDriver::unsubscribeInput(int deviceId, midi::Input *input) {
if (!(0 <= deviceId && deviceId < 16))
return;



+ 2
- 2
src/gamepad.cpp View File

@@ -82,7 +82,7 @@ std::string Driver::getInputDeviceName(int deviceId) {
return string::f(" %d (unavailable)", deviceId + 1);
}

midi::InputDevice *Driver::subscribeInputDevice(int deviceId, midi::Input *input) {
midi::InputDevice *Driver::subscribeInput(int deviceId, midi::Input *input) {
if (!(0 <= deviceId && deviceId < 16))
return NULL;

@@ -90,7 +90,7 @@ midi::InputDevice *Driver::subscribeInputDevice(int deviceId, midi::Input *input
return &devices[deviceId];
}

void Driver::unsubscribeInputDevice(int deviceId, midi::Input *input) {
void Driver::unsubscribeInput(int deviceId, midi::Input *input) {
if (!(0 <= deviceId && deviceId < 16))
return;



+ 2
- 2
src/keyboard.cpp View File

@@ -103,7 +103,7 @@ std::string Driver::getInputDeviceName(int deviceId) {
return "";
}

midi::InputDevice *Driver::subscribeInputDevice(int deviceId, midi::Input *input) {
midi::InputDevice *Driver::subscribeInput(int deviceId, midi::Input *input) {
if (deviceId != 0)
return NULL;

@@ -111,7 +111,7 @@ midi::InputDevice *Driver::subscribeInputDevice(int deviceId, midi::Input *input
return &device;
}

void Driver::unsubscribeInputDevice(int deviceId, midi::Input *input) {
void Driver::unsubscribeInput(int deviceId, midi::Input *input) {
if (deviceId != 0)
return;



+ 60
- 19
src/midi.cpp View File

@@ -7,6 +7,7 @@ namespace rack {
namespace midi {


/** Preserves the order of IDs */
static std::vector<int> driverIds;
static std::map<int, Driver*> drivers;

@@ -28,24 +29,28 @@ void InputDevice::unsubscribe(Input *input) {

void InputDevice::onMessage(Message message) {
for (Input *input : subscribed) {
input->onMessage(message);
// Filter channel
if (input->channel < 0 || message.status() == 0xf || message.channel() == input->channel) {
input->onMessage(message);
}
}
}

////////////////////
// Driver
////////////////////
void OutputDevice::subscribe(Output *output) {
subscribed.insert(output);
}

void OutputDevice::unsubscribe(Output *output) {
// Remove Output from subscriptions
auto it = subscribed.find(output);
if (it != subscribed.end())
subscribed.erase(it);
}

////////////////////
// IO
////////////////////

IO::~IO() {
// Because of polymorphic destruction, descendants must call this in their own destructor
// setDriverId(-1);
}

std::vector<int> IO::getDriverIds() {
return driverIds;
}
@@ -59,7 +64,7 @@ std::string IO::getDriverName(int driverId) {
}

void IO::setDriverId(int driverId) {
// Destroy driver
// Unset device and driver
setDeviceId(-1);
if (driver) {
driver = NULL;
@@ -81,6 +86,10 @@ std::string IO::getChannelName(int channel) {
return string::f("Channel %d", channel + 1);
}

void IO::setChannel(int channel) {
this->channel = channel;
}

json_t *IO::toJson() {
json_t *rootJ = json_object();
json_object_set_new(rootJ, "driver", json_integer(driverId));
@@ -118,6 +127,7 @@ void IO::fromJson(json_t *rootJ) {
////////////////////

Input::Input() {
// Set first driver as default
if (driverIds.size() >= 1) {
setDriverId(driverIds[0]);
}
@@ -144,24 +154,19 @@ std::string Input::getDeviceName(int deviceId) {
void Input::setDeviceId(int deviceId) {
// Destroy device
if (driver && this->deviceId >= 0) {
driver->unsubscribeInputDevice(this->deviceId, this);
driver->unsubscribeInput(this->deviceId, this);
inputDevice = NULL;
}
this->deviceId = -1;

// Create device
if (driver && deviceId >= 0) {
driver->subscribeInputDevice(deviceId, this);
inputDevice = driver->subscribeInput(deviceId, this);
this->deviceId = deviceId;
}
}

void InputQueue::onMessage(Message message) {
// Filter channel
if (channel >= 0) {
if (message.status() != 0xf && message.channel() != channel)
return;
}

// Push to queue
if ((int) queue.size() < queueMaxSize)
queue.push(message);
@@ -183,16 +188,52 @@ bool InputQueue::shift(Message *message) {
////////////////////

Output::Output() {
// Set first driver as default
if (driverIds.size() >= 1) {
setDriverId(driverIds[0]);
}
}

Output::~Output() {
setDriverId(-1);
}

std::vector<int> Output::getDeviceIds() {
if (driver) {
return driver->getOutputDeviceIds();
}
return {};
}

std::string Output::getDeviceName(int deviceId) {
if (driver) {
return driver->getOutputDeviceName(deviceId);
}
return "";
}

void Output::setDeviceId(int deviceId) {
// TODO
// Destroy device
if (driver && this->deviceId >= 0) {
driver->unsubscribeOutput(this->deviceId, this);
outputDevice = NULL;
}
this->deviceId = -1;

// Create device
if (driver && deviceId >= 0) {
outputDevice = driver->subscribeOutput(deviceId, this);
this->deviceId = deviceId;
}
}

void Output::sendMessage(Message message) {
if (outputDevice) {
outputDevice->sendMessage(message);
}
}


////////////////////
// midi
////////////////////


+ 2
- 2
src/rtmidi.cpp View File

@@ -77,7 +77,7 @@ std::string RtMidiDriver::getInputDeviceName(int deviceId) {
return "";
}

midi::InputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, midi::Input *input) {
midi::InputDevice *RtMidiDriver::subscribeInput(int deviceId, midi::Input *input) {
if (!(0 <= deviceId && deviceId < (int) rtMidiIn->getPortCount()))
return NULL;
RtMidiInputDevice *device = devices[deviceId];
@@ -89,7 +89,7 @@ midi::InputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, midi::Input
return device;
}

void RtMidiDriver::unsubscribeInputDevice(int deviceId, midi::Input *input) {
void RtMidiDriver::unsubscribeInput(int deviceId, midi::Input *input) {
auto it = devices.find(deviceId);
if (it == devices.end())
return;


Loading…
Cancel
Save