diff options
-rw-r--r-- | Alc/ALc.c | 3 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 26 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 87 |
3 files changed, 116 insertions, 0 deletions
@@ -255,6 +255,9 @@ static const ALCfunction alcFunctions[] = { DECL(alDeferUpdatesSOFT), DECL(alProcessUpdatesSOFT), + DECL(alGetSourcei64SOFT), + DECL(alGetSourcei64vSOFT), + { NULL, NULL } }; #undef DECL diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index f4f3b88e..d12fe3f8 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -18,6 +18,19 @@ #include "AL/alc.h" #include "AL/alext.h" +/* Define int64_t and uint64_t types */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include <inttypes.h> +#elif defined(_WIN32) && defined(__GNUC__) +#include <stdint.h> +#elif defined(_WIN32) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include <inttypes.h> +#endif + #ifndef AL_SOFT_deferred_updates #define AL_SOFT_deferred_updates 1 #define AL_DEFERRED_UPDATES_SOFT 0xC002 @@ -29,6 +42,19 @@ AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); #endif #endif +#ifndef AL_SOFT_source_latency +#define AL_SOFT_source_latency 1 +#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 +typedef int64_t ALint64SOFT; +typedef uint64_t ALuint64SOFT; +typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *values); +AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values); +#endif +#endif + #if defined(HAVE_STDINT_H) #include <stdint.h> 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 |