1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-03 09:49:31 +02:00

perf: inline functions in the audio hot path

This commit is contained in:
Roderick van Domburg 2025-08-14 00:53:59 +02:00
parent 9f37808851
commit 19f635f90b
No known key found for this signature in database
GPG key ID: 607FA06CB5236AE0
12 changed files with 18 additions and 5 deletions

View file

@ -452,6 +452,7 @@ impl Sink for AlsaSink {
} }
impl SinkAsBytes for AlsaSink { impl SinkAsBytes for AlsaSink {
#[inline]
fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> {
let mut start_index = 0; let mut start_index = 0;
let data_len = data.len(); let data_len = data.len();

View file

@ -171,6 +171,7 @@ impl Drop for GstreamerSink {
} }
impl SinkAsBytes for GstreamerSink { impl SinkAsBytes for GstreamerSink {
#[inline]
fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> {
if let Some(async_error) = &*self.async_error.lock() { if let Some(async_error) = &*self.async_error.lock() {
return Err(SinkError::OnWrite(async_error.to_string())); return Err(SinkError::OnWrite(async_error.to_string()));

View file

@ -46,6 +46,7 @@ fn mk_sink<S: Sink + Open + 'static>(device: Option<String>, format: AudioFormat
// reuse code for various backends // reuse code for various backends
macro_rules! sink_as_bytes { macro_rules! sink_as_bytes {
() => { () => {
#[inline]
fn write(&mut self, packet: AudioPacket, converter: &mut Converter) -> SinkResult<()> { fn write(&mut self, packet: AudioPacket, converter: &mut Converter) -> SinkResult<()> {
use crate::convert::i24; use crate::convert::i24;
use zerocopy::IntoBytes; use zerocopy::IntoBytes;

View file

@ -96,6 +96,7 @@ impl Sink for StdoutSink {
} }
impl SinkAsBytes for StdoutSink { impl SinkAsBytes for StdoutSink {
#[inline]
fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> {
self.output self.output
.as_deref_mut() .as_deref_mut()

View file

@ -137,6 +137,7 @@ impl Sink for PulseAudioSink {
} }
impl SinkAsBytes for PulseAudioSink { impl SinkAsBytes for PulseAudioSink {
#[inline]
fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> {
let sink = self.sink.as_mut().ok_or(PulseError::NotConnected)?; let sink = self.sink.as_mut().ok_or(PulseError::NotConnected)?;

View file

@ -139,6 +139,7 @@ impl Sink for SubprocessSink {
} }
impl SinkAsBytes for SubprocessSink { impl SinkAsBytes for SubprocessSink {
#[inline]
fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> {
// We get one attempted restart per write. // We get one attempted restart per write.
// We don't want to get stuck in a restart loop. // We don't want to get stuck in a restart loop.

View file

@ -42,7 +42,6 @@ impl Converter {
const SHIFT_S24: u8 = 23; // 24-bit: 2^23 = 8388608 const SHIFT_S24: u8 = 23; // 24-bit: 2^23 = 8388608
const SHIFT_S32: u8 = 31; // 32-bit: 2^31 = 2147483648 const SHIFT_S32: u8 = 31; // 32-bit: 2^31 = 2147483648
/// Additional bit shifts needed to scale from 16-bit to higher bit depths. /// Additional bit shifts needed to scale from 16-bit to higher bit depths.
/// These are the differences between the base shift amounts above. /// These are the differences between the base shift amounts above.
const SHIFT_16_TO_24: u8 = Self::SHIFT_S24 - Self::SHIFT_S16; // 23 - 15 = 8 const SHIFT_16_TO_24: u8 = Self::SHIFT_S24 - Self::SHIFT_S16; // 23 - 15 = 8

View file

@ -36,6 +36,7 @@ pub enum AudioPacket {
} }
impl AudioPacket { impl AudioPacket {
#[inline]
pub fn samples(&self) -> AudioPacketResult<&[f64]> { pub fn samples(&self) -> AudioPacketResult<&[f64]> {
match self { match self {
AudioPacket::Samples(s) => Ok(s), AudioPacket::Samples(s) => Ok(s),
@ -43,6 +44,7 @@ impl AudioPacket {
} }
} }
#[inline]
pub fn raw(&self) -> AudioPacketResult<&[u8]> { pub fn raw(&self) -> AudioPacketResult<&[u8]> {
match self { match self {
AudioPacket::Raw(d) => Ok(d), AudioPacket::Raw(d) => Ok(d),
@ -50,6 +52,7 @@ impl AudioPacket {
} }
} }
#[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
match self { match self {
AudioPacket::Samples(s) => s.is_empty(), AudioPacket::Samples(s) => s.is_empty(),

View file

@ -131,6 +131,7 @@ impl SymphoniaDecoder {
} }
} }
#[inline]
fn ts_to_ms(&self, ts: u64) -> u32 { fn ts_to_ms(&self, ts: u64) -> u32 {
match self.decoder.codec_params().time_base { match self.decoder.codec_params().time_base {
Some(time_base) => { Some(time_base) => {

View file

@ -25,6 +25,7 @@ pub trait VolumeGetter {
} }
impl VolumeGetter for NoOpVolume { impl VolumeGetter for NoOpVolume {
#[inline]
fn attenuation_factor(&self) -> f64 { fn attenuation_factor(&self) -> f64 {
1.0 1.0
} }

View file

@ -48,6 +48,7 @@ impl SoftMixer {
struct SoftVolume(Arc<AtomicU64>); struct SoftVolume(Arc<AtomicU64>);
impl VolumeGetter for SoftVolume { impl VolumeGetter for SoftVolume {
#[inline]
fn attenuation_factor(&self) -> f64 { fn attenuation_factor(&self) -> f64 {
f64::from_bits(self.0.load(Ordering::Relaxed)) f64::from_bits(self.0.load(Ordering::Relaxed))
} }

View file

@ -279,10 +279,12 @@ impl PlayerEvent {
pub type PlayerEventChannel = mpsc::UnboundedReceiver<PlayerEvent>; pub type PlayerEventChannel = mpsc::UnboundedReceiver<PlayerEvent>;
#[inline]
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)
} }
#[inline]
pub fn ratio_to_db(ratio: f64) -> f64 { pub fn ratio_to_db(ratio: f64) -> f64 {
ratio.log10() * DB_VOLTAGE_RATIO ratio.log10() * DB_VOLTAGE_RATIO
} }