Put CommonSampleRates to some use and clean up backend imports

This commit is contained in:
JasonLG1979 2023-06-30 12:36:12 -05:00
parent 242e68a98c
commit 25425dab5c
10 changed files with 123 additions and 72 deletions

View file

@ -1,11 +1,18 @@
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
use crate::config::{AudioFormat, SampleRate};
use crate::convert::Converter; use crate::{
use crate::decoder::AudioPacket; config::{AudioFormat, SampleRate},
use crate::{CommonSampleRates, NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE}; convert::Converter,
use alsa::device_name::HintIter; decoder::AudioPacket,
use alsa::pcm::{Access, Format, Frames, HwParams, PCM}; CommonSampleRates, NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE,
use alsa::{Direction, ValueOr}; };
use alsa::{
device_name::HintIter,
pcm::{Access, Format, Frames, HwParams, PCM},
Direction, ValueOr,
};
use std::process::exit; use std::process::exit;
use thiserror::Error; use thiserror::Error;
@ -204,7 +211,12 @@ impl Open for AlsaSink {
let latency_scale_factor = DECODER_SAMPLE_RATE as f64 / sample_rate as f64; 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 { Self {
pcm: None, pcm: None,

View file

@ -13,7 +13,9 @@ use std::sync::Arc;
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; 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 { pub struct GstreamerSink {
appsrc: gst_app::AppSrc, appsrc: gst_app::AppSrc,
@ -25,7 +27,13 @@ pub struct GstreamerSink {
impl Open for GstreamerSink { impl Open for GstreamerSink {
fn open(device: Option<String>, format: AudioFormat, sample_rate: u32) -> Self { fn open(device: Option<String>, 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!"); gst::init().expect("failed to init GStreamer!");
let gst_format = match format { let gst_format = match format {

View file

@ -1,11 +1,13 @@
use super::{Open, Sink, SinkError, SinkResult}; use super::{Open, Sink, SinkError, SinkResult};
use crate::config::AudioFormat;
use crate::convert::Converter; use crate::{
use crate::decoder::AudioPacket; config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS,
use crate::NUM_CHANNELS; };
use jack::{ use jack::{
AsyncClient, AudioOut, Client, ClientOptions, Control, Port, ProcessHandler, ProcessScope, AsyncClient, AudioOut, Client, ClientOptions, Control, Port, ProcessHandler, ProcessScope,
}; };
use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
pub struct JackSink { pub struct JackSink {
@ -42,9 +44,12 @@ impl Open for JackSink {
if format != AudioFormat::F32 { if format != AudioFormat::F32 {
warn!("JACK currently does not support {format:?} output"); warn!("JACK currently does not support {format:?} output");
} }
info!( info!(
"Using JACK sink with format {:?}, sample rate: {sample_rate}", "Using JackSink with format: {format:?}, sample rate: {}",
AudioFormat::F32 CommonSampleRates::try_from(sample_rate)
.unwrap_or_default()
.to_string()
); );
let client_name = client_name.unwrap_or_else(|| "librespot".to_string()); let client_name = client_name.unwrap_or_else(|| "librespot".to_string());

View file

@ -1,11 +1,12 @@
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
use crate::config::AudioFormat; use crate::{config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates};
use crate::convert::Converter;
use crate::decoder::AudioPacket; 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; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -48,7 +49,12 @@ impl Open for StdoutSink {
exit(0); 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 { Self {
output: None, output: None,

View file

@ -1,12 +1,15 @@
use super::{Open, Sink, SinkError, SinkResult}; use super::{Open, Sink, SinkError, SinkResult};
use crate::config::AudioFormat;
use crate::convert::Converter; use crate::{
use crate::decoder::AudioPacket; config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS,
use crate::NUM_CHANNELS; };
use portaudio_rs::device::{get_default_output_index, DeviceIndex, DeviceInfo};
use portaudio_rs::stream::*; use portaudio_rs::{
use std::process::exit; device::{get_default_output_index, DeviceIndex, DeviceInfo},
use std::time::Duration; stream::*,
};
use std::{process::exit, time::Duration};
pub enum PortAudioSink<'a> { pub enum PortAudioSink<'a> {
F32( F32(
@ -55,7 +58,12 @@ fn find_output(device: &str) -> Option<DeviceIndex> {
impl<'a> Open for PortAudioSink<'a> { impl<'a> Open for PortAudioSink<'a> {
fn open(device: Option<String>, format: AudioFormat, sample_rate: u32) -> PortAudioSink<'a> { fn open(device: Option<String>, 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(); portaudio_rs::initialize().unwrap();

View file

@ -1,8 +1,10 @@
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
use crate::config::AudioFormat;
use crate::convert::Converter; use crate::{
use crate::decoder::AudioPacket; config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS,
use crate::{NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE}; SAMPLE_RATE as DECODER_SAMPLE_RATE,
};
use libpulse_binding::{self as pulse, error::PAErr, stream::Direction}; use libpulse_binding::{self as pulse, error::PAErr, stream::Direction};
use libpulse_simple_binding::Simple; use libpulse_simple_binding::Simple;
use std::env; use std::env;
@ -76,7 +78,12 @@ impl Open for PulseAudioSink {
format 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 { let sample_spec = pulse::sample::Spec {
format: format.into(), format: format.into(),

View file

@ -1,15 +1,13 @@
use std::process::exit; use std::{process::exit, thread, time::Duration};
use std::thread;
use std::time::Duration;
use cpal::traits::{DeviceTrait, HostTrait}; use cpal::traits::{DeviceTrait, HostTrait};
use thiserror::Error; use thiserror::Error;
use super::{Sink, SinkError, SinkResult}; use super::{Sink, SinkError, SinkResult};
use crate::config::AudioFormat;
use crate::convert::Converter; use crate::{
use crate::decoder::AudioPacket; config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS,
use crate::NUM_CHANNELS; };
#[cfg(all( #[cfg(all(
feature = "rodiojack-backend", feature = "rodiojack-backend",
@ -176,15 +174,18 @@ pub fn open(
format: AudioFormat, format: AudioFormat,
sample_rate: u32, sample_rate: u32,
) -> RodioSink { ) -> RodioSink {
info!(
"Using Rodio sink with format {format:?} and cpal host: {}",
host.id().name()
);
if format != AudioFormat::S16 && format != AudioFormat::F32 { if format != AudioFormat::S16 && format != AudioFormat::F32 {
unimplemented!("Rodio currently only supports F32 and S16 formats"); 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(); let (sink, stream) = create_sink(&host, device).unwrap();
debug!("Rodio sink was created"); debug!("Rodio sink was created");

View file

@ -1,11 +1,12 @@
use super::{Open, Sink, SinkError, SinkResult}; use super::{Open, Sink, SinkError, SinkResult};
use crate::config::AudioFormat;
use crate::convert::Converter; use crate::{
use crate::decoder::AudioPacket; config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates, NUM_CHANNELS,
use crate::{NUM_CHANNELS, SAMPLE_RATE}; SAMPLE_RATE,
};
use sdl2::audio::{AudioQueue, AudioSpecDesired}; use sdl2::audio::{AudioQueue, AudioSpecDesired};
use std::thread; use std::{thread, time::Duration};
use std::time::Duration;
pub enum SdlSink { pub enum SdlSink {
F32(AudioQueue<f32>), F32(AudioQueue<f32>),
@ -15,7 +16,12 @@ pub enum SdlSink {
impl Open for SdlSink { impl Open for SdlSink {
fn open(device: Option<String>, format: AudioFormat, sample_rate: u32) -> Self { fn open(device: Option<String>, 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() { if device.is_some() {
warn!("SDL sink does not support specifying a device name"); warn!("SDL sink does not support specifying a device name");

View file

@ -1,11 +1,13 @@
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; 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 crate::{config::AudioFormat, convert::Converter, decoder::AudioPacket, CommonSampleRates};
use std::process::{exit, Child, Command, Stdio};
use std::{
io::{ErrorKind, Write},
process::{exit, Child, Command, Stdio},
};
use shell_words::split;
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -72,7 +74,12 @@ impl Open for SubprocessSink {
exit(0); 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 { Self {
shell_command, shell_command,

View file

@ -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 PAGES_PER_MS: f64 = SAMPLE_RATE as f64 / 1000.0;
pub const MS_PER_PAGE: f64 = 1000.0 / SAMPLE_RATE as f64; 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 { pub fn db_to_ratio(db: f64) -> f64 {
f64::powf(10.0, db / DB_VOLTAGE_RATIO) 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 ratio.log10() * DB_VOLTAGE_RATIO
} }
// not used by all backends
#[allow(dead_code)]
#[derive(Copy, Clone, Debug, Default)] #[derive(Copy, Clone, Debug, Default)]
pub enum CommonSampleRates { pub enum CommonSampleRates {
#[default] #[default]