aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2011-12-13 21:48:15 +0100
committerMax Kellermann <max@duempel.org>2011-12-13 22:02:05 +0100
commit78c4351e04629d701a3652da9af98b080fd9f2b8 (patch)
treee97f57ce2f56256b25c2c5809253e19cc8934da1 /src
parent0a427890fe5b889fa3737b829731267174204bc0 (diff)
downloadmpd-78c4351e04629d701a3652da9af98b080fd9f2b8.tar.gz
mpd-78c4351e04629d701a3652da9af98b080fd9f2b8.tar.xz
mpd-78c4351e04629d701a3652da9af98b080fd9f2b8.zip
output/openal: improve synchronization
This plugin's use of the "Timer" library was wrong; it added the same amount of virtual data in every iteration in _play(), but did not actually play something. This created an artificial, but useless, delay. This patch implements the method _cancel(), and implements hard-coded sleep values. This is only slightly better, but does not attempt to look sane.
Diffstat (limited to '')
-rw-r--r--src/output/openal_output_plugin.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/output/openal_output_plugin.c b/src/output/openal_output_plugin.c
index d8dc90ed5..ebd35ef12 100644
--- a/src/output/openal_output_plugin.c
+++ b/src/output/openal_output_plugin.c
@@ -20,7 +20,6 @@
#include "config.h"
#include "openal_output_plugin.h"
#include "output_api.h"
-#include "timer.h"
#include <glib.h>
@@ -44,7 +43,6 @@ struct openal_data {
const char *device_name;
ALCdevice *device;
ALCcontext *context;
- struct timer *timer;
ALuint buffers[NUM_BUFFERS];
unsigned filled;
ALuint source;
@@ -193,7 +191,6 @@ openal_open(struct audio_output *ao, struct audio_format *audio_format,
}
od->filled = 0;
- od->timer = timer_new(audio_format);
od->frequency = audio_format->sample_rate;
return true;
@@ -204,7 +201,6 @@ openal_close(struct audio_output *ao)
{
struct openal_data *od = (struct openal_data *)ao;
- timer_free(od->timer);
alcMakeContextCurrent(od->context);
alDeleteSources(1, &od->source);
alDeleteBuffers(NUM_BUFFERS, od->buffers);
@@ -212,6 +208,19 @@ openal_close(struct audio_output *ao)
alcCloseDevice(od->device);
}
+static unsigned
+openal_delay(struct audio_output *ao)
+{
+ struct openal_data *od = (struct openal_data *)ao;
+
+ return od->filled < NUM_BUFFERS || openal_has_processed(od)
+ ? 0
+ /* we don't know exactly how long we must wait for the
+ next buffer to finish, so this is a random
+ guess: */
+ : 50;
+}
+
static size_t
openal_play(struct audio_output *ao, const void *chunk, size_t size,
G_GNUC_UNUSED GError **error)
@@ -229,15 +238,8 @@ openal_play(struct audio_output *ao, const void *chunk, size_t size,
od->filled++;
} else {
/* wait for processed buffer */
- while (!openal_has_processed(od)) {
- if (!od->timer->started) {
- timer_start(od->timer);
- } else {
- timer_sync(od->timer);
- }
-
- timer_add(od->timer, size);
- }
+ while (!openal_has_processed(od))
+ g_usleep(10);
alSourceUnqueueBuffers(od->source, 1, &buffer);
}
@@ -271,6 +273,7 @@ const struct audio_output_plugin openal_output_plugin = {
.finish = openal_finish,
.open = openal_open,
.close = openal_close,
+ .delay = openal_delay,
.play = openal_play,
.cancel = openal_cancel,
};