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::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) 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::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;
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::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) 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 // Device
//////////////////// ////////////////////
@@ -37,8 +61,6 @@ struct Device {
virtual ~Device() {} virtual ~Device() {}
}; };


struct Input;

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


struct OutputDevice : 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 */ /** Not owned */
Driver *driver = NULL; Driver *driver = NULL;


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


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


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

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




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

Input(); Input();
~Input(); ~Input();


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




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

Output(); Output();
~Output(); ~Output();

std::vector<int> getDeviceIds() override;
std::string getDeviceName(int deviceId) override;
void setDeviceId(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::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;
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); 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)) if (!(0 <= deviceId && deviceId < 16))
return NULL; return NULL;


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


void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, midi::Input *input) {
void BridgeMidiDriver::unsubscribeInput(int deviceId, midi::Input *input) {
if (!(0 <= deviceId && deviceId < 16)) if (!(0 <= deviceId && deviceId < 16))
return; 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); 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)) if (!(0 <= deviceId && deviceId < 16))
return NULL; return NULL;


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


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




+ 2
- 2
src/keyboard.cpp View File

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


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


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


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




+ 60
- 19
src/midi.cpp View File

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




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


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


void InputDevice::onMessage(Message message) { void InputDevice::onMessage(Message message) {
for (Input *input : subscribed) { 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::~IO() {
// Because of polymorphic destruction, descendants must call this in their own destructor
// setDriverId(-1);
}

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


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


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

json_t *IO::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));
@@ -118,6 +127,7 @@ void IO::fromJson(json_t *rootJ) {
//////////////////// ////////////////////


Input::Input() { Input::Input() {
// Set first driver as default
if (driverIds.size() >= 1) { if (driverIds.size() >= 1) {
setDriverId(driverIds[0]); setDriverId(driverIds[0]);
} }
@@ -144,24 +154,19 @@ std::string Input::getDeviceName(int deviceId) {
void Input::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->unsubscribeInput(this->deviceId, this);
inputDevice = NULL;
} }
this->deviceId = -1; this->deviceId = -1;


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


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

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


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


Output::~Output() { Output::~Output() {
setDriverId(-1); 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) { 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 // midi
//////////////////// ////////////////////


+ 2
- 2
src/rtmidi.cpp View File

@@ -77,7 +77,7 @@ std::string RtMidiDriver::getInputDeviceName(int deviceId) {
return ""; 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())) if (!(0 <= deviceId && deviceId < (int) rtMidiIn->getPortCount()))
return NULL; return NULL;
RtMidiInputDevice *device = devices[deviceId]; RtMidiInputDevice *device = devices[deviceId];
@@ -89,7 +89,7 @@ midi::InputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, midi::Input
return device; return device;
} }


void RtMidiDriver::unsubscribeInputDevice(int deviceId, midi::Input *input) {
void RtMidiDriver::unsubscribeInput(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;


Loading…
Cancel
Save