diff options
author | Chris Robinson <[email protected]> | 2018-11-10 19:31:23 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-11-10 19:31:23 -0800 |
commit | 3939878cc0ac9e9043ee1cb30113136c2a8958e1 (patch) | |
tree | c849ba18da301724cfa3c7cecc343b2f5bb6edab /Alc/backends/null.cpp | |
parent | dc31969b04395db71d8162587f55cf81e7e69aac (diff) |
Use standard timing methods for the null and wave backends
Diffstat (limited to 'Alc/backends/null.cpp')
-rw-r--r-- | Alc/backends/null.cpp | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/Alc/backends/null.cpp b/Alc/backends/null.cpp index 2e1c6ac9..4c1d3956 100644 --- a/Alc/backends/null.cpp +++ b/Alc/backends/null.cpp @@ -25,6 +25,9 @@ #include <windows.h> #endif +#include <chrono> +#include <thread> + #include "alMain.h" #include "alu.h" #include "threads.h" @@ -35,6 +38,10 @@ namespace { +using std::chrono::seconds; +using std::chrono::milliseconds; +using std::chrono::nanoseconds; + constexpr ALCchar nullDevice[] = "No Output"; } // namespace @@ -82,48 +89,44 @@ static int ALCnullBackend_mixerProc(void *ptr) { ALCnullBackend *self = (ALCnullBackend*)ptr; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - struct timespec now, start; - ALuint64 avail, done; - const long restTime = (long)((ALuint64)device->UpdateSize * 1000000000 / - device->Frequency / 2); + const milliseconds restTime{device->UpdateSize*1000/device->Frequency / 2}; SetRTPriority(); althrd_setname(althrd_current(), MIXER_THREAD_NAME); - done = 0; - if(altimespec_get(&start, AL_TIME_UTC) != AL_TIME_UTC) - { - ERR("Failed to get starting time\n"); - return 1; - } + ALint64 done{0}; + auto start = std::chrono::steady_clock::now(); while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) && ATOMIC_LOAD(&device->Connected, almemory_order_acquire)) { - if(altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC) - { - ERR("Failed to get current time\n"); - return 1; - } + auto now = std::chrono::steady_clock::now(); - avail = (now.tv_sec - start.tv_sec) * device->Frequency; - avail += (ALint64)(now.tv_nsec - start.tv_nsec) * device->Frequency / 1000000000; - if(avail < done) + /* This converts from nanoseconds to nanosamples, then to samples. */ + ALint64 avail{std::chrono::duration_cast<seconds>((now-start) * device->Frequency).count()}; + if(avail-done < device->UpdateSize) { - /* Oops, time skipped backwards. Reset the number of samples done - * with one update available since we (likely) just came back from - * sleeping. */ - done = avail - device->UpdateSize; + std::this_thread::sleep_for(restTime); + continue; } - - if(avail-done < device->UpdateSize) - al_nssleep(restTime); - else while(avail-done >= device->UpdateSize) + while(avail-done >= device->UpdateSize) { ALCnullBackend_lock(self); - aluMixData(device, NULL, device->UpdateSize); + aluMixData(device, nullptr, device->UpdateSize); ALCnullBackend_unlock(self); done += device->UpdateSize; } + + /* For every completed second, increment the start time and reduce the + * samples done. This prevents the difference between the start time + * and current time from growing too large, while maintaining the + * correct number of samples to render. + */ + if(done >= device->Frequency) + { + seconds s{done/device->Frequency}; + start += s; + done -= device->Frequency*s.count(); + } } return 0; |