@@ -34,6 +34,10 @@ struct Driver { | |||
virtual std::vector<int> getDeviceIds() { | |||
return {}; | |||
} | |||
/** Returns the default device to use when the driver is selected, or -1 for none. */ | |||
virtual int getDefaultDeviceId() { | |||
return -1; | |||
} | |||
/** Returns the name of a device without obtaining it. */ | |||
virtual std::string getDeviceName(int deviceId) { | |||
return ""; | |||
@@ -194,7 +198,9 @@ struct Port { | |||
void init(); | |||
void destroy(); | |||
/** Registers a new audio driver. Takes pointer ownership. */ | |||
/** Registers a new audio driver. Takes pointer ownership. | |||
Driver ID is stored in patches and must be unique. -1 is reserved. | |||
*/ | |||
void addDriver(int driverId, Driver* driver); | |||
std::vector<int> getDriverIds(); | |||
Driver* getDriver(int driverId); | |||
@@ -104,6 +104,10 @@ struct Driver { | |||
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 ""; | |||
@@ -124,6 +128,9 @@ struct Driver { | |||
virtual std::vector<int> getOutputDeviceIds() { | |||
return {}; | |||
} | |||
virtual int getDefaultOutputDeviceId() { | |||
return -1; | |||
} | |||
virtual std::string getOutputDeviceName(int deviceId) { | |||
return ""; | |||
} | |||
@@ -207,6 +214,7 @@ struct Port { | |||
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; | |||
@@ -230,6 +238,7 @@ struct Input : Port { | |||
void reset(); | |||
std::vector<int> getDeviceIds() override; | |||
int getDefaultDeviceId() override; | |||
void setDeviceId(int deviceId) override; | |||
std::string getDeviceName(int deviceId) override; | |||
@@ -255,6 +264,7 @@ struct Output : Port { | |||
void reset(); | |||
std::vector<int> getDeviceIds() override; | |||
int getDefaultDeviceId() override; | |||
void setDeviceId(int deviceId) override; | |||
std::string getDeviceName(int deviceId) override; | |||
@@ -70,17 +70,12 @@ Port::Port() { | |||
} | |||
Port::~Port() { | |||
setDriverId(-1); | |||
setDeviceId(-1); | |||
} | |||
void Port::reset() { | |||
// Get default driver | |||
int firstDriverId = -1; | |||
std::vector<int> driverIds = getDriverIds(); | |||
if (!driverIds.empty()) | |||
firstDriverId = driverIds[0]; | |||
setDriverId(firstDriverId); | |||
// Set default driver | |||
setDriverId(-1); | |||
} | |||
Driver* Port::getDriver() { | |||
@@ -92,8 +87,6 @@ int Port::getDriverId() { | |||
} | |||
void Port::setDriverId(int driverId) { | |||
if (driverId == this->driverId) | |||
return; | |||
// Unset device and driver | |||
setDeviceId(-1); | |||
driver = NULL; | |||
@@ -104,11 +97,20 @@ void Port::setDriverId(int driverId) { | |||
if (driver) { | |||
this->driverId = driverId; | |||
} | |||
else { | |||
else if (!drivers.empty()) { | |||
// Set first driver as default | |||
driver = drivers[0].second; | |||
this->driverId = drivers[0].first; | |||
} | |||
else { | |||
// No fallback drivers | |||
return; | |||
} | |||
// Set default device if exists | |||
int defaultDeviceId = driver->getDefaultDeviceId(); | |||
if (defaultDeviceId >= 0) | |||
setDeviceId(defaultDeviceId); | |||
} | |||
std::string Port::getDriverName() { | |||
@@ -165,8 +167,10 @@ void Port::setDeviceId(int deviceId) { | |||
if (deviceId >= 0) { | |||
try { | |||
device = driver->subscribe(deviceId, this); | |||
this->deviceId = deviceId; | |||
onStartStream(); | |||
if (device) { | |||
this->deviceId = deviceId; | |||
onStartStream(); | |||
} | |||
} | |||
catch (Exception& e) { | |||
WARN("Audio port could not subscribe to device: %s", e.what()); | |||
@@ -375,6 +379,7 @@ void destroy() { | |||
void addDriver(int driverId, Driver* driver) { | |||
assert(driver); | |||
assert(driverId != -1); | |||
drivers.push_back(std::make_pair(driverId, driver)); | |||
} | |||
@@ -387,6 +392,8 @@ std::vector<int> getDriverIds() { | |||
} | |||
Driver* getDriver(int driverId) { | |||
if (driverId == -1) | |||
return NULL; | |||
// Search for driver by ID | |||
for (auto& pair : drivers) { | |||
if (pair.first == driverId) | |||
@@ -100,20 +100,25 @@ struct Driver : midi::Driver { | |||
return deviceIds; | |||
} | |||
int getDefaultInputDeviceId() override { | |||
return 0; | |||
} | |||
std::string getInputDeviceName(int deviceId) override { | |||
if (!(0 <= deviceId && deviceId < 16)) | |||
return ""; | |||
const char* name = glfwGetJoystickName(deviceId); | |||
if (name) { | |||
return name; | |||
} | |||
return string::f(" %d (unavailable)", deviceId + 1); | |||
if (!name) | |||
return string::f("#%d (unavailable)", deviceId + 1); | |||
return name; | |||
} | |||
midi::InputDevice* subscribeInput(int deviceId, midi::Input* input) override { | |||
if (!(0 <= deviceId && deviceId < 16)) | |||
return NULL; | |||
if (!glfwJoystickPresent(deviceId)) | |||
return NULL; | |||
devices[deviceId].subscribe(input); | |||
return &devices[deviceId]; | |||
@@ -230,6 +230,11 @@ struct Driver : midi::Driver { | |||
return deviceIds; | |||
} | |||
int getDefaultInputDeviceId() override { | |||
// QWERTY keyboard device | |||
return 0; | |||
} | |||
midi::InputDevice* getInputDevice(int deviceId) { | |||
if (deviceId == MOUSE_DEVICE_ID) | |||
return &mouseDevice; | |||
@@ -112,11 +112,20 @@ void Port::setDriverId(int driverId) { | |||
if (driver) { | |||
this->driverId = driverId; | |||
} | |||
else { | |||
else if (!drivers.empty()) { | |||
// Set first driver as default | |||
driver = drivers[0].second; | |||
this->driverId = drivers[0].first; | |||
} | |||
else { | |||
// No fallback drivers | |||
return; | |||
} | |||
// Set default device if exists | |||
int defaultDeviceId = getDefaultDeviceId(); | |||
if (defaultDeviceId >= 0) | |||
setDeviceId(defaultDeviceId); | |||
} | |||
Device* Port::getDevice() { | |||
@@ -191,7 +200,7 @@ Input::Input() { | |||
} | |||
Input::~Input() { | |||
setDriverId(-1); | |||
setDeviceId(-1); | |||
} | |||
void Input::reset() { | |||
@@ -211,6 +220,12 @@ std::vector<int> Input::getDeviceIds() { | |||
} | |||
} | |||
int Input::getDefaultDeviceId() { | |||
if (!driver) | |||
return -1; | |||
return driver->getDefaultInputDeviceId(); | |||
} | |||
void Input::setDeviceId(int deviceId) { | |||
// Destroy device | |||
if (driver && this->deviceId >= 0) { | |||
@@ -228,7 +243,9 @@ void Input::setDeviceId(int deviceId) { | |||
if (driver && deviceId >= 0) { | |||
try { | |||
device = inputDevice = driver->subscribeInput(deviceId, this); | |||
this->deviceId = deviceId; | |||
if (device) { | |||
this->deviceId = deviceId; | |||
} | |||
} | |||
catch (Exception& e) { | |||
WARN("MIDI port could not subscribe to input: %s", e.what()); | |||
@@ -272,7 +289,7 @@ Output::Output() { | |||
} | |||
Output::~Output() { | |||
setDriverId(-1); | |||
setDeviceId(-1); | |||
} | |||
void Output::reset() { | |||
@@ -309,7 +326,9 @@ void Output::setDeviceId(int deviceId) { | |||
if (driver && deviceId >= 0) { | |||
try { | |||
device = outputDevice = driver->subscribeOutput(deviceId, this); | |||
this->deviceId = deviceId; | |||
if (device) { | |||
this->deviceId = deviceId; | |||
} | |||
} | |||
catch (Exception& e) { | |||
WARN("MIDI port could not subscribe to output: %s", e.what()); | |||
@@ -317,6 +336,12 @@ void Output::setDeviceId(int deviceId) { | |||
} | |||
} | |||
int Output::getDefaultDeviceId() { | |||
if (!driver) | |||
return -1; | |||
return driver->getDefaultOutputDeviceId(); | |||
} | |||
std::string Output::getDeviceName(int deviceId) { | |||
if (!driver) | |||
return ""; | |||