Quick minimal hack to get latest rodio working.

This commit is contained in:
Will Stott 2020-12-02 19:45:31 +00:00
parent 89cafd7c86
commit 8ff1dc24bd
3 changed files with 878 additions and 121 deletions

891
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,88 +1,110 @@
use super::{Open, Sink}; use super::{Open, Sink};
extern crate cpal; extern crate cpal;
extern crate rodio; extern crate rodio;
use cpal::traits::{DeviceTrait, HostTrait};
use std::process::exit; use std::process::exit;
use std::{io, thread, time}; use std::{io, thread, time};
pub struct RodioSink { pub struct RodioSink {
rodio_sink: rodio::Sink, 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) { fn list_formats(ref device: &rodio::Device) {
let default_fmt = match device.default_output_format() { let default_fmt = match device.default_output_config() {
Ok(fmt) => cpal::SupportedFormat::from(fmt), Ok(fmt) => cpal::SupportedStreamConfig::from(fmt),
Err(e) => { Err(e) => {
warn!("Error getting default rodio::Sink format: {:?}", e); warn!("Error getting default rodio::Sink config: {}", e);
return; 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(), Ok(f) => f.peekable(),
Err(e) => { Err(e) => {
warn!("Error getting supported rodio::Sink formats: {:?}", e); warn!("Error getting supported rodio::Sink configs: {}", e);
return; return;
} }
}; };
if output_formats.peek().is_some() { if output_configs.peek().is_some() {
debug!(" Available formats:"); debug!(" Available configs:");
for format in output_formats { for format in output_configs {
let s = format!( debug!(" {:?}", 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);
}
} }
} }
} }
fn list_outputs() { fn list_outputs() {
let default_device = rodio::default_output_device().unwrap(); let default_device = get_default_device();
println!("Default Audio Device:\n {}", default_device.name()); let default_device_name = default_device.name().expect("cannot get output name");
println!("Default Audio Device:\n {}", default_device_name);
list_formats(&default_device); list_formats(&default_device);
println!("Other Available Audio Devices:"); println!("Other Available Audio Devices:");
for device in rodio::output_devices() { for device in cpal::default_host()
if device.name() != default_device.name() { .output_devices()
println!(" {}", device.name()); .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); list_formats(&device);
} }
} }
} }
impl Open for RodioSink { fn get_default_device() -> rodio::Device {
fn open(device: Option<String>) -> RodioSink { cpal::default_host()
debug!("Using rodio sink"); .default_output_device()
.expect("no default output device available")
let mut rodio_device = rodio::default_output_device().expect("no output device available"); }
if device.is_some() {
let device_name = device.unwrap();
fn match_device(device: Option<String>) -> rodio::Device {
match device {
Some(device_name) => {
if device_name == "?".to_string() { if device_name == "?".to_string() {
list_outputs(); list_outputs();
exit(0) exit(0)
} }
let mut found = false; for d in cpal::default_host()
for d in rodio::output_devices() { .output_devices()
if d.name() == device_name { .expect("cannot get list of output devices")
rodio_device = d; {
found = true; if d.name().expect("cannot get output name") == device_name {
break; return d;
} }
} }
if !found { println!("No output sink matching '{}' found.", device_name);
println!("No output sink matching '{}' found.", device_name); exit(0)
exit(0)
}
} }
let sink = rodio::Sink::new(&rodio_device); None => return get_default_device(),
}
}
RodioSink { rodio_sink: sink } 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,
stream: stream.0,
}
} }
} }