mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Fully implement CommonSampleRates
This commit is contained in:
parent
1ab5bac786
commit
15e2b441aa
2 changed files with 132 additions and 3 deletions
|
@ -2,7 +2,7 @@ use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
|
|||
use crate::config::{AudioFormat, SampleRate};
|
||||
use crate::convert::Converter;
|
||||
use crate::decoder::AudioPacket;
|
||||
use crate::{COMMON_SAMPLE_RATES, NUM_CHANNELS, SAMPLE_RATE as DECODER_SAMPLE_RATE};
|
||||
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};
|
||||
|
@ -35,7 +35,7 @@ enum AlsaError {
|
|||
UnsupportedSampleRate {
|
||||
device: String,
|
||||
samplerate: u32,
|
||||
supported_rates: Vec<u32>,
|
||||
supported_rates: Vec<String>,
|
||||
e: alsa::Error,
|
||||
},
|
||||
|
||||
|
@ -382,9 +382,21 @@ impl AlsaSink {
|
|||
|
||||
hwp.set_rate(self.sample_rate, ValueOr::Nearest)
|
||||
.map_err(|e| {
|
||||
let common_sample_rates = CommonSampleRates::default();
|
||||
|
||||
let supported_rates = (hwp.get_rate_min().unwrap_or_default()
|
||||
..=hwp.get_rate_max().unwrap_or_default())
|
||||
.filter(|r| COMMON_SAMPLE_RATES.contains(r) && hwp.test_rate(*r).is_ok())
|
||||
.filter_map(|r| {
|
||||
if common_sample_rates.contains(r) && hwp.test_rate(r).is_ok() {
|
||||
Some(
|
||||
CommonSampleRates::try_from(r)
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
AlsaError::UnsupportedSampleRate {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
|
@ -39,3 +42,117 @@ pub fn db_to_ratio(db: f64) -> f64 {
|
|||
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]
|
||||
Hz8000,
|
||||
Hz11025,
|
||||
Hz16000,
|
||||
Hz22050,
|
||||
Hz44100,
|
||||
Hz48000,
|
||||
Hz88200,
|
||||
Hz96000,
|
||||
Hz176400,
|
||||
Hz192000,
|
||||
Hz352800,
|
||||
Hz384000,
|
||||
Hz705600,
|
||||
Hz768000,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for CommonSampleRates {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
use CommonSampleRates::*;
|
||||
|
||||
match value {
|
||||
8000 => Ok(Hz8000),
|
||||
11025 => Ok(Hz11025),
|
||||
16000 => Ok(Hz16000),
|
||||
22050 => Ok(Hz22050),
|
||||
44100 => Ok(Hz44100),
|
||||
48000 => Ok(Hz48000),
|
||||
88200 => Ok(Hz88200),
|
||||
96000 => Ok(Hz96000),
|
||||
176400 => Ok(Hz176400),
|
||||
192000 => Ok(Hz192000),
|
||||
352800 => Ok(Hz352800),
|
||||
384000 => Ok(Hz384000),
|
||||
705600 => Ok(Hz705600),
|
||||
768000 => Ok(Hz768000),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CommonSampleRates {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use CommonSampleRates::*;
|
||||
|
||||
let rate_str = match self {
|
||||
Hz8000 => "8kHz",
|
||||
Hz11025 => "11.025kHz",
|
||||
Hz16000 => "16kHz",
|
||||
Hz22050 => "22.05kHz",
|
||||
Hz44100 => "44.1kHz",
|
||||
Hz48000 => "48kHz",
|
||||
Hz88200 => "88.2kHz",
|
||||
Hz96000 => "96kHz",
|
||||
Hz176400 => "176.4kHz",
|
||||
Hz192000 => "192kHz",
|
||||
Hz352800 => "352.8kHz",
|
||||
Hz384000 => "384kHz",
|
||||
Hz705600 => "705.6kHz",
|
||||
Hz768000 => "768kHz",
|
||||
};
|
||||
|
||||
write!(f, "{}", rate_str)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for CommonSampleRates {
|
||||
type Item = CommonSampleRates;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
use CommonSampleRates::*;
|
||||
|
||||
vec![
|
||||
Hz8000, Hz11025, Hz16000, Hz22050, Hz44100, Hz48000, Hz88200, Hz96000, Hz176400,
|
||||
Hz192000, Hz352800, Hz384000, Hz705600, Hz768000,
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl CommonSampleRates {
|
||||
pub fn as_u32(&self) -> u32 {
|
||||
use CommonSampleRates::*;
|
||||
|
||||
match self {
|
||||
Hz8000 => 8000,
|
||||
Hz11025 => 11025,
|
||||
Hz16000 => 16000,
|
||||
Hz22050 => 22050,
|
||||
Hz44100 => 44100,
|
||||
Hz48000 => 48000,
|
||||
Hz88200 => 88200,
|
||||
Hz96000 => 96000,
|
||||
Hz176400 => 176400,
|
||||
Hz192000 => 192000,
|
||||
Hz352800 => 352800,
|
||||
Hz384000 => 384000,
|
||||
Hz705600 => 705600,
|
||||
Hz768000 => 768000,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains(&self, rate: u32) -> bool {
|
||||
self.into_iter().any(|r| r.as_u32() == rate)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue