GetSourceSecOffset * * Gets the current read offset for the given Source, in seconds. The offset is * relative to the start of the queue (not the start of the current buffer). */
| 223 | * relative to the start of the queue (not the start of the current buffer). |
| 224 | */ |
| 225 | ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds *clocktime) |
| 226 | { |
| 227 | ALCdevice *device{context->mDevice.get()}; |
| 228 | const ALbufferlistitem *Current; |
| 229 | uint64_t readPos; |
| 230 | ALuint refcount; |
| 231 | ALvoice *voice; |
| 232 | |
| 233 | do { |
| 234 | Current = nullptr; |
| 235 | readPos = 0; |
| 236 | while(((refcount=device->MixCount.load(std::memory_order_acquire))&1)) |
| 237 | std::this_thread::yield(); |
| 238 | *clocktime = GetDeviceClockTime(device); |
| 239 | |
| 240 | voice = GetSourceVoice(Source, context); |
| 241 | if(voice) |
| 242 | { |
| 243 | Current = voice->mCurrentBuffer.load(std::memory_order_relaxed); |
| 244 | |
| 245 | readPos = uint64_t{voice->mPosition.load(std::memory_order_relaxed)} << FRACTIONBITS; |
| 246 | readPos |= voice->mPositionFrac.load(std::memory_order_relaxed); |
| 247 | } |
| 248 | std::atomic_thread_fence(std::memory_order_acquire); |
| 249 | } while(refcount != device->MixCount.load(std::memory_order_relaxed)); |
| 250 | |
| 251 | ALdouble offset{0.0}; |
| 252 | if(voice) |
| 253 | { |
| 254 | const ALbufferlistitem *BufferList{Source->queue}; |
| 255 | const ALbuffer *BufferFmt{nullptr}; |
| 256 | while(BufferList && BufferList != Current) |
| 257 | { |
| 258 | if(!BufferFmt) BufferFmt = BufferList->mBuffer; |
| 259 | readPos += uint64_t{BufferList->mSampleLen} << FRACTIONBITS; |
| 260 | BufferList = BufferList->mNext.load(std::memory_order_relaxed); |
| 261 | } |
| 262 | |
| 263 | while(BufferList && !BufferFmt) |
| 264 | { |
| 265 | BufferFmt = BufferList->mBuffer; |
| 266 | BufferList = BufferList->mNext.load(std::memory_order_relaxed); |
| 267 | } |
| 268 | assert(BufferFmt != nullptr); |
| 269 | |
| 270 | offset = static_cast<ALdouble>(readPos) / ALdouble{FRACTIONONE} / BufferFmt->Frequency; |
| 271 | } |
| 272 | |
| 273 | return offset; |
| 274 | } |
| 275 | |
| 276 | /* GetSourceOffset |
| 277 | * |
no test coverage detected