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 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,

View file

@ -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<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!");
let gst_format = match format {

View file

@ -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());

View file

@ -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,

View file

@ -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<DeviceIndex> {
impl<'a> Open for 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();

View file

@ -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(),

View file

@ -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");

View file

@ -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<f32>),
@ -15,7 +16,12 @@ pub enum SdlSink {
impl Open for SdlSink {
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() {
warn!("SDL sink does not support specifying a device name");

View file

@ -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,

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 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]