mirror of
https://github.com/librespot-org/librespot.git
synced 2025-02-06 17:47:10 +00:00
Address review comments
This commit is contained in:
parent
cea92a9c3a
commit
1ab5bac786
7 changed files with 55 additions and 39 deletions
connect/src
playback/src
src
|
@ -874,6 +874,7 @@ impl SpircTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
match update.typ() {
|
match update.typ() {
|
||||||
|
MessageType::kMessageTypeHello => self.notify(Some(ident)),
|
||||||
MessageType::kMessageTypeLoad => {
|
MessageType::kMessageTypeLoad => {
|
||||||
self.handle_load(update.state.get_or_default())?;
|
self.handle_load(update.state.get_or_default())?;
|
||||||
self.notify(None)
|
self.notify(None)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
|
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
|
||||||
use crate::config::AudioFormat;
|
use crate::config::{AudioFormat, SampleRate};
|
||||||
use crate::convert::Converter;
|
use crate::convert::Converter;
|
||||||
use crate::decoder::AudioPacket;
|
use crate::decoder::AudioPacket;
|
||||||
use crate::{NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE};
|
use crate::{COMMON_SAMPLE_RATES, NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE};
|
||||||
use alsa::device_name::HintIter;
|
use alsa::device_name::HintIter;
|
||||||
use alsa::pcm::{Access, Format, Frames, HwParams, PCM};
|
use alsa::pcm::{Access, Format, Frames, HwParams, PCM};
|
||||||
use alsa::{Direction, ValueOr};
|
use alsa::{Direction, ValueOr};
|
||||||
|
@ -12,22 +12,6 @@ use thiserror::Error;
|
||||||
const OPTIMAL_NUM_PERIODS: Frames = 5;
|
const OPTIMAL_NUM_PERIODS: Frames = 5;
|
||||||
const MIN_NUM_PERIODS: Frames = 2;
|
const MIN_NUM_PERIODS: Frames = 2;
|
||||||
|
|
||||||
const COMMON_SAMPLE_RATES: [u32; 14] = [
|
|
||||||
8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600,
|
|
||||||
768000,
|
|
||||||
];
|
|
||||||
|
|
||||||
const SUPPORTED_SAMPLE_RATES: [u32; 4] = [44100, 48000, 88200, 96000];
|
|
||||||
|
|
||||||
const FORMATS: [AudioFormat; 6] = [
|
|
||||||
AudioFormat::S16,
|
|
||||||
AudioFormat::S24,
|
|
||||||
AudioFormat::S24_3,
|
|
||||||
AudioFormat::S32,
|
|
||||||
AudioFormat::F32,
|
|
||||||
AudioFormat::F64,
|
|
||||||
];
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
enum AlsaError {
|
enum AlsaError {
|
||||||
#[error("<AlsaSink> Device {device} Unsupported Format {alsa_format} ({format:?}), {e}, Supported Format(s): {supported_formats:?}")]
|
#[error("<AlsaSink> Device {device} Unsupported Format {alsa_format} ({format:?}), {e}, Supported Format(s): {supported_formats:?}")]
|
||||||
|
@ -134,25 +118,22 @@ fn list_compatible_devices() -> SinkResult<()> {
|
||||||
{
|
{
|
||||||
let mut supported_formats_and_samplerates = String::new();
|
let mut supported_formats_and_samplerates = String::new();
|
||||||
|
|
||||||
for format in FORMATS.iter() {
|
for format in AudioFormat::default().into_iter() {
|
||||||
let hwp = hwp.clone();
|
let hwp = hwp.clone();
|
||||||
|
|
||||||
if hwp.set_format((*format).into()).is_ok() {
|
if hwp.set_format(format.into()).is_ok() {
|
||||||
let sample_rates: Vec<String> = SUPPORTED_SAMPLE_RATES
|
let sample_rates: Vec<String> = SampleRate::default()
|
||||||
.iter()
|
.into_iter()
|
||||||
.filter_map(|sample_rate| {
|
.filter_map(|sample_rate| {
|
||||||
let hwp = hwp.clone();
|
let hwp = hwp.clone();
|
||||||
if hwp
|
if hwp
|
||||||
.set_rate(*sample_rate, ValueOr::Nearest)
|
.set_rate(
|
||||||
|
sample_rate.as_u32(),
|
||||||
|
ValueOr::Nearest,
|
||||||
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
match *sample_rate {
|
Some(sample_rate.to_string())
|
||||||
44100 => Some("44.1kHz".to_string()),
|
|
||||||
48000 => Some("48kHz".to_string()),
|
|
||||||
88200 => Some("88.2kHz".to_string()),
|
|
||||||
96000 => Some("96kHz".to_string()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -161,7 +142,7 @@ fn list_compatible_devices() -> SinkResult<()> {
|
||||||
|
|
||||||
if !sample_rates.is_empty() {
|
if !sample_rates.is_empty() {
|
||||||
let format_and_sample_rates =
|
let format_and_sample_rates =
|
||||||
if *format == AudioFormat::S24_3 {
|
if format == AudioFormat::S24_3 {
|
||||||
format!(
|
format!(
|
||||||
"\n\t\tFormat: {format:?} Sample Rate(s): {}",
|
"\n\t\tFormat: {format:?} Sample Rate(s): {}",
|
||||||
sample_rates.join(", ")
|
sample_rates.join(", ")
|
||||||
|
@ -379,10 +360,10 @@ impl AlsaSink {
|
||||||
let alsa_format = self.format.into();
|
let alsa_format = self.format.into();
|
||||||
|
|
||||||
hwp.set_format(alsa_format).map_err(|e| {
|
hwp.set_format(alsa_format).map_err(|e| {
|
||||||
let supported_formats = FORMATS
|
let supported_formats = AudioFormat::default()
|
||||||
.iter()
|
.into_iter()
|
||||||
.filter_map(|f| {
|
.filter_map(|f| {
|
||||||
if hwp.test_format((*f).into()).is_ok() {
|
if hwp.test_format(f.into()).is_ok() {
|
||||||
Some(format!("{f:?}"))
|
Some(format!("{f:?}"))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -151,6 +151,17 @@ pub enum SampleRate {
|
||||||
Hz96000,
|
Hz96000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for SampleRate {
|
||||||
|
type Item = SampleRate;
|
||||||
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
use SampleRate::*;
|
||||||
|
|
||||||
|
vec![Hz44100, Hz48000, Hz88200, Hz96000].into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for SampleRate {
|
impl FromStr for SampleRate {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
|
@ -302,6 +313,17 @@ pub enum AudioFormat {
|
||||||
S16,
|
S16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for AudioFormat {
|
||||||
|
type Item = AudioFormat;
|
||||||
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
use AudioFormat::*;
|
||||||
|
|
||||||
|
vec![F64, F32, S32, S24, S24_3, S16].into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for AudioFormat {
|
impl FromStr for AudioFormat {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
|
|
@ -25,6 +25,13 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,7 @@ impl Player {
|
||||||
{
|
{
|
||||||
let (cmd_tx, cmd_rx) = mpsc::unbounded_channel();
|
let (cmd_tx, cmd_rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
let player_id = PLAYER_COUNTER.fetch_add(1, Ordering::AcqRel);
|
let player_id = PLAYER_COUNTER.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
let thread_name = format!("player:{}", player_id);
|
let thread_name = format!("player:{}", player_id);
|
||||||
|
|
||||||
|
@ -1954,7 +1954,7 @@ impl PlayerInternal {
|
||||||
// The player increments the player id when it gets it...
|
// The player increments the player id when it gets it...
|
||||||
let thread_name = format!(
|
let thread_name = format!(
|
||||||
"loader:{}:{}",
|
"loader:{}:{}",
|
||||||
PLAYER_COUNTER.load(Ordering::Relaxed).saturating_sub(1),
|
PLAYER_COUNTER.load(Ordering::SeqCst).saturating_sub(1),
|
||||||
spotify_id.to_uri().unwrap_or_default()
|
spotify_id.to_uri().unwrap_or_default()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,7 @@ impl StereoInterleavedResampler {
|
||||||
debug!("Interpolation Quality: {interpolation_quality}");
|
debug!("Interpolation Quality: {interpolation_quality}");
|
||||||
|
|
||||||
// The player increments the player id when it gets it...
|
// The player increments the player id when it gets it...
|
||||||
let player_id = PLAYER_COUNTER.load(Ordering::Relaxed).saturating_sub(1);
|
let player_id = PLAYER_COUNTER.load(Ordering::SeqCst).saturating_sub(1);
|
||||||
|
|
||||||
let left_thread_name = format!("resampler:{player_id}:left");
|
let left_thread_name = format!("resampler:{player_id}:left");
|
||||||
let right_thread_name = format!("resampler:{player_id}:right");
|
let right_thread_name = format!("resampler:{player_id}:right");
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
|
|
||||||
use std::{collections::HashMap, process::exit, process::Command, sync::atomic::Ordering, thread};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
process::{exit, Command},
|
||||||
|
sync::atomic::Ordering,
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
use librespot::{
|
use librespot::{
|
||||||
metadata::audio::UniqueFields,
|
metadata::audio::UniqueFields,
|
||||||
|
@ -18,7 +23,7 @@ impl EventHandler {
|
||||||
// The player increments the player id when it gets it...
|
// The player increments the player id when it gets it...
|
||||||
let thread_name = format!(
|
let thread_name = format!(
|
||||||
"event-handler:{}",
|
"event-handler:{}",
|
||||||
PLAYER_COUNTER.load(Ordering::Relaxed).saturating_sub(1)
|
PLAYER_COUNTER.load(Ordering::SeqCst).saturating_sub(1)
|
||||||
);
|
);
|
||||||
|
|
||||||
let builder = thread::Builder::new().name(thread_name.clone());
|
let builder = thread::Builder::new().name(thread_name.clone());
|
||||||
|
|
Loading…
Reference in a new issue