[retro-gtk/wip/aplazas/c-port: 16/34] Port PaPlayer to C



commit 958a9db567d3574f7ebb41ed9603af02ab91da28
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Mon Sep 11 09:14:55 2017 +0200

    Port PaPlayer to C

 retro-gtk/Makefile.am          |    6 +-
 retro-gtk/audio/pa-player.vala |   40 ------------
 retro-gtk/retro-core-view.c    |    1 +
 retro-gtk/retro-pa-player.c    |  136 ++++++++++++++++++++++++++++++++++++++++
 retro-gtk/retro-pa-player.h    |   27 ++++++++
 5 files changed, 168 insertions(+), 42 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index 271ca3c..6ea8387 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -57,6 +57,7 @@ retro_gtk_private_h_sources = \
        retro-module.h \
        retro-option.h \
        retro-options.h \
+       retro-pa-player.h \
        retro-rotation.h \
        retro-system-av-info.h \
        retro-system-info.h \
@@ -64,8 +65,6 @@ retro_gtk_private_h_sources = \
        $(NULL)
 
 libretro_gtk_la_SOURCES = \
-       audio/pa-player.vala \
-       \
        input/controller.vala \
        input/input.vala \
        input/input-device-manager.vala \
@@ -97,6 +96,7 @@ libretro_gtk_la_SOURCES = \
        retro-mouse-id.c \
        retro-option.c \
        retro-options.c \
+       retro-pa-player.c \
        retro-pixel-format.c \
        retro-pointer-id.c \
        retro-video-filter.c \
@@ -121,6 +121,8 @@ retro-log.c: retro-gtk-internal.h
 
 retro-module.c: retro-gtk-internal.h
 
+retro-pa-player.c: retro-gtk-internal.h
+
 libretro_gtk_la_LDFLAGS =
 
 libretro_gtk_la_VALAFLAGS = \
diff --git a/retro-gtk/retro-core-view.c b/retro-gtk/retro-core-view.c
index 89ad450..84e19a2 100644
--- a/retro-gtk/retro-core-view.c
+++ b/retro-gtk/retro-core-view.c
@@ -7,6 +7,7 @@
 #include "retro-core-view-input-device.h"
 #include "retro-joypad-id.h"
 #include "retro-mouse-id.h"
+#include "retro-pa-player.h"
 #include "retro-pointer-id.h"
 
 static guint16 DEFAULT_KEY_JOYPAD_BUTTON_MAPPING[RETRO_JOYPAD_ID_COUNT] = {
diff --git a/retro-gtk/retro-pa-player.c b/retro-gtk/retro-pa-player.c
new file mode 100644
index 0000000..8c134c9
--- /dev/null
+++ b/retro-gtk/retro-pa-player.c
@@ -0,0 +1,136 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-pa-player.h"
+
+#include <pulse/simple.h>
+#include <pulse/pulseaudio.h>
+#include "retro-gtk-internal.h"
+
+struct _RetroPaPlayer
+{
+  GObject parent_instance;
+  RetroCore *core;
+  gulong on_audio_output_id;
+  gdouble sample_rate;
+  pa_simple *simple;
+};
+
+G_DEFINE_TYPE (RetroPaPlayer, retro_pa_player, G_TYPE_OBJECT)
+
+/* Private */
+
+static void
+retro_pa_player_finalize (GObject *object)
+{
+  RetroPaPlayer *self = (RetroPaPlayer *)object;
+
+  g_clear_object (&self->core);
+  pa_simple_free (self->simple);
+
+  G_OBJECT_CLASS (retro_pa_player_parent_class)->finalize (object);
+}
+
+static void
+retro_pa_player_class_init (RetroPaPlayerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = retro_pa_player_finalize;
+}
+
+static void
+retro_pa_player_init (RetroPaPlayer *self)
+{
+}
+
+static void
+retro_pa_player_prepare_for_sample_rate (RetroPaPlayer *self,
+                                         gdouble        sample_rate)
+{
+  pa_sample_spec sample_spec = {0};
+
+  g_return_if_fail (RETRO_IS_PA_PLAYER (self));
+
+  self->sample_rate = sample_rate;
+
+  pa_sample_spec_init (&sample_spec);
+  sample_spec.format = PA_SAMPLE_S16NE;
+  sample_spec.rate = (guint32) sample_rate;
+  sample_spec.channels = 2;
+
+  if (self->simple != NULL)
+    pa_simple_free (self->simple);
+
+  self->simple = pa_simple_new (NULL, NULL, PA_STREAM_PLAYBACK, NULL, "",
+                                &sample_spec, NULL, NULL, NULL);
+}
+
+static void
+retro_pa_player_on_audio_output (RetroCore *sender,
+                                 gint16    *data,
+                                 int        length,
+                                 gdouble    sample_rate,
+                                 gpointer   user_data)
+{
+  RetroPaPlayer *self = RETRO_PA_PLAYER (user_data);
+
+  g_return_if_fail (RETRO_IS_PA_PLAYER (self));
+
+  if (self->simple == NULL || sample_rate != self->sample_rate)
+    retro_pa_player_prepare_for_sample_rate (self, sample_rate);
+
+  pa_simple_write (self->simple, data, sizeof (gint16) * length, NULL);
+}
+
+/* Public */
+
+/**
+ * retro_pa_player_set_core:
+ * @self: a #RetroPaPlayer
+ * @core: (nullable): a #RetroCore, or %NULL
+ *
+ * Sets @core as the #RetroCore played by @self.
+ */
+void
+retro_pa_player_set_core (RetroPaPlayer *self,
+                          RetroCore     *core)
+{
+  g_return_if_fail (RETRO_IS_PA_PLAYER (self));
+
+  if (self->core == core)
+    return;
+
+  if (self->core != NULL) {
+    g_signal_handler_disconnect (G_OBJECT (self->core),
+                                 self->on_audio_output_id);
+    g_clear_object (&self->core);
+  }
+
+  if (core != NULL) {
+    self->core = g_object_ref (core);
+    self->on_audio_output_id =
+      g_signal_connect_object (core,
+                               "audio-output",
+                               (GCallback) retro_pa_player_on_audio_output,
+                               self,
+                               0);
+  }
+
+  if (self->simple != NULL) {
+    pa_simple_free (self->simple);
+    self->simple = NULL;
+  }
+}
+
+/**
+ * retro_pa_player_new:
+ *
+ * Creates a new #RetroPaPlayer.
+ *
+ * Returns: (transfer full): a new #RetroPaPlayer
+ */
+RetroPaPlayer *
+retro_pa_player_new (void)
+{
+  return g_object_new (RETRO_TYPE_PA_PLAYER, NULL);
+}
diff --git a/retro-gtk/retro-pa-player.h b/retro-gtk/retro-pa-player.h
new file mode 100644
index 0000000..c126731
--- /dev/null
+++ b/retro-gtk/retro-pa-player.h
@@ -0,0 +1,27 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_PA_PLAYER_H
+#define RETRO_PA_PLAYER_H
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+// FIXME Remove as soon as possible.
+typedef struct _RetroCore RetroCore;
+
+#define RETRO_TYPE_PA_PLAYER (retro_pa_player_get_type())
+
+G_DECLARE_FINAL_TYPE (RetroPaPlayer, retro_pa_player, RETRO, PA_PLAYER, GObject)
+
+RetroPaPlayer *retro_pa_player_new (void);
+void retro_pa_player_set_core (RetroPaPlayer *self,
+                               RetroCore     *core);
+
+G_END_DECLS
+
+#endif /* RETRO_PA_PLAYER_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]