summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c2
-rw-r--r--Alc/backends/alsa.c21
-rw-r--r--Alc/backends/coreaudio.c10
-rw-r--r--Alc/backends/dsound.c11
-rw-r--r--Alc/backends/loopback.c11
-rw-r--r--Alc/backends/mmdevapi.c10
-rw-r--r--Alc/backends/null.c11
-rw-r--r--Alc/backends/opensl.c10
-rw-r--r--Alc/backends/oss.c10
-rw-r--r--Alc/backends/portaudio.c10
-rw-r--r--Alc/backends/pulseaudio.c23
-rw-r--r--Alc/backends/sndio.c10
-rw-r--r--Alc/backends/solaris.c10
-rw-r--r--Alc/backends/wave.c11
-rw-r--r--Alc/backends/winmm.c10
-rw-r--r--OpenAL32/Include/alMain.h3
-rw-r--r--OpenAL32/Include/alu.h7
17 files changed, 165 insertions, 15 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index ee2bd8a9..bd486ca1 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -43,7 +43,7 @@
/************************************************
* Backends
************************************************/
-#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
static struct BackendInfo BackendList[] = {
#ifdef HAVE_PULSEAUDIO
{ "pulse", alc_pulse_init, alc_pulse_deinit, alc_pulse_probe, EmptyFuncs },
diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c
index 49fec523..880f7ac9 100644
--- a/Alc/backends/alsa.c
+++ b/Alc/backends/alsa.c
@@ -79,6 +79,7 @@ MAKE_FUNC(snd_pcm_start);
MAKE_FUNC(snd_pcm_resume);
MAKE_FUNC(snd_pcm_reset);
MAKE_FUNC(snd_pcm_wait);
+MAKE_FUNC(snd_pcm_delay);
MAKE_FUNC(snd_pcm_state);
MAKE_FUNC(snd_pcm_avail_update);
MAKE_FUNC(snd_pcm_areas_silence);
@@ -151,6 +152,7 @@ MAKE_FUNC(snd_card_next);
#define snd_pcm_resume psnd_pcm_resume
#define snd_pcm_reset psnd_pcm_reset
#define snd_pcm_wait psnd_pcm_wait
+#define snd_pcm_delay psnd_pcm_delay
#define snd_pcm_state psnd_pcm_state
#define snd_pcm_avail_update psnd_pcm_avail_update
#define snd_pcm_areas_silence psnd_pcm_areas_silence
@@ -241,6 +243,7 @@ static ALCboolean alsa_load(void)
LOAD_FUNC(snd_pcm_resume);
LOAD_FUNC(snd_pcm_reset);
LOAD_FUNC(snd_pcm_wait);
+ LOAD_FUNC(snd_pcm_delay);
LOAD_FUNC(snd_pcm_state);
LOAD_FUNC(snd_pcm_avail_update);
LOAD_FUNC(snd_pcm_areas_silence);
@@ -1224,6 +1227,21 @@ static void alsa_stop_capture(ALCdevice *Device)
}
+static ALint64 alsa_get_latency(ALCdevice *device)
+{
+ alsa_data *data = (alsa_data*)device->ExtraData;
+ snd_pcm_sframes_t delay = 0;
+ int err;
+
+ if((err=snd_pcm_delay(data->pcmHandle, &delay)) < 0)
+ {
+ ERR("Failed to get latency!\n");
+ return 0;
+ }
+ return maxi64((ALint64)delay*1000000000/device->Frequency, 0);
+}
+
+
static const BackendFuncs alsa_funcs = {
alsa_open_playback,
alsa_close_playback,
@@ -1235,7 +1253,8 @@ static const BackendFuncs alsa_funcs = {
alsa_start_capture,
alsa_stop_capture,
alsa_capture_samples,
- alsa_available_samples
+ alsa_available_samples,
+ alsa_get_latency
};
ALCboolean alc_alsa_init(BackendFuncs *func_list)
diff --git a/Alc/backends/coreaudio.c b/Alc/backends/coreaudio.c
index a4f72468..df28d706 100644
--- a/Alc/backends/coreaudio.c
+++ b/Alc/backends/coreaudio.c
@@ -663,6 +663,13 @@ static ALCuint ca_available_samples(ALCdevice *device)
}
+static ALint64 ca_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs ca_funcs = {
ca_open_playback,
ca_close_playback,
@@ -674,7 +681,8 @@ static const BackendFuncs ca_funcs = {
ca_start_capture,
ca_stop_capture,
ca_capture_samples,
- ca_available_samples
+ ca_available_samples,
+ ca_get_latency
};
ALCboolean alc_ca_init(BackendFuncs *func_list)
diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c
index a80d2a99..89910c7f 100644
--- a/Alc/backends/dsound.c
+++ b/Alc/backends/dsound.c
@@ -934,6 +934,14 @@ done:
return RingBufferSize(data->Ring);
}
+
+static ALint64 DSoundGetLatency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs DSoundFuncs = {
DSoundOpenPlayback,
DSoundClosePlayback,
@@ -945,7 +953,8 @@ static const BackendFuncs DSoundFuncs = {
DSoundStartCapture,
DSoundStopCapture,
DSoundCaptureSamples,
- DSoundAvailableSamples
+ DSoundAvailableSamples,
+ DSoundGetLatency
};
diff --git a/Alc/backends/loopback.c b/Alc/backends/loopback.c
index eafed3e3..ae7e32b4 100644
--- a/Alc/backends/loopback.c
+++ b/Alc/backends/loopback.c
@@ -54,6 +54,14 @@ static void loopback_stop_playback(ALCdevice *device)
(void)device;
}
+
+static ALint64 loopback_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs loopback_funcs = {
loopback_open_playback,
loopback_close_playback,
@@ -65,7 +73,8 @@ static const BackendFuncs loopback_funcs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ loopback_get_latency
};
ALCboolean alc_loopback_init(BackendFuncs *func_list)
diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c
index 0edd8e60..bffc463a 100644
--- a/Alc/backends/mmdevapi.c
+++ b/Alc/backends/mmdevapi.c
@@ -937,6 +937,13 @@ static void MMDevApiStopPlayback(ALCdevice *device)
}
+static ALint64 MMDevApiGetLatency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs MMDevApiFuncs = {
MMDevApiOpenPlayback,
MMDevApiClosePlayback,
@@ -948,7 +955,8 @@ static const BackendFuncs MMDevApiFuncs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ MMDevApiGetLatency
};
diff --git a/Alc/backends/null.c b/Alc/backends/null.c
index 1b9bedef..f39d3071 100644
--- a/Alc/backends/null.c
+++ b/Alc/backends/null.c
@@ -129,6 +129,14 @@ static void null_stop_playback(ALCdevice *device)
}
+static ALint64 null_get_latency(ALCdevice *device)
+{
+ /* FIXME: Time until next update + "safe" offset */
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs null_funcs = {
null_open_playback,
null_close_playback,
@@ -140,7 +148,8 @@ static const BackendFuncs null_funcs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ null_get_latency
};
ALCboolean alc_null_init(BackendFuncs *func_list)
diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c
index bf243e38..f2df0218 100644
--- a/Alc/backends/opensl.c
+++ b/Alc/backends/opensl.c
@@ -401,6 +401,13 @@ static void opensl_stop_playback(ALCdevice *Device)
}
+static ALint64 opensl_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs opensl_funcs = {
opensl_open_playback,
opensl_close_playback,
@@ -412,7 +419,8 @@ static const BackendFuncs opensl_funcs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ opensl_get_latency
};
diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c
index 365bb802..6786f8c6 100644
--- a/Alc/backends/oss.c
+++ b/Alc/backends/oss.c
@@ -476,6 +476,13 @@ static ALCuint oss_available_samples(ALCdevice *Device)
}
+static ALint64 oss_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs oss_funcs = {
oss_open_playback,
oss_close_playback,
@@ -487,7 +494,8 @@ static const BackendFuncs oss_funcs = {
oss_start_capture,
oss_stop_capture,
oss_capture_samples,
- oss_available_samples
+ oss_available_samples,
+ oss_get_latency
};
ALCboolean alc_oss_init(BackendFuncs *func_list)
diff --git a/Alc/backends/portaudio.c b/Alc/backends/portaudio.c
index b9998150..1558e89f 100644
--- a/Alc/backends/portaudio.c
+++ b/Alc/backends/portaudio.c
@@ -419,6 +419,13 @@ static ALCuint pa_available_samples(ALCdevice *device)
}
+static ALint64 pa_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs pa_funcs = {
pa_open_playback,
pa_close_playback,
@@ -430,7 +437,8 @@ static const BackendFuncs pa_funcs = {
pa_start_capture,
pa_stop_capture,
pa_capture_samples,
- pa_available_samples
+ pa_available_samples,
+ pa_get_latency
};
ALCboolean alc_pa_init(BackendFuncs *func_list)
diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c
index 2621e334..87a04946 100644
--- a/Alc/backends/pulseaudio.c
+++ b/Alc/backends/pulseaudio.c
@@ -66,6 +66,7 @@ MAKE_FUNC(pa_stream_is_corked);
MAKE_FUNC(pa_stream_cork);
MAKE_FUNC(pa_stream_is_suspended);
MAKE_FUNC(pa_stream_get_device_name);
+MAKE_FUNC(pa_stream_get_latency);
MAKE_FUNC(pa_path_get_filename);
MAKE_FUNC(pa_get_binary_name);
MAKE_FUNC(pa_threaded_mainloop_free);
@@ -138,6 +139,7 @@ MAKE_FUNC(pa_stream_begin_write);
#define pa_stream_cork ppa_stream_cork
#define pa_stream_is_suspended ppa_stream_is_suspended
#define pa_stream_get_device_name ppa_stream_get_device_name
+#define pa_stream_get_latency ppa_stream_get_latency
#define pa_path_get_filename ppa_path_get_filename
#define pa_get_binary_name ppa_get_binary_name
#define pa_threaded_mainloop_free ppa_threaded_mainloop_free
@@ -273,6 +275,7 @@ static ALCboolean pulse_load(void)
LOAD_FUNC(pa_stream_cork);
LOAD_FUNC(pa_stream_is_suspended);
LOAD_FUNC(pa_stream_get_device_name);
+ LOAD_FUNC(pa_stream_get_latency);
LOAD_FUNC(pa_path_get_filename);
LOAD_FUNC(pa_get_binary_name);
LOAD_FUNC(pa_threaded_mainloop_free);
@@ -1375,6 +1378,23 @@ static ALCuint pulse_available_samples(ALCdevice *device)
}
+static ALint64 pulse_get_latency(ALCdevice *device)
+{
+ pulse_data *data = device->ExtraData;
+ pa_usec_t latency = 0;
+ int neg;
+
+ if(pa_stream_get_latency(data->stream, &latency, &neg) == 0)
+ {
+ if(neg)
+ latency = 0;
+ return (ALint64)minu64(latency, (((ALuint64)0x7fffffff << 32)|0xffffffff)/1000) * 1000;
+ }
+ ERR("Failed to get stream latency!\n");
+ return 0;
+}
+
+
static const BackendFuncs pulse_funcs = {
pulse_open_playback,
pulse_close_playback,
@@ -1386,7 +1406,8 @@ static const BackendFuncs pulse_funcs = {
pulse_start_capture,
pulse_stop_capture,
pulse_capture_samples,
- pulse_available_samples
+ pulse_available_samples,
+ pulse_get_latency
};
ALCboolean alc_pulse_init(BackendFuncs *func_list)
diff --git a/Alc/backends/sndio.c b/Alc/backends/sndio.c
index 1d1c512c..c1dbc1a6 100644
--- a/Alc/backends/sndio.c
+++ b/Alc/backends/sndio.c
@@ -252,6 +252,13 @@ static void sndio_stop_playback(ALCdevice *device)
}
+static ALint64 sndio_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs sndio_funcs = {
sndio_open_playback,
sndio_close_playback,
@@ -263,7 +270,8 @@ static const BackendFuncs sndio_funcs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ sndio_get_latency
};
ALCboolean alc_sndio_init(BackendFuncs *func_list)
diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c
index 215e7209..4be32a50 100644
--- a/Alc/backends/solaris.c
+++ b/Alc/backends/solaris.c
@@ -236,6 +236,13 @@ static void solaris_stop_playback(ALCdevice *device)
}
+static ALint64 solaris_get_latency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs solaris_funcs = {
solaris_open_playback,
solaris_close_playback,
@@ -247,7 +254,8 @@ static const BackendFuncs solaris_funcs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ solaris_get_latency
};
ALCboolean alc_solaris_init(BackendFuncs *func_list)
diff --git a/Alc/backends/wave.c b/Alc/backends/wave.c
index 47db5460..fb118ee8 100644
--- a/Alc/backends/wave.c
+++ b/Alc/backends/wave.c
@@ -322,6 +322,14 @@ static void wave_stop_playback(ALCdevice *device)
}
+static ALint64 wave_get_latency(ALCdevice *device)
+{
+ /* FIXME: time until next update + "safe" offset */
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs wave_funcs = {
wave_open_playback,
wave_close_playback,
@@ -333,7 +341,8 @@ static const BackendFuncs wave_funcs = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ wave_get_latency
};
ALCboolean alc_wave_init(BackendFuncs *func_list)
diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c
index b7c637d6..ecd76e52 100644
--- a/Alc/backends/winmm.c
+++ b/Alc/backends/winmm.c
@@ -705,6 +705,13 @@ static ALCuint WinMMAvailableSamples(ALCdevice *Device)
}
+static ALint64 WinMMGetLatency(ALCdevice *device)
+{
+ (void)device;
+ return 0;
+}
+
+
static const BackendFuncs WinMMFuncs = {
WinMMOpenPlayback,
WinMMClosePlayback,
@@ -716,7 +723,8 @@ static const BackendFuncs WinMMFuncs = {
WinMMStartCapture,
WinMMStopCapture,
WinMMCaptureSamples,
- WinMMAvailableSamples
+ WinMMAvailableSamples,
+ WinMMGetLatency
};
ALCboolean alcWinMMInit(BackendFuncs *FuncList)
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 8b1bcc0f..f4f3b88e 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -419,6 +419,8 @@ typedef struct {
void (*StopCapture)(ALCdevice*);
ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
ALCuint (*AvailableSamples)(ALCdevice*);
+
+ ALint64 (*GetLatency)(ALCdevice*);
} BackendFuncs;
struct BackendInfo {
@@ -604,6 +606,7 @@ struct ALCdevice_struct
#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a)))
#define ALCdevice_CaptureSamples(a,b,c) ((a)->Funcs->CaptureSamples((a), (b), (c)))
#define ALCdevice_AvailableSamples(a) ((a)->Funcs->AvailableSamples((a)))
+#define ALCdevice_GetLatency(a) ((a)->Funcs->GetLatency((a)))
// Frequency was requested by the app or config file
#define DEVICE_FREQUENCY_REQUEST (1<<1)
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index cd8f1554..f623589f 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -201,6 +201,13 @@ static __inline ALint64 maxi64(ALint64 a, ALint64 b)
static __inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
{ return mini64(max, maxi64(min, val)); }
+static __inline ALuint64 minu64(ALuint64 a, ALuint64 b)
+{ return ((a > b) ? b : a); }
+static __inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
+{ return ((a > b) ? a : b); }
+static __inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
+{ return minu64(max, maxu64(min, val)); }
+
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
{