Skip to content

Commit 5e7abc2

Browse files
committed
feat: Skip track on failed sample rate changes
Adjust the error handling for failed changes of sample rate, such that we skip the track. In addition to skipping the track, if the error is due to sample rate changes not being supported by the current track, then mark the track as unavailable as it will not become playable (at least for the lifetime of the current program run).
1 parent 5ff3ffa commit 5e7abc2

File tree

10 files changed

+47
-18
lines changed

10 files changed

+47
-18
lines changed

playback/src/audio_backend/gstreamer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl Sink for GstreamerSink {
173173
}
174174

175175
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
176-
Err(SinkError::SampleRateChange("not implemented".into()))
176+
Err(SinkError::SampleRateChangeNotSupported)
177177
}
178178

179179
sink_as_bytes!();

playback/src/audio_backend/jackaudio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Sink for JackSink {
8282
}
8383

8484
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
85-
Err(SinkError::SampleRateChange("not implemented".into()))
85+
Err(SinkError::SampleRateChangeNotSupported)
8686
}
8787
}
8888

playback/src/audio_backend/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ pub enum SinkError {
1515
InvalidParams(String),
1616
#[error("Audio Sink Error Changing State: {0}")]
1717
StateChange(String),
18-
#[error("Audio Sink Error Updating Sample Rate: {0}")]
19-
SampleRateChange(String),
18+
#[error("Audio Sink Error Updating Sample Rate: Not Supported")]
19+
SampleRateChangeNotSupported,
2020
}
2121

2222
pub type SinkResult<T> = Result<T, SinkError>;

playback/src/audio_backend/pipe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl Sink for StdoutSink {
9393
}
9494

9595
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
96-
Err(SinkError::SampleRateChange("not implemented".into()))
96+
Err(SinkError::SampleRateChangeNotSupported)
9797
}
9898

9999
sink_as_bytes!();

playback/src/audio_backend/portaudio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl Sink for PortAudioSink<'_> {
175175
}
176176

177177
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
178-
Err(SinkError::SampleRateChange("not implemented".into()))
178+
Err(SinkError::SampleRateChangeNotSupported)
179179
}
180180
}
181181

playback/src/audio_backend/pulseaudio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl Sink for PulseAudioSink {
134134
}
135135

136136
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
137-
Err(SinkError::SampleRateChange("not implemented".into()))
137+
Err(SinkError::SampleRateChangeNotSupported)
138138
}
139139

140140
sink_as_bytes!();

playback/src/audio_backend/rodio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ impl Sink for RodioSink {
241241
}
242242

243243
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
244-
Err(SinkError::SampleRateChange("not implemented".into()))
244+
Err(SinkError::SampleRateChangeNotSupported)
245245
}
246246

247247
fn write(&mut self, packet: AudioPacket, converter: &mut Converter) -> SinkResult<()> {

playback/src/audio_backend/sdl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl Sink for SdlSink {
116116
}
117117

118118
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
119-
Err(SinkError::SampleRateChange("not implemented".into()))
119+
Err(SinkError::SampleRateChangeNotSupported)
120120
}
121121
}
122122

playback/src/audio_backend/subprocess.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl Sink for SubprocessSink {
136136
}
137137

138138
fn update_sample_rate(&mut self, _new_sample_rate: u32) -> SinkResult<()> {
139-
Err(SinkError::SampleRateChange("not implemented".into()))
139+
Err(SinkError::SampleRateChangeNotSupported)
140140
}
141141

142142
sink_as_bytes!();

playback/src/player.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ use futures_util::{
3737
};
3838
use librespot_metadata::{audio::UniqueFields, track::Tracks};
3939

40+
use crate::SAMPLES_PER_SECOND;
41+
use crate::audio_backend::SinkError;
4042
use symphonia::core::io::MediaSource;
4143
use symphonia::core::probe::Hint;
4244
use tokio::sync::{mpsc, oneshot};
4345

44-
use crate::SAMPLES_PER_SECOND;
45-
4646
const PRELOAD_NEXT_TRACK_BEFORE_END_DURATION_MS: u32 = 30000;
4747
pub const DB_VOLTAGE_RATIO: f64 = 20.0;
4848
pub const PCM_AT_0DBFS: f64 = 1.0;
@@ -1925,12 +1925,41 @@ impl PlayerInternal {
19251925
self.sink_sample_rate, loaded_track.sample_rate
19261926
);
19271927

1928-
if let Err(e) = self.sink.update_sample_rate(loaded_track.sample_rate) {
1929-
error!(
1930-
"Failed to update sink sample rate: {e}. Track playback may be distorted."
1931-
);
1932-
} else {
1933-
self.sink_sample_rate = loaded_track.sample_rate;
1928+
match self.sink.update_sample_rate(loaded_track.sample_rate) {
1929+
Ok(()) => {
1930+
self.sink_sample_rate = loaded_track.sample_rate;
1931+
}
1932+
Err(e) => {
1933+
error!("{e}");
1934+
1935+
let reaction_event = match e {
1936+
SinkError::SampleRateChangeNotSupported => {
1937+
// The sink does not support changing its sample rate; this track
1938+
// will never be playable.
1939+
PlayerEvent::Unavailable {
1940+
track_id: track_id.clone(),
1941+
play_request_id,
1942+
}
1943+
}
1944+
_ => {
1945+
// Could be a transient error; try the next track
1946+
PlayerEvent::EndOfTrack {
1947+
track_id: track_id.clone(),
1948+
play_request_id,
1949+
}
1950+
}
1951+
};
1952+
1953+
self.send_event(reaction_event);
1954+
1955+
self.state = PlayerState::EndOfTrack {
1956+
track_id,
1957+
play_request_id,
1958+
loaded_track,
1959+
};
1960+
1961+
return;
1962+
}
19341963
}
19351964
}
19361965

0 commit comments

Comments
 (0)