aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
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
parentdc31969b04395db71d8162587f55cf81e7e69aac (diff)
Use standard timing methods for the null and wave backends
Diffstat (limited to 'Alc')
-rw-r--r--Alc/backends/null.cpp57
-rw-r--r--Alc/backends/wave.cpp61
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;