From 03553a9b0f120d713ea60444c5404afc0cb2d950 Mon Sep 17 00:00:00 2001
From: Jack Moffitt <jack@xiph.org>
Date: Sat, 24 Feb 2001 01:31:48 +0000
Subject: [PATCH] rik@kde.org's ao_get_latency patch + fixes to make it compile
 incremented teh library version

git-svn-id: http://svn.xiph.org/trunk/ao@1330 0101bb08-14d6-0310-b084-bc0e0c8e3800
---
 configure.in                     |  2 +-
 include/ao/ao.h                  |  4 ++++
 src/ao_null.c                    |  8 +++++++-
 src/ao_wav.c                     |  8 +++++++-
 src/audio_out.c                  |  8 ++++++++
 src/plugins/alsa/ao_alsa.c       |  8 ++++++++
 src/plugins/arts/ao_arts.c       | 28 ++++++++++++++++++++++------
 src/plugins/esd/ao_esd.c         |  8 +++++++-
 src/plugins/irix/ao_irix.c       |  6 ++++++
 src/plugins/oss/ao_oss.c         |  7 ++++++-
 src/plugins/solaris/ao_solaris.c |  6 ++++++
 11 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/configure.in b/configure.in
index 992a886..6d5a844 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ AM_DISABLE_STATIC
 dnl Library versioning
 LIB_CURRENT=1
 LIB_REVISION=0
-LIB_AGE=0
+LIB_AGE=1
 AC_SUBST(LIB_CURRENT)
 AC_SUBST(LIB_REVISION)
 AC_SUBST(LIB_AGE)
diff --git a/include/ao/ao.h b/include/ao/ao.h
index 08f1bd9..4311b0f 100644
--- a/include/ao/ao.h
+++ b/include/ao/ao.h
@@ -61,6 +61,7 @@ typedef struct ao_functions_s {
 	ao_internal_t *(*open)(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options);
 	void (*play)(ao_internal_t *state, void* output_samples, uint_32 num_bytes);
 	void (*close)(ao_internal_t *state);
+	int (*get_latency)(ao_internal_t *state);
 } ao_functions_t;
 
 typedef struct ao_device_s {
@@ -97,6 +98,9 @@ void ao_close(ao_device_t *device);
 /* misc functions */
 int ao_is_big_endian(void);
 
+/* returns the number of bytes buffered by the driver / output device */
+int ao_get_latency(ao_device_t *device);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/src/ao_null.c b/src/ao_null.c
index 1ffe6b7..caed4a3 100644
--- a/src/ao_null.c
+++ b/src/ao_null.c
@@ -73,9 +73,15 @@ static ao_info_t *ao_null_get_driver_info(void)
 	return &ao_null_info;
 }
 
+static int ao_null_get_latency(void)
+{
+	return 0;
+}
+
 ao_functions_t ao_null = {
 	ao_null_get_driver_info,
 	ao_null_open,
 	ao_null_play,
-	ao_null_close
+	ao_null_close,
+	ao_null_get_latency
 };
diff --git a/src/ao_wav.c b/src/ao_wav.c
index 4742906..fe0c022 100644
--- a/src/ao_wav.c
+++ b/src/ao_wav.c
@@ -300,6 +300,11 @@ ERR:
 	free(s);
 }
 
+static int ao_wav_get_latency(void)
+{
+	return 0;
+}
+
 static ao_info_t *ao_wav_get_driver_info(void)
 {
 	return &ao_wav_info;
@@ -328,5 +333,6 @@ ao_functions_t ao_wav =
         ao_wav_get_driver_info,
         ao_wav_open,
         ao_wav_play,
-        ao_wav_close
+        ao_wav_close,
+        ao_wav_get_latency
 };
diff --git a/src/audio_out.c b/src/audio_out.c
index 62002bb..b892296 100644
--- a/src/audio_out.c
+++ b/src/audio_out.c
@@ -84,6 +84,8 @@ driver_tree_t *_get_plugin(char *plugin_file)
 		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
 		dt->functions->close = dlsym(dt->handle, "plugin_close");
 		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
+		dt->functions->get_latency = dlsym(dt->handle, "plugin_get_latency");
+		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
 	} else {
 		return NULL;
 	}
@@ -318,3 +320,9 @@ int ao_is_big_endian(void)
 	if (bytewise[0] == 0xba) return 1;
 	return 0;
 }
+
+int ao_get_latency(ao_device_t *device)
+{
+	return device->funcs->get_latency(device->state);
+}
+
diff --git a/src/plugins/alsa/ao_alsa.c b/src/plugins/alsa/ao_alsa.c
index 3030912..3d9349d 100644
--- a/src/plugins/alsa/ao_alsa.c
+++ b/src/plugins/alsa/ao_alsa.c
@@ -212,6 +212,14 @@ void plugin_play(ao_internal_t *state, void* output_samples, uint_32 num_bytes)
 	}
 }
 
+int plugin_get_latency(ao_internal_t *state)
+{
+	ao_alsa_internal_t * s = (ao_alsa_internal_t *) state;
+	snd_pcm_channel_status_t status;
+	int err = snd_pcm_channel_status(s->pcm_handle, &status);
+	return (err < 0 ? 0 : status.count);
+}
+
 ao_info_t *plugin_get_driver_info(void)
 {
 	return &ao_alsa_info;
diff --git a/src/plugins/arts/ao_arts.c b/src/plugins/arts/ao_arts.c
index 75a8cfb..ff4b88c 100644
--- a/src/plugins/arts/ao_arts.c
+++ b/src/plugins/arts/ao_arts.c
@@ -32,14 +32,17 @@
 typedef struct ao_arts_internal_s
 {
   arts_stream_t stream;
+	uint_32 bits;
+	uint_32 rate;
+	uint_32 channels;
 } ao_arts_internal_t;
 
 ao_info_t ao_arts_info =
 {
-	"aRts output",
-	"arts",
-	"Rik Hemsley (rikkus) <rik@kde.org>",
-	"Outputs to the aRts soundserver."
+  "aRts output",
+  "arts",
+  "Rik Hemsley (rikkus) <rik@kde.org>",
+  "Outputs to the aRts soundserver."
 };
 
   ao_internal_t *
@@ -74,7 +77,11 @@ plugin_open
 
   state->stream = arts_play_stream(rate, bits, channels, "ao stream");
 
-	return state;
+	state->bits = bits;
+	state->rate = rate;
+	state->channels = channels;
+
+  return state;
 }
 
   void
@@ -102,9 +109,18 @@ plugin_play
   }
 }
 
+  int
+plugin_get_latency(ao_internal_t * state)
+{
+  ao_arts_internal_t * s = (ao_arts_internal_t *)state;
+	int ms = arts_stream_get(s->stream, ARTS_P_TOTAL_LATENCY);
+	int sample_rate = (s->bits / 8) * s->rate * s->channels;
+	return (sample_rate * ms) / 1000;
+}
+
   ao_info_t *
 plugin_get_driver_info(void)
 {
-	return &ao_arts_info;
+  return &ao_arts_info;
 }
 
diff --git a/src/plugins/esd/ao_esd.c b/src/plugins/esd/ao_esd.c
index 16fd3d7..fccfb16 100644
--- a/src/plugins/esd/ao_esd.c
+++ b/src/plugins/esd/ao_esd.c
@@ -108,7 +108,7 @@ ao_internal_t *plugin_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_opti
 
 void plugin_close(ao_internal_t *state)
 {
-	ao_esd_internal_t *s = (ao_esd_internal_t *) state;
+	ao_esd_internal_t *s = (ao_esd_internal_t *)state;
 	close(s->sock);
 	free(s->host);
 	free(s);
@@ -119,6 +119,12 @@ void plugin_play(ao_internal_t *state, void* output_samples, uint_32 num_bytes)
 	write(((ao_esd_internal_t *) state)->sock, output_samples, num_bytes);
 }
 
+int plugin_get_latency(ao_internal_t *state)
+{
+	ao_esd_internal_t *s = (ao_esd_internal_t *)state;
+	return (esd_get_latency(s->sock));
+}
+
 ao_info_t *plugin_get_driver_info(void)
 {
 	return &ao_esd_info;
diff --git a/src/plugins/irix/ao_irix.c b/src/plugins/irix/ao_irix.c
index 96dd972..fd7dbd9 100644
--- a/src/plugins/irix/ao_irix.c
+++ b/src/plugins/irix/ao_irix.c
@@ -163,6 +163,12 @@ void plugin_close(ao_internal_t *state)
 	free(state);
 }
 
+int plugin_get_latency(ao_internal_t *state)
+{
+	/* TODO */
+	return 0;
+}
+
 ao_info_t *plugin_get_driver_info(void)
 {
 	return &ao_irix_info;
diff --git a/src/plugins/oss/ao_oss.c b/src/plugins/oss/ao_oss.c
index 3648553..ba2d48d 100644
--- a/src/plugins/oss/ao_oss.c
+++ b/src/plugins/oss/ao_oss.c
@@ -166,7 +166,6 @@ ao_internal_t *plugin_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_opti
 	ioctl(state->fd,SNDCTL_DSP_SPEED, &tmp);
 	
 	return state;
-	
 
  ERR:
 	if(state != NULL)
@@ -196,6 +195,12 @@ void plugin_close(ao_internal_t *state)
 	free(s);
 }
 
+int plugin_get_latency(ao_internal_t *state)
+{
+	int odelay = 0;
+	ioctl(((ao_oss_internal_t *)state)->fd, SNDCTL_DSP_GETODELAY, &odelay);
+	return odelay;
+}
 
 ao_info_t *plugin_get_driver_info(void)
 {
diff --git a/src/plugins/solaris/ao_solaris.c b/src/plugins/solaris/ao_solaris.c
index 57c62f7..d6fcbee 100644
--- a/src/plugins/solaris/ao_solaris.c
+++ b/src/plugins/solaris/ao_solaris.c
@@ -122,6 +122,12 @@ void plugin_close(ao_internal_t *state)
 	free(state);
 }
 
+int plugin_get_latency(ao_internal_t *state)
+{
+	/* TODO */
+	return 0;
+}
+
 const ao_info_t *plugin_get_driver_info(void)
 {
 	return &ao_solaris_info;
-- 
GitLab