[retro-gtk] retro-pa-player: Bufferize samples on each frame
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk] retro-pa-player: Bufferize samples on each frame
- Date: Thu, 30 Jan 2020 09:29:28 +0000 (UTC)
commit 47a2e576add29455987a481e930d1cd7033dba2d
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Thu Jan 23 02:57:37 2020 +0500
retro-pa-player: Bufferize samples on each frame
Currently RetroCore bufferizes individual samples into batches of 512 frames.
It was done as a workaround for blocking audio, but it can lead to a situation
where the buffer was almost filled during a frame, but not completely, leading
to the audio being delayed until the next frame, which leads to audio desync.
Instead, do itin RetroPaPlayer itself, buffering the audio during a frame and
submitting it all at once when RetroCore emits 'frame' signal.
This will allow to stop doing buffering in RetroCore.
retro-gtk/retro-pa-player.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
---
diff --git a/retro-gtk/retro-pa-player.c b/retro-gtk/retro-pa-player.c
index 9d44018..c96f35f 100644
--- a/retro-gtk/retro-pa-player.c
+++ b/retro-gtk/retro-pa-player.c
@@ -2,6 +2,7 @@
#include "retro-pa-player-private.h"
+#include "retro-core-private.h"
#include <pulse/simple.h>
#include <pulse/pulseaudio.h>
@@ -10,6 +11,8 @@ struct _RetroPaPlayer
GObject parent_instance;
RetroCore *core;
gulong on_audio_output_id;
+ gulong on_iterated_id;
+ GArray *buffer;
gdouble sample_rate;
pa_simple *simple;
};
@@ -30,6 +33,8 @@ retro_pa_player_finalize (GObject *object)
self->simple = NULL;
}
+ g_array_unref (self->buffer);
+
G_OBJECT_CLASS (retro_pa_player_parent_class)->finalize (object);
}
@@ -44,6 +49,7 @@ retro_pa_player_class_init (RetroPaPlayerClass *klass)
static void
retro_pa_player_init (RetroPaPlayer *self)
{
+ self->buffer = g_array_new (FALSE, FALSE, sizeof (gint16));
}
static void
@@ -81,7 +87,19 @@ retro_pa_player_on_audio_output (RetroCore *sender,
{
RetroPaPlayer *self = RETRO_PA_PLAYER (user_data);
- g_return_if_fail (RETRO_IS_PA_PLAYER (self));
+ g_array_append_vals (self->buffer, data, length);
+}
+
+static void
+on_iterated (RetroCore *core,
+ RetroPaPlayer *self)
+{
+ gdouble sample_rate;
+
+ if (retro_core_is_running_ahead (self->core))
+ return;
+
+ sample_rate = retro_core_get_sample_rate (self->core);
if (self->simple == NULL || sample_rate != self->sample_rate)
retro_pa_player_prepare_for_sample_rate (self, sample_rate);
@@ -89,7 +107,12 @@ retro_pa_player_on_audio_output (RetroCore *sender,
if (self->simple == NULL)
return;
- pa_simple_write (self->simple, data, sizeof (gint16) * length, NULL);
+ pa_simple_write (self->simple,
+ self->buffer->data,
+ self->buffer->len * sizeof (gint16),
+ NULL);
+
+ g_array_set_size (self->buffer, 0);
}
/* Public */
@@ -113,6 +136,8 @@ retro_pa_player_set_core (RetroPaPlayer *self,
if (self->core != NULL) {
g_signal_handler_disconnect (G_OBJECT (self->core),
self->on_audio_output_id);
+ g_signal_handler_disconnect (G_OBJECT (self->core),
+ self->on_iterated_id);
g_clear_object (&self->core);
}
@@ -124,6 +149,12 @@ retro_pa_player_set_core (RetroPaPlayer *self,
(GCallback) retro_pa_player_on_audio_output,
self,
0);
+ self->on_iterated_id =
+ g_signal_connect_object (core,
+ "iterated",
+ (GCallback) on_iterated,
+ self,
+ 0);
}
if (self->simple != NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]