aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c3
-rw-r--r--OpenAL32/Include/alMain.h26
-rw-r--r--OpenAL32/alSource.c87
3 files changed, 116 insertions, 0 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index bd486ca1..0fb87fad 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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