[retro-gtk] retro-gtk: Use PulseAudio.Simple rather than RetroGtk.PaDevice



commit 5611de2b20c7c643e746069ad76b15c3f8d6cd47
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Wed Aug 24 17:43:01 2016 +0200

    retro-gtk: Use PulseAudio.Simple rather than RetroGtk.PaDevice
    
    Also remove RetroGtk.PaDevice and RetroGtk.RingBuffer as they are not
    used anymore.
    
    This replace the buggy custom PulseAudio device implementation by the
    simple and sandard PulseAudio.Simple, avoiding sound to stop working
    after some time on some systems.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=770340

 retro-gtk/audio/pa-player.vala |  199 ++++-----------------------------------
 1 files changed, 21 insertions(+), 178 deletions(-)
---
diff --git a/retro-gtk/audio/pa-player.vala b/retro-gtk/audio/pa-player.vala
index d520f27..700397f 100644
--- a/retro-gtk/audio/pa-player.vala
+++ b/retro-gtk/audio/pa-player.vala
@@ -6,177 +6,6 @@ using Retro;
 
 namespace RetroGtk {
 
-private class RingBuffer : Object {
-       public size_t buffer_size { get; construct; }
-
-       private uint8* buffer;
-       private size_t start;
-       private size_t written;
-       private size_t end {
-               get { return (start + written) % buffer_size; }
-       }
-
-       public RingBuffer (size_t size) {
-               Object (buffer_size: size);
-       }
-
-       construct {
-               buffer = malloc (buffer_size);
-               start = written = 0;
-       }
-
-       ~RingBuffer () {
-               free (buffer);
-       }
-
-       public bool push (uint8* src, size_t size) {
-               if (size > get_writable_size ())
-                       return false;
-
-               if (end + size <= buffer_size) {
-                       Memory.copy (buffer + end, src, size);
-                       written += size;
-               }
-               else {
-                       size_t cpsize = buffer_size - end;
-                       push (src, cpsize);
-                       push (src + cpsize, size - cpsize);
-               }
-
-               return true;
-       }
-
-       public bool pop (uint8* dst, size_t size) {
-               if (size > get_readable_size ())
-                       return false;
-
-               if (start + size <= buffer_size) {
-                       Memory.copy (dst, buffer + start, size);
-                       start = (start + size) % buffer_size;
-                       written -= size;
-               }
-               else {
-                       size_t cpsize = buffer_size - start;
-                       pop (dst, cpsize);
-                       pop (dst + cpsize, size - cpsize);
-               }
-
-               return true;
-       }
-
-       public size_t get_readable_size () {
-               return written;
-       }
-
-       public size_t get_writable_size () {
-               return buffer_size - written;
-       }
-}
-
-private class PaDevice : GLib.Object {
-       private ThreadedMainLoop  loop;
-       private Context           context;
-       private SampleSpec        spec;
-       private RingBuffer ring_buffer;
-
-       private bool started;
-       private Stream? stream = null;
-
-       public PaDevice (uint32 sample_rate = 44100) {
-               spec = SampleSpec () {
-                       format   = SampleFormat.S16NE,
-                       rate     = sample_rate,
-                       channels = 2
-               };
-
-               started = false;
-       }
-
-       construct {
-               loop = new ThreadedMainLoop ();
-               ring_buffer = new RingBuffer (88200);
-       }
-
-       ~PaDevice () {
-               stop ();
-       }
-
-       private void start () {
-               context = new Context (loop.get_api (), null);
-               var context_flags = Context.Flags.NOFAIL;
-               context.set_state_callback (cstate_cb);
-
-               // Connect the context
-               if (context.connect (null, context_flags, null) < 0) {
-                       stderr.printf ("Error: pa_context_connect () failed: %s\n", PulseAudio.strerror 
(context.errno ()));
-               }
-
-               loop.start ();
-
-               started = true;
-       }
-
-       private void stop () {
-               if (!started) return;
-
-               loop.stop ();
-
-               context = null;
-               stream = null;
-
-               started = false;
-       }
-
-       private void cstate_cb (Context context) {
-               if (context.get_state () == Context.State.READY) {
-                       var attr = Stream.BufferAttr ();
-
-                       Stream.Flags flags = Stream.Flags.INTERPOLATE_TIMING | 
Stream.Flags.AUTO_TIMING_UPDATE | Stream.Flags.EARLY_REQUESTS;
-
-                       stream = new Stream (context, "", spec);
-
-                       size_t n_fragments = 12;
-
-                       size_t fragment_size = spec.bytes_per_second () / 2 / n_fragments;
-                       if (fragment_size < 1024)
-                               fragment_size = 1024;
-
-                       attr.maxlength = (uint32) (fragment_size * (n_fragments+1));
-                       attr.tlength = (uint32) (fragment_size * n_fragments);
-                       attr.prebuf = (uint32) fragment_size;
-                       attr.minreq = (uint32) fragment_size;
-
-                       stream.connect_playback (null, attr, flags, null, null);
-               }
-       }
-
-       public void play (int16[] data) {
-               if (!started) start ();
-
-               if (stream != null) {
-                       ring_buffer.push ((uint8*) data, data.length * sizeof(int16));
-
-                       var attr = stream.get_buffer_attr ();
-                       if (attr != null) {
-                               size_t to_read = attr.minreq;
-                               if (ring_buffer.get_readable_size () >= to_read) {
-                                       void* tmp_buffer = malloc (to_read);
-
-                                       ring_buffer.pop (tmp_buffer, to_read);
-                                       stream.write (tmp_buffer, to_read);
-
-                                       free (tmp_buffer);
-                               }
-                       }
-               }
-       }
-
-       public void set_sample_rate (uint32 sample_rate) {
-               stop ();
-               spec.rate = sample_rate;
-       }
-}
-
 public class PaPlayer : GLib.Object, Retro.Audio {
        private ulong av_info_sig = 0;
        private ulong init_sig = 0;
@@ -205,14 +34,21 @@ public class PaPlayer : GLib.Object, Retro.Audio {
                }
        }
 
-       private PaDevice device;
+       private Simple simple;
 
        public PaPlayer (uint32 sample_rate = 44100) {
                Object (sample_rate: sample_rate);
        }
 
        construct {
-               device = new PaDevice ();
+               var sample_spec = SampleSpec() {
+                       format = SampleFormat.S16NE,
+                       rate = sample_rate,
+                       channels = 2
+               };
+               simple = new Simple (null, null, Stream.Direction.PLAYBACK,
+                                    null, "", sample_spec, null, null,
+                                    null);
        }
 
        private uint32 _sample_rate;
@@ -223,19 +59,26 @@ public class PaPlayer : GLib.Object, Retro.Audio {
 
                        _sample_rate = value;
 
-                       device.set_sample_rate (value);
+                       var sample_spec = SampleSpec() {
+                               format = SampleFormat.S16NE,
+                               rate = value,
+                               channels = 2
+                       };
+                       simple = new Simple (null, null, Stream.Direction.PLAYBACK,
+                                            null, "", sample_spec, null, null,
+                                            null);
                }
                default = 44100;
        }
 
        private void play_sample (int16 left, int16 right) {
-               if (device != null)
-                       device.play ({ left, right });
+               int16[] data = { left, right };
+               simple.write (data, sizeof (int16) * data.length);
        }
 
        private size_t play_batch (int16[] data, size_t frames) {
-               if (device != null)
-                       device.play (data);
+               simple.write (data, sizeof (int16) * data.length);
+
                return 0;
        }
 


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