aboutsummaryrefslogtreecommitdiffstats
path: root/al/source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'al/source.cpp')
-rw-r--r--al/source.cpp97
1 files changed, 40 insertions, 57 deletions
diff --git a/al/source.cpp b/al/source.cpp
index 9bae27a5..1b5aa851 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -377,96 +377,79 @@ ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context)
}
-/* GetSampleOffset
+struct VoicePos {
+ ALuint pos, frac;
+ ALbufferlistitem *bufferitem;
+};
+
+/**
+ * GetSampleOffset
*
- * Retrieves the sample offset into the Source's queue (from the Sample, Byte
- * or Second offset supplied by the application). This takes into account the
- * fact that the buffer format may have been modifed since.
+ * Retrieves the voice position, fixed-point fraction, and bufferlist item
+ * using the source's stored offset and offset type. If the source has no
+ * stored offset, or the offset is out of range, returns an empty optional.
*/
-bool GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac)
+al::optional<VoicePos> GetSampleOffset(ALsource *Source)
{
- const ALbuffer *BufferFmt{nullptr};
- const ALbufferlistitem *BufferList;
-
+ al::optional<VoicePos> ret;
+
/* Find the first valid Buffer in the Queue */
- BufferList = Source->queue;
- while(BufferList && !BufferFmt)
+ const ALbuffer *BufferFmt{nullptr};
+ ALbufferlistitem *BufferList{Source->queue};
+ while(BufferList)
{
- BufferFmt = BufferList->mBuffer;
+ if((BufferFmt=BufferList->mBuffer) != nullptr) break;
BufferList = BufferList->mNext.load(std::memory_order_relaxed);
}
- if(!BufferFmt)
+ if(!BufferList)
{
Source->OffsetType = AL_NONE;
Source->Offset = 0.0;
- return false;
+ return ret;
}
+ /* Get sample frame offset */
+ ALuint offset{0u}, frac{0u};
ALdouble dbloff, dblfrac;
switch(Source->OffsetType)
{
case AL_BYTE_OFFSET:
/* Determine the ByteOffset (and ensure it is block aligned) */
- *offset = static_cast<ALuint>(Source->Offset);
+ offset = static_cast<ALuint>(Source->Offset);
if(BufferFmt->OriginalType == UserFmtIMA4)
{
- ALsizei align = (BufferFmt->OriginalAlign-1)/2 + 4;
- *offset /= align * ChannelsFromFmt(BufferFmt->mFmtChannels);
- *offset *= BufferFmt->OriginalAlign;
+ const ALsizei align{(BufferFmt->OriginalAlign-1)/2 + 4};
+ offset /= align * ChannelsFromFmt(BufferFmt->mFmtChannels);
+ offset *= BufferFmt->OriginalAlign;
}
else if(BufferFmt->OriginalType == UserFmtMSADPCM)
{
- ALsizei align = (BufferFmt->OriginalAlign-2)/2 + 7;
- *offset /= align * ChannelsFromFmt(BufferFmt->mFmtChannels);
- *offset *= BufferFmt->OriginalAlign;
+ const ALsizei align{(BufferFmt->OriginalAlign-2)/2 + 7};
+ offset /= align * ChannelsFromFmt(BufferFmt->mFmtChannels);
+ offset *= BufferFmt->OriginalAlign;
}
else
- *offset /= FrameSizeFromFmt(BufferFmt->mFmtChannels, BufferFmt->mFmtType);
- *frac = 0;
+ offset /= FrameSizeFromFmt(BufferFmt->mFmtChannels, BufferFmt->mFmtType);
+ frac = 0;
break;
case AL_SAMPLE_OFFSET:
- dblfrac = modf(Source->Offset, &dbloff);
- *offset = static_cast<ALuint>(mind(dbloff, std::numeric_limits<ALuint>::max()));
- *frac = static_cast<ALuint>(mind(dblfrac*FRACTIONONE, FRACTIONONE-1.0));
+ dblfrac = std::modf(Source->Offset, &dbloff);
+ offset = static_cast<ALuint>(mind(dbloff, std::numeric_limits<ALuint>::max()));
+ frac = static_cast<ALuint>(mind(dblfrac*FRACTIONONE, FRACTIONONE-1.0));
break;
case AL_SEC_OFFSET:
- dblfrac = modf(Source->Offset*BufferFmt->Frequency, &dbloff);
- *offset = static_cast<ALuint>(mind(dbloff, std::numeric_limits<ALuint>::max()));
- *frac = static_cast<ALuint>(mind(dblfrac*FRACTIONONE, FRACTIONONE-1.0));
+ dblfrac = std::modf(Source->Offset*BufferFmt->Frequency, &dbloff);
+ offset = static_cast<ALuint>(mind(dbloff, std::numeric_limits<ALuint>::max()));
+ frac = static_cast<ALuint>(mind(dblfrac*FRACTIONONE, FRACTIONONE-1.0));
break;
}
Source->OffsetType = AL_NONE;
Source->Offset = 0.0;
- return true;
-}
-
-
-struct VoicePos {
- ALuint pos, frac;
- ALbufferlistitem *bufferitem;
-};
-
-/**
- * CalcOffset
- *
- * Calculates the voice position, fixed-point fraction, and bufferlist item
- * using the source's stored offset. If the source has no stored offset, or the
- * offset is out of range, returns an empty optional.
- */
-al::optional<VoicePos> CalcOffset(ALsource *Source)
-{
- al::optional<VoicePos> ret;
-
- /* Get sample frame offset */
- ALuint offset{0u}, frac{0u};
- if(!GetSampleOffset(Source, &offset, &frac))
- return ret;
-
+ /* Find the bufferlist item this offset belongs to. */
ALuint totalBufferLen{0u};
- ALbufferlistitem *BufferList{Source->queue};
while(BufferList && totalBufferLen <= offset)
{
if(BufferList->mSampleLen > offset-totalBufferLen)
@@ -1021,7 +1004,7 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
*/
if(ALvoice *voice{GetSourceVoice(Source, Context)})
{
- auto vpos = CalcOffset(Source);
+ auto vpos = GetSampleOffset(Source);
if(!vpos) SETERR_RETURN(Context, AL_INVALID_VALUE, false, "Invalid offset");
voice->mPosition.store(vpos->pos, std::memory_order_relaxed);
@@ -1240,7 +1223,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
BackendLockGuard _{*device->Backend};
if(ALvoice *voice{GetSourceVoice(Source, Context)})
{
- auto vpos = CalcOffset(Source);
+ auto vpos = GetSampleOffset(Source);
if(!vpos) SETERR_RETURN(Context, AL_INVALID_VALUE, false, "Invalid source offset");
voice->mPosition.store(vpos->pos, std::memory_order_relaxed);
@@ -2781,7 +2764,7 @@ START_API_FUNC
voice->mPosition.store(0u, std::memory_order_relaxed);
voice->mPositionFrac.store(0, std::memory_order_relaxed);
bool start_fading{false};
- if(auto vpos = CalcOffset(source))
+ if(auto vpos = GetSampleOffset(source))
{
start_fading = vpos->pos != 0 || vpos->frac != 0 || vpos->bufferitem != BufferList;
voice->mPosition.store(vpos->pos, std::memory_order_relaxed);