Browse Source

Merge pull request #543 from willstott101/rodio-0.13

WIP: rodio 0.13
Sasha Hilton 3 years ago
parent
commit
2fa69cdc6e
3 changed files with 608 additions and 107 deletions
  1. 543 64
      Cargo.lock
  2. 2 2
      playback/Cargo.toml
  3. 63 41
      playback/src/audio_backend/rodio.rs

File diff suppressed because it is too large
+ 543 - 64
Cargo.lock


+ 2 - 2
playback/Cargo.toml

@@ -28,8 +28,8 @@ portaudio-rs    = { version = "0.3", optional = true }
 libpulse-sys    = { version = "0.0.0", optional = true }
 jack            = { version = "0.5", optional = true }
 libc            = { version = "0.2", optional = true }
-rodio           = { version = "0.9", optional = true, default-features = false }
-cpal            = { version = "0.8", optional = true }
+rodio           = { version = "0.13", optional = true, default-features = false }
+cpal            = { version = "0.13", optional = true }
 sdl2            = { version = "0.32", optional = true }
 gstreamer       = { version = "0.15", optional = true }
 gstreamer-app   = { version = "0.15", optional = true }

+ 63 - 41
playback/src/audio_backend/rodio.rs

@@ -1,88 +1,110 @@
 use super::{Open, Sink};
 extern crate cpal;
 extern crate rodio;
+use cpal::traits::{DeviceTrait, HostTrait};
 use std::process::exit;
 use std::{io, thread, time};
 
 pub struct RodioSink {
     rodio_sink: rodio::Sink,
+    // We have to keep hold of this object, or the Sink can't play...
+    #[allow(dead_code)]
+    stream: rodio::OutputStream,
 }
 
 fn list_formats(ref device: &rodio::Device) {
-    let default_fmt = match device.default_output_format() {
-        Ok(fmt) => cpal::SupportedFormat::from(fmt),
+    let default_fmt = match device.default_output_config() {
+        Ok(fmt) => cpal::SupportedStreamConfig::from(fmt),
         Err(e) => {
-            warn!("Error getting default rodio::Sink format: {:?}", e);
+            warn!("Error getting default rodio::Sink config: {}", e);
             return;
         }
     };
+    debug!("  Default config:");
+    debug!("    {:?}", default_fmt);
 
-    let mut output_formats = match device.supported_output_formats() {
+    let mut output_configs = match device.supported_output_configs() {
         Ok(f) => f.peekable(),
         Err(e) => {
-            warn!("Error getting supported rodio::Sink formats: {:?}", e);
+            warn!("Error getting supported rodio::Sink configs: {}", e);
             return;
         }
     };
 
-    if output_formats.peek().is_some() {
-        debug!("  Available formats:");
-        for format in output_formats {
-            let s = format!(
-                "{}ch, {:?}, min {:?}, max {:?}",
-                format.channels, format.data_type, format.min_sample_rate, format.max_sample_rate
-            );
-            if format == default_fmt {
-                debug!("    (default) {}", s);
-            } else {
-                debug!("    {:?}", format);
-            }
+    if output_configs.peek().is_some() {
+        debug!("  Available configs:");
+        for format in output_configs {
+            debug!("    {:?}", format);
         }
     }
 }
 
 fn list_outputs() {
-    let default_device = rodio::default_output_device().unwrap();
-    println!("Default Audio Device:\n  {}", default_device.name());
+    let default_device = get_default_device();
+    let default_device_name = default_device.name().expect("cannot get output name");
+    println!("Default Audio Device:\n  {}", default_device_name);
     list_formats(&default_device);
 
     println!("Other Available Audio Devices:");
-    for device in rodio::output_devices() {
-        if device.name() != default_device.name() {
-            println!("  {}", device.name());
+    for device in cpal::default_host()
+        .output_devices()
+        .expect("cannot get list of output devices")
+    {
+        let device_name = device.name().expect("cannot get output name");
+        if device_name != default_device_name {
+            println!("  {}", device_name);
             list_formats(&device);
         }
     }
 }
 
-impl Open for RodioSink {
-    fn open(device: Option<String>) -> RodioSink {
-        debug!("Using rodio sink");
-
-        let mut rodio_device = rodio::default_output_device().expect("no output device available");
-        if device.is_some() {
-            let device_name = device.unwrap();
+fn get_default_device() -> rodio::Device {
+    cpal::default_host()
+        .default_output_device()
+        .expect("no default output device available")
+}
 
+fn match_device(device: Option<String>) -> rodio::Device {
+    match device {
+        Some(device_name) => {
             if device_name == "?".to_string() {
                 list_outputs();
                 exit(0)
             }
-            let mut found = false;
-            for d in rodio::output_devices() {
-                if d.name() == device_name {
-                    rodio_device = d;
-                    found = true;
-                    break;
+            for d in cpal::default_host()
+                .output_devices()
+                .expect("cannot get list of output devices")
+            {
+                if d.name().expect("cannot get output name") == device_name {
+                    return d;
                 }
             }
-            if !found {
-                println!("No output sink matching '{}' found.", device_name);
-                exit(0)
-            }
+            println!("No output sink matching '{}' found.", device_name);
+            exit(0)
         }
-        let sink = rodio::Sink::new(&rodio_device);
+        None => return get_default_device(),
+    }
+}
+
+impl Open for RodioSink {
+    fn open(device: Option<String>) -> RodioSink {
+        debug!(
+            "Using rodio sink with cpal host: {:?}",
+            cpal::default_host().id()
+        );
+
+        let rodio_device = match_device(device);
+        debug!("Using cpal device");
+        let stream = rodio::OutputStream::try_from_device(&rodio_device)
+            .expect("Couldn't open output stream.");
+        debug!("Using rodio stream");
+        let sink = rodio::Sink::try_new(&stream.1).expect("Couldn't create output sink.");
+        debug!("Using rodio sink");
 
-        RodioSink { rodio_sink: sink }
+        RodioSink {
+            rodio_sink: sink,
+            stream: stream.0,
+        }
     }
 }
 

Some files were not shown because too many files changed in this diff