|
@@ -225,7 +225,13 @@ std::vector<int> Input::getDeviceIds() { |
|
|
int Input::getDefaultDeviceId() { |
|
|
int Input::getDefaultDeviceId() { |
|
|
if (!driver) |
|
|
if (!driver) |
|
|
return -1; |
|
|
return -1; |
|
|
return driver->getDefaultInputDeviceId(); |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
return driver->getDefaultInputDeviceId(); |
|
|
|
|
|
} |
|
|
|
|
|
catch (Exception& e) { |
|
|
|
|
|
WARN("MIDI port get default input device ID: %s", e.what()); |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Input::setDeviceId(int deviceId) { |
|
|
void Input::setDeviceId(int deviceId) { |
|
@@ -311,6 +317,7 @@ InputQueue::~InputQueue() { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void InputQueue::onMessage(const Message& message) { |
|
|
void InputQueue::onMessage(const Message& message) { |
|
|
|
|
|
// Reject MIDI message if queue is full |
|
|
if (internal->queue.size() >= InputQueue_maxSize) |
|
|
if (internal->queue.size() >= InputQueue_maxSize) |
|
|
return; |
|
|
return; |
|
|
// Push to queue |
|
|
// Push to queue |
|
@@ -318,20 +325,21 @@ void InputQueue::onMessage(const Message& message) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool InputQueue::tryPop(Message* messageOut, int64_t maxFrame) { |
|
|
bool InputQueue::tryPop(Message* messageOut, int64_t maxFrame) { |
|
|
if (!internal->queue.empty()) { |
|
|
|
|
|
const Message& msg = internal->queue.top(); |
|
|
|
|
|
if (msg.getFrame() <= maxFrame) { |
|
|
|
|
|
*messageOut = msg; |
|
|
|
|
|
internal->queue.pop(); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (internal->queue.empty()) |
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
const Message& msg = internal->queue.top(); |
|
|
|
|
|
if (msg.getFrame() <= maxFrame) { |
|
|
|
|
|
*messageOut = msg; |
|
|
|
|
|
internal->queue.pop(); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// If next MIDI message is too far in the future, clear the queue. |
|
|
|
|
|
// This solves the issue of unconsumed messages getting stuck in the future when a DAW rewinds the engine frame. |
|
|
|
|
|
int futureFrames = 2 * APP->engine->getBlockFrames(); |
|
|
|
|
|
if (msg.getFrame() - maxFrame > futureFrames) { |
|
|
|
|
|
internal->queue.clear(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// If next MIDI message is too far in the future, clear the queue. |
|
|
|
|
|
// This solves the issue of unconsumed messages getting stuck in the future when a DAW rewinds the engine frame. |
|
|
|
|
|
int futureFrames = 2 * APP->engine->getBlockFrames(); |
|
|
|
|
|
if (msg.getFrame() - maxFrame > futureFrames) { |
|
|
|
|
|
internal->queue.clear(); |
|
|
} |
|
|
} |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
@@ -400,7 +408,13 @@ void Output::setDeviceId(int deviceId) { |
|
|
int Output::getDefaultDeviceId() { |
|
|
int Output::getDefaultDeviceId() { |
|
|
if (!driver) |
|
|
if (!driver) |
|
|
return -1; |
|
|
return -1; |
|
|
return driver->getDefaultOutputDeviceId(); |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
return driver->getDefaultOutputDeviceId(); |
|
|
|
|
|
} |
|
|
|
|
|
catch (Exception& e) { |
|
|
|
|
|
WARN("MIDI port get default output device ID: %s", e.what()); |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::string Output::getDeviceName(int deviceId) { |
|
|
std::string Output::getDeviceName(int deviceId) { |
|
|