| 170 | } |
| 171 | |
| 172 | void runThread() { |
| 173 | system::setThreadName("RtMidi output"); |
| 174 | |
| 175 | std::unique_lock<decltype(mutex)> lock(mutex); |
| 176 | while (!stopped) { |
| 177 | if (messageQueue.empty()) { |
| 178 | // No messages. Wait on the CV to be notified. |
| 179 | cv.wait(lock); |
| 180 | } |
| 181 | else { |
| 182 | // Get earliest message |
| 183 | const MessageSchedule& ms = messageQueue.top(); |
| 184 | double duration = ms.timestamp - system::getTime(); |
| 185 | |
| 186 | // If we need to wait, release the lock and wait for the timeout or notify_one(). |
| 187 | // If the top message has a NAN timestamp, this condition is false and the message is sent immediately. |
| 188 | // Don't bother waiting if duration is close to zero. Just send the message immediately. 100 us is less than typical jitter for MIDI output devices. |
| 189 | if (duration > 1e-4) { |
| 190 | // If this returns std::cv_status::timeout, it does NOT imply that notify_one() was not called, so a new message may have been pushed. So we must always restart the loop and get the top message again. |
| 191 | cv.wait_for(lock, std::chrono::duration<double>(duration)); |
| 192 | continue; |
| 193 | } |
| 194 | |
| 195 | // Send and remove from queue |
| 196 | sendMessageNow(ms.message); |
| 197 | messageQueue.pop(); |
| 198 | } |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | void sendMessageNow(const midi::Message& message) { |
| 203 | try { |
nothing calls this directly
no test coverage detected