mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Put CommonSampleRates to some use and clean up backend imports
This commit is contained in:
parent
242e68a98c
commit
25425dab5c
10 changed files with 123 additions and 72 deletions
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue