diff --git a/playback/src/audio_backend/alsa.rs b/playback/src/audio_backend/alsa.rs index 86010e50..8b138618 100644 --- a/playback/src/audio_backend/alsa.rs +++ b/playback/src/audio_backend/alsa.rs @@ -1,11 +1,18 @@ use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; -use crate::config::{AudioFormat, SampleRate}; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::{CommonSampleRates, NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE}; -use alsa::device_name::HintIter; -use alsa::pcm::{Access, Format, Frames, HwParams, PCM}; -use alsa::{Direction, ValueOr}; + +use crate::{ + config::{AudioFormat, SampleRate}, + convert::Converter, + decoder::AudioPacket, + CommonSampleRates, NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE, +}; + +use alsa::{ + device_name::HintIter, + pcm::{Access, Format, Frames, HwParams, PCM}, + Direction, ValueOr, +}; + use std::process::exit; use thiserror::Error; @@ -204,7 +211,12 @@ impl Open for AlsaSink { let latency_scale_factor = DECODER_SAMPLE_RATE as f64 / sample_rate as f64; - info!("Using AlsaSink with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using AlsaSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); Self { pcm: None, diff --git a/playback/src/audio_backend/gstreamer.rs b/playback/src/audio_backend/gstreamer.rs index ec748a98..f70ee37f 100644 --- a/playback/src/audio_backend/gstreamer.rs +++ b/playback/src/audio_backend/gstreamer.rs @@ -13,7 +13,9 @@ use std::sync::Arc; use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; -use crate::{config::AudioFormat, convert::Converter, decoder::AudioPacket, NUM_CHANNELS}; +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS, +}; pub struct GstreamerSink { appsrc: gst_app::AppSrc, @@ -25,7 +27,13 @@ pub struct GstreamerSink { impl Open for GstreamerSink { fn open(device: Option, format: AudioFormat, sample_rate: u32) -> Self { - info!("Using GStreamer sink with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using GstreamerSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); + gst::init().expect("failed to init GStreamer!"); let gst_format = match format { diff --git a/playback/src/audio_backend/jackaudio.rs b/playback/src/audio_backend/jackaudio.rs index 1122a427..1236e1f3 100644 --- a/playback/src/audio_backend/jackaudio.rs +++ b/playback/src/audio_backend/jackaudio.rs @@ -1,11 +1,13 @@ use super::{Open, Sink, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::NUM_CHANNELS; + +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS, +}; + use jack::{ AsyncClient, AudioOut, Client, ClientOptions, Control, Port, ProcessHandler, ProcessScope, }; + use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; pub struct JackSink { @@ -42,9 +44,12 @@ impl Open for JackSink { if format != AudioFormat::F32 { warn!("JACK currently does not support {format:?} output"); } + info!( - "Using JACK sink with format {:?}, sample rate: {sample_rate}", - AudioFormat::F32 + "Using JackSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() ); let client_name = client_name.unwrap_or_else(|| "librespot".to_string()); diff --git a/playback/src/audio_backend/pipe.rs b/playback/src/audio_backend/pipe.rs index 05db4953..6c0751e7 100644 --- a/playback/src/audio_backend/pipe.rs +++ b/playback/src/audio_backend/pipe.rs @@ -1,11 +1,12 @@ use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; +use crate::{config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates}; + +use std::{ + fs::OpenOptions, + io::{self, Write}, + process::exit, +}; -use std::fs::OpenOptions; -use std::io::{self, Write}; -use std::process::exit; use thiserror::Error; #[derive(Debug, Error)] @@ -48,7 +49,12 @@ impl Open for StdoutSink { exit(0); } - info!("Using StdoutSink (pipe) with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using StdoutSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); Self { output: None, diff --git a/playback/src/audio_backend/portaudio.rs b/playback/src/audio_backend/portaudio.rs index 178c8386..2868926b 100644 --- a/playback/src/audio_backend/portaudio.rs +++ b/playback/src/audio_backend/portaudio.rs @@ -1,12 +1,15 @@ use super::{Open, Sink, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::NUM_CHANNELS; -use portaudio_rs::device::{get_default_output_index, DeviceIndex, DeviceInfo}; -use portaudio_rs::stream::*; -use std::process::exit; -use std::time::Duration; + +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS, +}; + +use portaudio_rs::{ + device::{get_default_output_index, DeviceIndex, DeviceInfo}, + stream::*, +}; + +use std::{process::exit, time::Duration}; pub enum PortAudioSink<'a> { F32( @@ -55,7 +58,12 @@ fn find_output(device: &str) -> Option { impl<'a> Open for PortAudioSink<'a> { fn open(device: Option, format: AudioFormat, sample_rate: u32) -> PortAudioSink<'a> { - info!("Using PortAudio sink with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using PortAudioSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); portaudio_rs::initialize().unwrap(); diff --git a/playback/src/audio_backend/pulseaudio.rs b/playback/src/audio_backend/pulseaudio.rs index 25ad8c5d..b43f1886 100644 --- a/playback/src/audio_backend/pulseaudio.rs +++ b/playback/src/audio_backend/pulseaudio.rs @@ -1,8 +1,10 @@ use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::{NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE}; + +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS, + SAMPLE_RATE as DECODER_SAMPLE_RATE, +}; + use libpulse_binding::{self as pulse, error::PAErr, stream::Direction}; use libpulse_simple_binding::Simple; use std::env; @@ -76,7 +78,12 @@ impl Open for PulseAudioSink { format }; - info!("Using PulseAudioSink with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using PulseAudioSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); let sample_spec = pulse::sample::Spec { format: format.into(), diff --git a/playback/src/audio_backend/rodio.rs b/playback/src/audio_backend/rodio.rs index 05a060cb..956014a4 100644 --- a/playback/src/audio_backend/rodio.rs +++ b/playback/src/audio_backend/rodio.rs @@ -1,15 +1,13 @@ -use std::process::exit; -use std::thread; -use std::time::Duration; +use std::{process::exit, thread, time::Duration}; use cpal::traits::{DeviceTrait, HostTrait}; use thiserror::Error; use super::{Sink, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::NUM_CHANNELS; + +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS, +}; #[cfg(all( feature = "rodiojack-backend", @@ -176,15 +174,18 @@ pub fn open( format: AudioFormat, sample_rate: u32, ) -> RodioSink { - info!( - "Using Rodio sink with format {format:?} and cpal host: {}", - host.id().name() - ); - if format != AudioFormat::S16 && format != AudioFormat::F32 { unimplemented!("Rodio currently only supports F32 and S16 formats"); } + info!( + "Using RodioSink with format: {format:?}, sample rate: {}, and cpal host: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string(), + host.id().name(), + ); + let (sink, stream) = create_sink(&host, device).unwrap(); debug!("Rodio sink was created"); diff --git a/playback/src/audio_backend/sdl.rs b/playback/src/audio_backend/sdl.rs index ce7c146b..a3856a25 100644 --- a/playback/src/audio_backend/sdl.rs +++ b/playback/src/audio_backend/sdl.rs @@ -1,11 +1,12 @@ use super::{Open, Sink, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::{NUM_CHANNELS, SAMPLE_RATE}; + +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS, + SAMPLE_RATE, +}; + use sdl2::audio::{AudioQueue, AudioSpecDesired}; -use std::thread; -use std::time::Duration; +use std::{thread, time::Duration}; pub enum SdlSink { F32(AudioQueue), @@ -15,7 +16,12 @@ pub enum SdlSink { impl Open for SdlSink { fn open(device: Option, format: AudioFormat, sample_rate: u32) -> Self { - info!("Using SDL sink with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using SdlSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); if device.is_some() { warn!("SDL sink does not support specifying a device name"); diff --git a/playback/src/audio_backend/subprocess.rs b/playback/src/audio_backend/subprocess.rs index 15778dbe..21f9a291 100644 --- a/playback/src/audio_backend/subprocess.rs +++ b/playback/src/audio_backend/subprocess.rs @@ -1,11 +1,13 @@ use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use shell_words::split; -use std::io::{ErrorKind, Write}; -use std::process::{exit, Child, Command, Stdio}; +use crate::{config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates}; + +use std::{ + io::{ErrorKind, Write}, + process::{exit, Child, Command, Stdio}, +}; + +use shell_words::split; use thiserror::Error; #[derive(Debug, Error)] @@ -72,7 +74,12 @@ impl Open for SubprocessSink { exit(0); } - info!("Using SubprocessSink with format: {format:?}, sample rate: {sample_rate}"); + info!( + "Using SubprocessSink with format: {format:?}, sample rate: {}", + CommonSampleRates::try_from(sample_rate) + .unwrap_or_default() + .to_string() + ); Self { shell_command, diff --git a/playback/src/lib.rs b/playback/src/lib.rs index ed206de0..c7d8297d 100644 --- a/playback/src/lib.rs +++ b/playback/src/lib.rs @@ -28,13 +28,6 @@ pub const SAMPLES_PER_SECOND: u32 = SAMPLE_RATE * NUM_CHANNELS as u32; pub const PAGES_PER_MS: f64 = SAMPLE_RATE as f64 / 1000.0; pub const MS_PER_PAGE: f64 = 1000.0 / SAMPLE_RATE as f64; -// not used by all backends -#[allow(dead_code)] -const COMMON_SAMPLE_RATES: [u32; 14] = [ - 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, - 768000, -]; - pub fn db_to_ratio(db: f64) -> f64 { f64::powf(10.0, db / DB_VOLTAGE_RATIO) } @@ -43,8 +36,6 @@ pub fn ratio_to_db(ratio: f64) -> f64 { ratio.log10() * DB_VOLTAGE_RATIO } -// not used by all backends -#[allow(dead_code)] #[derive(Copy, Clone, Debug, Default)] pub enum CommonSampleRates { #[default]