diff options
author | Chris Robinson <[email protected]> | 2012-08-18 11:02:54 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2012-08-18 11:06:39 -0700 |
commit | 3ae5fcbd7e8759b0542a46f20d17cfb5610c5218 (patch) | |
tree | 4b844b3169818324b5f19589599c3d529db26807 /OpenAL32/alSource.c | |
parent | ac4fc4026c3b1b0b9487216399bef04d419b04b8 (diff) |
Add the start of AL_SOFT_source_latency
This extension will provide a way for apps to get accurate latency and playback
position information
Diffstat (limited to 'OpenAL32/alSource.c')
-rw-r--r-- | OpenAL32/alSource.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 2c5fb30d..8ff8a3b1 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -47,6 +47,7 @@ const ALsizei ResamplerPrePadding[ResamplerMax] = { static ALvoid InitSourceParams(ALsource *Source); +static ALint64 GetSourceOffset(ALsource *Source); static ALvoid GetSourceOffsets(ALsource *Source, ALenum name, ALdouble *offsets, ALdouble updateLen); static ALint GetSampleOffset(ALsource *Source); @@ -1230,6 +1231,62 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values } +AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64 *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + al_try + { + if((Source=LookupSource(Context, source)) == NULL) + al_throwerr(Context, AL_INVALID_NAME); + CHECK_VALUE(Context, values); + switch(param) + { + default: + al_throwerr(Context, AL_INVALID_ENUM); + } + } + al_endtry; + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + al_try + { + if((Source=LookupSource(Context, source)) == NULL) + al_throwerr(Context, AL_INVALID_NAME); + CHECK_VALUE(Context, values); + switch(param) + { + case AL_SAMPLE_OFFSET_LATENCY_SOFT: + LockContext(Context); + values[0] = GetSourceOffset(Source); + values[1] = ALCdevice_GetLatency(Context->Device); + UnlockContext(Context); + break; + + default: + al_throwerr(Context, AL_INVALID_ENUM); + } + } + al_endtry; + + ALCcontext_DecRef(Context); +} + + AL_API ALvoid AL_APIENTRY alSourcePlay(ALuint source) { alSourcePlayv(1, &source); @@ -1744,6 +1801,36 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } } +/* GetSourceOffset + * + * Gets the current read offset for the given Source, in 32.32 fixed-point + * samples. The offset is relative to the start of the queue (not the start of + * the current buffer). + */ +static ALint64 GetSourceOffset(ALsource *Source) +{ + const ALbufferlistitem *BufferList; + ALuint64 readPos; + ALuint i; + + if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) + return 0; + + /* NOTE: This is the offset into the *current* buffer, so add the length of + * any played buffers */ + readPos = (ALuint64)Source->position << 32; + readPos |= (ALuint64)Source->position_fraction << (32-FRACTIONBITS); + BufferList = Source->queue; + for(i = 0;i < Source->BuffersPlayed && BufferList;i++) + { + if(BufferList->buffer) + readPos += (ALuint64)BufferList->buffer->SampleLen << 32; + BufferList = BufferList->next; + } + + return (ALint64)minu64(readPos, ((ALuint64)0x7fffffff<<32)|0xffffffff); +} + /* GetSourceOffsets * * Gets the current read and write offsets for the given Source, in the |