Stop using MIDI drivers and ports completely
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
cb26617890
commit
d3584b0567
3 changed files with 5 additions and 212 deletions
209
include/midi.hpp
209
include/midi.hpp
|
@ -117,213 +117,10 @@ struct Message {
|
|||
}
|
||||
};
|
||||
|
||||
////////////////////
|
||||
// Driver
|
||||
////////////////////
|
||||
|
||||
struct InputDevice;
|
||||
struct Input;
|
||||
struct OutputDevice;
|
||||
struct Output;
|
||||
|
||||
/** Wraps a MIDI driver API containing any number of MIDI devices.
|
||||
*/
|
||||
struct Driver {
|
||||
virtual ~Driver() {}
|
||||
/** Returns the name of the driver. E.g. "ALSA". */
|
||||
virtual std::string getName() {
|
||||
return "";
|
||||
}
|
||||
/** Returns a list of all input device IDs that can be subscribed to. */
|
||||
virtual std::vector<int> getInputDeviceIds() {
|
||||
return {};
|
||||
}
|
||||
/** Returns the default device to use when the driver is selected, or -1 for none. */
|
||||
virtual int getDefaultInputDeviceId() {
|
||||
return -1;
|
||||
}
|
||||
/** Returns the name of an input device without obtaining it. */
|
||||
virtual std::string getInputDeviceName(int deviceId) {
|
||||
return "";
|
||||
}
|
||||
/** Adds the given port as a reference holder of a device and returns the it.
|
||||
Creates the Device if no ports are subscribed before calling.
|
||||
*/
|
||||
virtual InputDevice* subscribeInput(int deviceId, Input* input) {
|
||||
return NULL;
|
||||
}
|
||||
/** Removes the give port as a reference holder of a device.
|
||||
Deletes the Device if no ports are subscribed after calling.
|
||||
*/
|
||||
virtual void unsubscribeInput(int deviceId, Input* input) {}
|
||||
|
||||
// The following behave identically as the above methods except for outputs.
|
||||
|
||||
virtual std::vector<int> getOutputDeviceIds() {
|
||||
return {};
|
||||
}
|
||||
virtual int getDefaultOutputDeviceId() {
|
||||
return -1;
|
||||
}
|
||||
virtual std::string getOutputDeviceName(int deviceId) {
|
||||
return "";
|
||||
}
|
||||
virtual OutputDevice* subscribeOutput(int deviceId, Output* output) {
|
||||
return NULL;
|
||||
}
|
||||
virtual void unsubscribeOutput(int deviceId, Output* output) {}
|
||||
};
|
||||
|
||||
////////////////////
|
||||
// Device
|
||||
////////////////////
|
||||
|
||||
/** A single MIDI device of a driver API.
|
||||
|
||||
Modules and the UI should not interact with this API directly. Use Port instead.
|
||||
|
||||
Methods throw `rack::Exception` if the driver API has an exception.
|
||||
*/
|
||||
struct Device {
|
||||
virtual ~Device() {}
|
||||
virtual std::string getName() {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
struct InputDevice : Device {
|
||||
std::set<Input*> subscribed;
|
||||
/** Not public. Use Driver::subscribeInput(). */
|
||||
void subscribe(Input* input);
|
||||
/** Not public. Use Driver::unsubscribeInput(). */
|
||||
void unsubscribe(Input* input);
|
||||
/** Called when a MIDI message is received from the device. */
|
||||
void onMessage(const Message& message);
|
||||
};
|
||||
|
||||
struct OutputDevice : Device {
|
||||
std::set<Output*> subscribed;
|
||||
/** Not public. Use Driver::subscribeOutput(). */
|
||||
void subscribe(Output* output);
|
||||
/** Not public. Use Driver::unsubscribeOutput(). */
|
||||
void unsubscribe(Output* output);
|
||||
/** Sends a MIDI message to the device. */
|
||||
virtual void sendMessage(const Message& message) {}
|
||||
};
|
||||
|
||||
////////////////////
|
||||
// Port
|
||||
////////////////////
|
||||
|
||||
/** A handle to a Device, typically owned by modules to have shared access to a single Device.
|
||||
|
||||
All Port methods safely wrap Drivers methods.
|
||||
That is, if the active Device throws a `rack::Exception`, it is caught and logged inside all Port methods, so they do not throw exceptions.
|
||||
|
||||
Use Input or Output subclasses in your module, not Port directly.
|
||||
*/
|
||||
struct Port {
|
||||
/** For MIDI output, the channel to automatically set outbound messages.
|
||||
If -1, the channel is not overwritten and must be set by MIDI generator.
|
||||
|
||||
For MIDI input, messages will be filtered by the channel.
|
||||
If -1, all MIDI channels pass through.
|
||||
*/
|
||||
int channel = -1;
|
||||
|
||||
// private
|
||||
int driverId = -1;
|
||||
int deviceId = -1;
|
||||
/** Not owned */
|
||||
Driver* driver = NULL;
|
||||
Device* device = NULL;
|
||||
Context* context;
|
||||
|
||||
Port();
|
||||
virtual ~Port();
|
||||
|
||||
Driver* getDriver();
|
||||
int getDriverId();
|
||||
void setDriverId(int driverId);
|
||||
|
||||
Device* getDevice();
|
||||
virtual std::vector<int> getDeviceIds() = 0;
|
||||
virtual int getDefaultDeviceId() = 0;
|
||||
int getDeviceId();
|
||||
virtual void setDeviceId(int deviceId) = 0;
|
||||
virtual std::string getDeviceName(int deviceId) = 0;
|
||||
|
||||
virtual std::vector<int> getChannels() = 0;
|
||||
int getChannel();
|
||||
void setChannel(int channel);
|
||||
std::string getChannelName(int channel);
|
||||
|
||||
json_t* toJson();
|
||||
void fromJson(json_t* rootJ);
|
||||
};
|
||||
|
||||
|
||||
struct Input : Port {
|
||||
/** Not owned */
|
||||
InputDevice* inputDevice = NULL;
|
||||
|
||||
Input();
|
||||
~Input();
|
||||
void reset();
|
||||
|
||||
std::vector<int> getDeviceIds() override;
|
||||
int getDefaultDeviceId() override;
|
||||
void setDeviceId(int deviceId) override;
|
||||
std::string getDeviceName(int deviceId) override;
|
||||
|
||||
std::vector<int> getChannels() override;
|
||||
|
||||
virtual void onMessage(const Message& message) {}
|
||||
};
|
||||
|
||||
|
||||
/** An Input port that stores incoming MIDI messages and releases them when ready according to their frame timestamp.
|
||||
*/
|
||||
struct InputQueue : Input {
|
||||
struct Internal;
|
||||
Internal* internal;
|
||||
|
||||
InputQueue();
|
||||
~InputQueue();
|
||||
void onMessage(const Message& message) override;
|
||||
/** Pops and returns the next message (by setting `messageOut`) if its frame timestamp is `maxFrame` or earlier.
|
||||
Returns whether a message was returned.
|
||||
*/
|
||||
bool tryPop(Message* messageOut, int64_t maxFrame);
|
||||
size_t size();
|
||||
};
|
||||
|
||||
|
||||
struct Output : Port {
|
||||
/** Not owned */
|
||||
OutputDevice* outputDevice = NULL;
|
||||
|
||||
Output();
|
||||
~Output();
|
||||
void reset();
|
||||
|
||||
std::vector<int> getDeviceIds() override;
|
||||
int getDefaultDeviceId() override;
|
||||
void setDeviceId(int deviceId) override;
|
||||
std::string getDeviceName(int deviceId) override;
|
||||
|
||||
std::vector<int> getChannels() override;
|
||||
|
||||
void sendMessage(const Message& message);
|
||||
};
|
||||
|
||||
|
||||
PRIVATE void init();
|
||||
PRIVATE void destroy();
|
||||
/** Registers a new MIDI driver. Takes pointer ownership. */
|
||||
void addDriver(int driverId, Driver* driver);
|
||||
std::vector<int> getDriverIds();
|
||||
Driver* getDriver(int driverId);
|
||||
/* NOTE all the other MIDI stuff (drivers, ports etc) is purposefully missing here, unwanted in Cardinal
|
||||
*/
|
||||
struct Port;
|
||||
|
||||
|
||||
} // namespace midi
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue