Skip to content

Commit

Permalink
remove seek support for (lewton) vorbis
Browse files Browse the repository at this point in the history
seek is broken, RustAudio/lewton#73.
We could work around it by:
 - using unsafe to create an instance of Self
 - use mem::swap to turn the &mut self into a mut self
 - take out the underlying Read+Seek
 - make a new self and seek

If this issue is fixed use the implementation in
commit: 3bafe32
  • Loading branch information
dvdsk committed Apr 4, 2024
1 parent 3bafe32 commit 26e9db7
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 34 deletions.
45 changes: 13 additions & 32 deletions src/decoder/vorbis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,39 +76,20 @@ where
None
}

/// seek is broken, https://github.com/RustAudio/lewton/issues/73.
// We could work around it by:
// - using unsafe to create an instance of Self
// - use mem::swap to turn the &mut self into a mut self
// - take out the underlying Read+Seek
// - make a new self and seek
//
// If this issue is fixed use the implementation in
// commit: 3bafe32388b4eb7a48c6701e6c65044dc8c555e6
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
// note sample rate in vorbis encoding is constant
let samples = pos.as_secs_f32() * self.sample_rate() as f32;
self.stream_reader.seek_absgp_pg(samples as u64)?;

// first few frames (packets) sometimes fail to decode, if
// that happens just retry a few times.
let mut last_err = None;
for _ in 0..10 {
// 10 seemed to work best in testing
let res = self.stream_reader.read_dec_packet_itl();
match res {
Ok(data) => {
match data {
Some(d) => self.current_data = d,
None => self.current_data = Vec::new(),
}
// make sure the next seek returns the
// sample for the correct speaker
let to_skip = self.next % self.channels() as usize;
for _ in 0..to_skip {
self.next();
}
return Ok(());
}
Err(e) => last_err = Some(e),
}
}

Err(SeekError::LewtonDecoder(
last_err.expect("is set if we get out of the for loop"),
))
fn try_seek(&mut self, _: Duration) -> Result<(), SeekError> {
Err(SeekError::NotSupported {
underlying_source: std::any::type_name::<Self>(),
})
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/seek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,15 @@ fn seek_does_not_break_channel_order() {
is_silent(&samples, source.channels(), channel0),
"channel0 should be silent,
channel0 starts at idx: {channel0}
seek offset: {offset:?}
seek: {beep_start:?} + {offset:?}
samples: {samples:?}"
);
let channel1 = (1 + channel_offset) % 2;
assert!(
!is_silent(&samples, source.channels(), channel1),
"channel1 should not be silent,
channel1; starts at idx: {channel1}
seek offset: {offset:?}
seek: {beep_start:?} + {offset:?}
samples: {samples:?}"
);
}
Expand Down

0 comments on commit 26e9db7

Please sign in to comment.