From 659ea26ae0fdd0c61b3c2648f9704b4279e72774 Mon Sep 17 00:00:00 2001 From: Lcchy <52164716+Lcchy@users.noreply.github.com> Date: Sun, 13 Dec 2020 18:48:39 +0100 Subject: [PATCH] Add JackHost devices to rodio-backend --- Cargo.toml | 1 + playback/Cargo.toml | 3 +- playback/src/audio_backend/rodio.rs | 75 +++++++++++++++++++---------- 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 085ccb8e3..b56fc47a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ portaudio-backend = ["librespot-playback/portaudio-backend"] pulseaudio-backend = ["librespot-playback/pulseaudio-backend"] jackaudio-backend = ["librespot-playback/jackaudio-backend"] rodio-backend = ["librespot-playback/rodio-backend"] +rodiojack-backend = ["librespot-playback/rodiojack-backend"] sdl-backend = ["librespot-playback/sdl-backend"] gstreamer-backend = ["librespot-playback/gstreamer-backend"] diff --git a/playback/Cargo.toml b/playback/Cargo.toml index df3800788..9008f3e25 100644 --- a/playback/Cargo.toml +++ b/playback/Cargo.toml @@ -41,6 +41,7 @@ alsa-backend = ["alsa"] portaudio-backend = ["portaudio-rs"] pulseaudio-backend = ["libpulse-sys", "libc"] jackaudio-backend = ["jack"] -rodio-backend = ["rodio", "cpal"] +rodio-backend = ["rodio", "cpal/jack"] +rodiojack-backend = ["rodio", "cpal/jack"] sdl-backend = ["sdl2"] gstreamer-backend = ["gstreamer", "gstreamer-app", "glib", "zerocopy"] diff --git a/playback/src/audio_backend/rodio.rs b/playback/src/audio_backend/rodio.rs index bc1017867..8d2176015 100644 --- a/playback/src/audio_backend/rodio.rs +++ b/playback/src/audio_backend/rodio.rs @@ -1,9 +1,9 @@ use super::{Open, Sink}; extern crate cpal; extern crate rodio; -use cpal::traits::{DeviceTrait, HostTrait}; use std::process::exit; use std::{io, thread, time}; +use cpal::{HostId, traits::{DeviceTrait, HostTrait}}; pub struct RodioSink { rodio_sink: rodio::Sink, @@ -46,14 +46,18 @@ fn list_outputs() { list_formats(&default_device); println!("Other Available Audio Devices:"); - 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 { + for host in cpal::available_hosts() { + let found_devices = cpal::host_from_id(host) + .expect(&format!("Host {:?} not found", host)) + .output_devices().expect(&format!("Cannot get list of output devices of Host: {:?}", host)); + for device in found_devices { + let device_name = device.name().expect("cannot get output name"); + if device_name != default_device_name { + println!(" {}", device_name); println!(" {}", device_name); - list_formats(&device); + println!(" {}", device_name); + list_formats(&device); + } } } } @@ -71,40 +75,61 @@ fn match_device(device: Option) -> rodio::Device { list_outputs(); exit(0) } - 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; + for host in cpal::available_hosts() { + let found_devices = cpal::host_from_id(host) + .expect(&format!("Host {:?} not found", host)) + .output_devices().expect(&format!("Cannot get list of output devices of Host: {:?}", host)); + for d in found_devices { + if d.name().expect("cannot get output name") == device_name { + return d; + } } } println!("No output sink matching '{}' found.", device_name); exit(0) - } + }, None => return get_default_device(), } } +fn get_host_id(device: &Option) -> HostId { + match device { + Some(device_name) => { + if *device_name == "?".to_string() { + list_outputs(); + exit(0) + } + for host in cpal::available_hosts() { + let found_devices = cpal::host_from_id(host) + .expect(&format!("Host {:?} not found", host)) + .output_devices().expect(&format!("Cannot get list of output devices of Host: {:?}", host)); + for d in found_devices { + if d.name().expect("cannot get output name") == *device_name { + return host; + } + } + } + println!("No output sink matching '{}' found.", device_name); + exit(0) + }, + None => return cpal::default_host().id(), + } +} + impl Open for RodioSink { fn open(device: Option) -> RodioSink { - debug!( - "Using rodio sink with cpal host: {:?}", - cpal::default_host().id() - ); + + + debug!("Using rodio sink with cpal host: {:?}", get_host_id(&device)); 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."); + 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, - stream: stream.0, - } + RodioSink { rodio_sink: sink, stream: stream.0 } } }