aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/null.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-10 19:31:23 -0800
committerChris Robinson <[email protected]>2018-11-10 19:31:23 -0800
commit3939878cc0ac9e9043ee1cb30113136c2a8958e1 (patch)
treec849ba18da301724cfa3c7cecc343b2f5bb6edab /Alc/backends/null.cpp
parentdc31969b04395db71d8162587f55cf81e7e69aac (diff)
Use standard timing methods for the null and wave backends
Diffstat (limited to 'Alc/backends/null.cpp')
-rw-r--r--Alc/backends/null.cpp57
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;