瀏覽代碼

Merge pull request #1 from ipha/pulseaudio_stop_sink

Stop pulseaudio sink when not in use
ComlOnline 7 年之前
父節點
當前提交
74964d8087
共有 1 個文件被更改,包括 32 次插入21 次删除
  1. 32 21
      src/audio_backend/pulseaudio.rs

+ 32 - 21
src/audio_backend/pulseaudio.rs

@@ -5,7 +5,12 @@ use std::ptr::{null, null_mut};
 use std::mem::{transmute};
 use std::ffi::CString;
 
-pub struct PulseAudioSink(*mut pa_simple);
+pub struct PulseAudioSink {
+    s    : *mut pa_simple,
+    ss   : pa_sample_spec,
+    name : CString,
+    desc : CString
+}
 
 impl Open for PulseAudioSink {
    fn open(device: Option<String>) -> PulseAudioSink {
@@ -24,30 +29,40 @@ impl Open for PulseAudioSink {
         let name = CString::new("librespot").unwrap();
         let description = CString::new("A spoty client library").unwrap();
 
-        let s = unsafe {
-            pa_simple_new(null(),               // Use the default server.
-                          name.as_ptr(),        // Our application's name.
-                          PA_STREAM_PLAYBACK,
-                          null(),               // Use the default device.
-                          description.as_ptr(), // Description of our stream.
-                          &ss,                  // Our sample format.
-                          null(),               // Use default channel map
-                          null(),               // Use default buffering attributes.
-                          null_mut(),           // Ignore error code.
-            )
-        };
-        assert!(s != null_mut());
-        
-        PulseAudioSink(s)
+        PulseAudioSink {
+            s: null_mut(),
+            ss: ss,
+            name: name,
+            desc: description
+        }
     }
 }
 
 impl Sink for PulseAudioSink {
     fn start(&mut self) -> io::Result<()> {
+        if self.s == null_mut() {
+            self.s = unsafe {
+                pa_simple_new(null(),               // Use the default server.
+                              self.name.as_ptr(),   // Our application's name.
+                              PA_STREAM_PLAYBACK,
+                              null(),               // Use the default device.
+                              self.desc.as_ptr(),   // desc of our stream.
+                              &self.ss,             // Our sample format.
+                              null(),               // Use default channel map
+                              null(),               // Use default buffering attributes.
+                              null_mut(),           // Ignore error code.
+                )
+            };
+            assert!(self.s != null_mut());
+        }
         Ok(())
     }
 
     fn stop(&mut self) -> io::Result<()> {
+        unsafe {
+            pa_simple_free(self.s);
+        }
+        self.s = null_mut();
         Ok(())
     }
 
@@ -55,13 +70,9 @@ impl Sink for PulseAudioSink {
         unsafe {
             let ptr = transmute(data.as_ptr());
             let bytes = data.len() as usize * 2;
-            pa_simple_write(self.0, ptr, bytes, null_mut());
+            pa_simple_write(self.s, ptr, bytes, null_mut());
         };
         
         Ok(())
     }
 }
-
-
-
-