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.
This commit is contained in:
parent
0a427890fe
commit
78c4351e04
@ -20,7 +20,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "openal_output_plugin.h"
|
#include "openal_output_plugin.h"
|
||||||
#include "output_api.h"
|
#include "output_api.h"
|
||||||
#include "timer.h"
|
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ struct openal_data {
|
|||||||
const char *device_name;
|
const char *device_name;
|
||||||
ALCdevice *device;
|
ALCdevice *device;
|
||||||
ALCcontext *context;
|
ALCcontext *context;
|
||||||
struct timer *timer;
|
|
||||||
ALuint buffers[NUM_BUFFERS];
|
ALuint buffers[NUM_BUFFERS];
|
||||||
unsigned filled;
|
unsigned filled;
|
||||||
ALuint source;
|
ALuint source;
|
||||||
@ -193,7 +191,6 @@ openal_open(struct audio_output *ao, struct audio_format *audio_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
od->filled = 0;
|
od->filled = 0;
|
||||||
od->timer = timer_new(audio_format);
|
|
||||||
od->frequency = audio_format->sample_rate;
|
od->frequency = audio_format->sample_rate;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -204,7 +201,6 @@ openal_close(struct audio_output *ao)
|
|||||||
{
|
{
|
||||||
struct openal_data *od = (struct openal_data *)ao;
|
struct openal_data *od = (struct openal_data *)ao;
|
||||||
|
|
||||||
timer_free(od->timer);
|
|
||||||
alcMakeContextCurrent(od->context);
|
alcMakeContextCurrent(od->context);
|
||||||
alDeleteSources(1, &od->source);
|
alDeleteSources(1, &od->source);
|
||||||
alDeleteBuffers(NUM_BUFFERS, od->buffers);
|
alDeleteBuffers(NUM_BUFFERS, od->buffers);
|
||||||
@ -212,6 +208,19 @@ openal_close(struct audio_output *ao)
|
|||||||
alcCloseDevice(od->device);
|
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
|
static size_t
|
||||||
openal_play(struct audio_output *ao, const void *chunk, size_t size,
|
openal_play(struct audio_output *ao, const void *chunk, size_t size,
|
||||||
G_GNUC_UNUSED GError **error)
|
G_GNUC_UNUSED GError **error)
|
||||||
@ -229,15 +238,8 @@ openal_play(struct audio_output *ao, const void *chunk, size_t size,
|
|||||||
od->filled++;
|
od->filled++;
|
||||||
} else {
|
} else {
|
||||||
/* wait for processed buffer */
|
/* wait for processed buffer */
|
||||||
while (!openal_has_processed(od)) {
|
while (!openal_has_processed(od))
|
||||||
if (!od->timer->started) {
|
g_usleep(10);
|
||||||
timer_start(od->timer);
|
|
||||||
} else {
|
|
||||||
timer_sync(od->timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_add(od->timer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
alSourceUnqueueBuffers(od->source, 1, &buffer);
|
alSourceUnqueueBuffers(od->source, 1, &buffer);
|
||||||
}
|
}
|
||||||
@ -271,6 +273,7 @@ const struct audio_output_plugin openal_output_plugin = {
|
|||||||
.finish = openal_finish,
|
.finish = openal_finish,
|
||||||
.open = openal_open,
|
.open = openal_open,
|
||||||
.close = openal_close,
|
.close = openal_close,
|
||||||
|
.delay = openal_delay,
|
||||||
.play = openal_play,
|
.play = openal_play,
|
||||||
.cancel = openal_cancel,
|
.cancel = openal_cancel,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user