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 | |
parent | dc31969b04395db71d8162587f55cf81e7e69aac (diff) |
Use standard timing methods for the null and wave backends
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/backends/null.cpp | 57 | ||||
-rw-r--r-- | Alc/backends/wave.cpp | 61 |
2 files changed, 61 insertions, 57 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; diff --git a/Alc/backends/wave.cpp b/Alc/backends/wave.cpp index ec67342a..d5611783 100644 --- a/Alc/backends/wave.cpp +++ b/Alc/backends/wave.cpp @@ -25,6 +25,9 @@ #include <memory.h> #include <errno.h> +#include <chrono> +#include <thread> + #include "alMain.h" #include "alu.h" #include "alconfig.h" @@ -36,6 +39,10 @@ namespace { +using std::chrono::seconds; +using std::chrono::milliseconds; +using std::chrono::nanoseconds; + constexpr ALCchar waveDevice[] = "Wave File Writer"; constexpr ALubyte SUBTYPE_PCM[]{ @@ -131,45 +138,27 @@ static int ALCwaveBackend_mixerProc(void *ptr) { ALCwaveBackend *self = (ALCwaveBackend*)ptr; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - struct timespec now, start; - ALint64 avail, done; - ALuint frameSize; - size_t fs; - const long restTime = (long)((ALuint64)device->UpdateSize * 1000000000 / - device->Frequency / 2); + const milliseconds restTime{device->UpdateSize*1000/device->Frequency / 2}; althrd_setname(althrd_current(), MIXER_THREAD_NAME); - frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder); + ALsizei frameSize{FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder)}; - 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) { ALCwaveBackend_lock(self); aluMixData(device, self->mBuffer, device->UpdateSize); @@ -204,7 +193,7 @@ static int ALCwaveBackend_mixerProc(void *ptr) } } - fs = fwrite(self->mBuffer, frameSize, device->UpdateSize, self->mFile); + size_t fs{fwrite(self->mBuffer, frameSize, device->UpdateSize, self->mFile)}; (void)fs; if(ferror(self->mFile)) { @@ -215,6 +204,18 @@ static int ALCwaveBackend_mixerProc(void *ptr) break; } } + + /* 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; |