aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-01-31 00:11:50 -0800
committerChris Robinson <[email protected]>2019-02-04 21:22:43 -0800
commitb7b4cfae2b6e275ea360dfb163f504321f73f849 (patch)
tree1bc26f17719923eada9dde5250b2e35e847ba6c2
parent367191cbfb427528aee347024dbf978bee7f5cea (diff)
Fixed alffplay underrun recovery timing
-rw-r--r--examples/alffplay.cpp59
1 files changed, 26 insertions, 33 deletions
diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp
index 28b968e2..c51c5119 100644
--- a/examples/alffplay.cpp
+++ b/examples/alffplay.cpp
@@ -91,16 +91,17 @@ inline constexpr int64_t operator "" _i64(unsigned long long int n) noexcept { r
#define M_PI (3.14159265358979323846)
#endif
+using fixed32 = std::chrono::duration<int64_t,std::ratio<1,(1_i64<<32)>>;
using nanoseconds = std::chrono::nanoseconds;
using microseconds = std::chrono::microseconds;
using milliseconds = std::chrono::milliseconds;
using seconds = std::chrono::seconds;
using seconds_d64 = std::chrono::duration<double>;
-const std::string AppName("alffplay");
+const std::string AppName{"alffplay"};
-bool EnableDirectOut = false;
-bool EnableWideStereo = false;
+bool EnableDirectOut{false};
+bool EnableWideStereo{false};
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
LPALCGETINTEGER64VSOFT alcGetInteger64vSOFT;
@@ -115,20 +116,20 @@ LPALEVENTCONTROLSOFT alEventControlSOFT;
LPALEVENTCALLBACKSOFT alEventCallbackSOFT;
#endif
-const seconds AVNoSyncThreshold(10);
+const seconds AVNoSyncThreshold{10};
const milliseconds VideoSyncThreshold(10);
#define VIDEO_PICTURE_QUEUE_SIZE 16
-const seconds_d64 AudioSyncThreshold(0.03);
-const milliseconds AudioSampleCorrectionMax(50);
+const seconds_d64 AudioSyncThreshold{0.03};
+const milliseconds AudioSampleCorrectionMax{50};
/* Averaging filter coefficient for audio sync. */
#define AUDIO_DIFF_AVG_NB 20
-const double AudioAvgFilterCoeff = std::pow(0.01, 1.0/AUDIO_DIFF_AVG_NB);
+const double AudioAvgFilterCoeff{std::pow(0.01, 1.0/AUDIO_DIFF_AVG_NB)};
/* Per-buffer size, in time */
-const milliseconds AudioBufferTime(20);
+const milliseconds AudioBufferTime{20};
/* Buffer total size, in time (should be divisible by the buffer time) */
-const milliseconds AudioBufferTotalTime(800);
+const milliseconds AudioBufferTotalTime{800};
#define MAX_QUEUE_SIZE (15 * 1024 * 1024) /* Bytes of compressed data to keep queued */
@@ -419,15 +420,15 @@ nanoseconds AudioState::getClockNoLock()
// Get the current device clock time and latency.
auto device = alcGetContextsDevice(alcGetCurrentContext());
- ALCint64SOFT devtimes[2] = {0,0};
+ ALCint64SOFT devtimes[2]{0,0};
alcGetInteger64vSOFT(device, ALC_DEVICE_CLOCK_LATENCY_SOFT, 2, devtimes);
- auto latency = nanoseconds(devtimes[1]);
- auto device_time = nanoseconds(devtimes[0]);
+ auto latency = nanoseconds{devtimes[1]};
+ auto device_time = nanoseconds{devtimes[0]};
// The clock is simply the current device time relative to the recorded
// start time. We can also subtract the latency to get more a accurate
// position of where the audio device actually is in the output stream.
- return device_time - mDeviceStartTime - latency;
+ std::max(device_time - mDeviceStartTime - latency, nanoseconds::zero());
}
/* The source-based clock is based on 4 components:
@@ -445,12 +446,10 @@ nanoseconds AudioState::getClockNoLock()
* sample at OpenAL's current position, and subtracting the source latency
* from that gives the timestamp of the sample currently at the DAC.
*/
- nanoseconds pts = mCurrentPts;
+ nanoseconds pts{mCurrentPts};
if(mSource)
{
ALint64SOFT offset[2];
- ALint queued;
- ALint status;
/* NOTE: The source state must be checked last, in case an underrun
* occurs and the source stops between retrieving the offset+latency
@@ -461,9 +460,10 @@ nanoseconds AudioState::getClockNoLock()
{
ALint ioffset;
alGetSourcei(mSource, AL_SAMPLE_OFFSET, &ioffset);
- offset[0] = static_cast<ALint64SOFT>(ioffset) << 32;
+ offset[0] = ALint64SOFT{ioffset} << 32;
offset[1] = 0;
}
+ ALint queued, status;
alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued);
alGetSourcei(mSource, AL_SOURCE_STATE, &status);
@@ -473,16 +473,13 @@ nanoseconds AudioState::getClockNoLock()
* when it starts recovery. */
if(status != AL_STOPPED)
{
- using fixed32 = std::chrono::duration<int64_t,std::ratio<1,(1ll<<32)>>;
-
pts -= AudioBufferTime*queued;
pts += std::chrono::duration_cast<nanoseconds>(
- fixed32(offset[0] / mCodecCtx->sample_rate)
- );
+ fixed32{offset[0] / mCodecCtx->sample_rate});
}
/* Don't offset by the latency if the source isn't playing. */
if(status == AL_PLAYING)
- pts -= nanoseconds(offset[1]);
+ pts -= nanoseconds{offset[1]};
}
return std::max(pts, nanoseconds::zero());
@@ -503,16 +500,14 @@ void AudioState::startPlayback()
alSourcePlay(mSource);
if(alcGetInteger64vSOFT)
{
- using fixed32 = std::chrono::duration<int64_t,std::ratio<1,(1ll<<32)>>;
-
// Subtract the total buffer queue time from the current pts to get the
// pts of the start of the queue.
- nanoseconds startpts = mCurrentPts - AudioBufferTotalTime;
- int64_t srctimes[2]={0,0};
+ nanoseconds startpts{mCurrentPts - AudioBufferTotalTime};
+ int64_t srctimes[2]{0,0};
alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_CLOCK_SOFT, srctimes);
- auto device_time = nanoseconds(srctimes[1]);
- auto src_offset = std::chrono::duration_cast<nanoseconds>(fixed32(srctimes[0])) /
- mCodecCtx->sample_rate;
+ auto device_time = nanoseconds{srctimes[1]};
+ auto src_offset = std::chrono::duration_cast<nanoseconds>(fixed32{srctimes[0]}) /
+ mCodecCtx->sample_rate;
// The mixer may have ticked and incremented the device time and sample
// offset, so subtract the source offset from the device time to get
@@ -1068,10 +1063,8 @@ int AudioState::handler()
*/
int64_t devtime{};
alcGetInteger64vSOFT(alcGetContextsDevice(alcGetCurrentContext()),
- ALC_DEVICE_CLOCK_SOFT, 1, &devtime);
- auto device_time = nanoseconds{devtime};
-
- mDeviceStartTime = device_time - mCurrentPts + AudioBufferTotalTime;
+ ALC_DEVICE_CLOCK_SOFT, 1, &devtime);
+ mDeviceStartTime = nanoseconds{devtime} - mCurrentPts;
}
continue;
}