diff options
author | Chris Xiong <chirs241097@gmail.com> | 2020-12-14 14:07:49 +0800 |
---|---|---|
committer | Chris Xiong <chirs241097@gmail.com> | 2020-12-14 14:07:49 +0800 |
commit | 64fd118e1c5944befcf067a0e99d6d138c7559cb (patch) | |
tree | 71ff8b662c266dda6940b54fb45da642143532e0 /core/qmpmidiplay.cpp | |
parent | fcd13f9b227d80e066775f75b09bc6ec9337bfc8 (diff) | |
download | QMidiPlayer-64fd118e1c5944befcf067a0e99d6d138c7559cb.tar.xz |
Before we have tick-based playback, we get this monstrosity.
This should help fixing issues such as "welp my player freezes when I
switch tracks" etc.
Don't worry. Event-based playback is here to stay. TODOs:
- Maybe switch to an implementation based on condition variables?
Current implementation is just a mess and unnecessarily wastes
CPU time. Also that will allow several new interfaces to be added
(such as player.interrupt)
- Fix seeking. Seeking is still weird if there's a long gap between
events.
Diffstat (limited to 'core/qmpmidiplay.cpp')
-rw-r--r-- | core/qmpmidiplay.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index c987e01..99db420 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -236,17 +236,43 @@ void CMidiPlayer::playEvents() break; high_resolution_clock::time_point a = high_resolution_clock::now(); auto sendtime = a - b; - if (sendtime.count() < (getEvent(tceptr)->time - ct)*dpt) + if (sendtime.count() < (getEvent(tceptr)->time - ct) * dpt) { double ns_sleep = (getEvent(tceptr)->time - ct) * dpt - sendtime.count(); double correction = (getTick() - ttick) * dpt - (b - ttime).count(); if (correction > 0) correction = 0; + if (ns_sleep + correction > 2e8) + { + high_resolution_clock::time_point t = high_resolution_clock::now(); + uint64_t tts = uint64_t(ns_sleep + correction); + while (tts > 2e8 && !tcstop && midiReaders) + { +#ifdef _WIN32 + w32usleep(2e5); +#else + std::this_thread::sleep_for(std::chrono::nanoseconds(uint64_t(2e8))); +#endif + tts -= uint64_t((high_resolution_clock::now() - t).count()); + t = high_resolution_clock::now(); + } + if (tts > 0 && !tcstop && midiReaders) + { #ifdef _WIN32 - w32usleep((uint64_t)(((getEvent(tceptr)->time - ct)*dpt - sendtime.count()) / 1000)); + w32usleep(tts / 1000); #else - std::this_thread::sleep_for(std::chrono::nanoseconds((uint64_t)(ns_sleep + correction))); + std::this_thread::sleep_for(std::chrono::nanoseconds(tts)); #endif + } + } + else + { +#ifdef _WIN32 + w32usleep(uint64_t((ns_sleep + correction) / 1000))); +#else + std::this_thread::sleep_for(std::chrono::nanoseconds(uint64_t(ns_sleep + correction))); +#endif + } } if (tcstop || !midiReaders) break; |