1use lewton::inside_ogg::OggStreamReader;
2use std::{
3 io::{Read, Seek, SeekFrom},
4 vec::IntoIter,
5};
6
7use crate::SoundSource;
8
9pub struct OggDecoder<T: Seek + Read + Send + 'static> {
11 reader: Option<OggStreamReader<T>>,
12 buffer: IntoIter<i16>,
13 done: bool,
14}
15impl<T: Seek + Read + Send + 'static> OggDecoder<T> {
16 pub fn new(data: T) -> Result<Self, lewton::VorbisError> {
18 let mut reader = OggStreamReader::new(data)?;
19 let _ = reader.read_dec_packet_itl()?;
21 Ok(Self {
22 buffer: reader
23 .read_dec_packet_itl()?
24 .unwrap_or_default()
25 .into_iter(),
26 reader: Some(reader),
27 done: false,
28 })
29 }
30
31 fn reader(&self) -> &OggStreamReader<T> {
32 self.reader.as_ref().unwrap()
33 }
34
35 fn reader_mut(&mut self) -> &mut OggStreamReader<T> {
36 self.reader.as_mut().unwrap()
37 }
38}
39impl<T: Seek + Read + Send + 'static> SoundSource for OggDecoder<T> {
40 fn channels(&self) -> u16 {
41 self.reader().ident_hdr.audio_channels as u16
42 }
43
44 fn sample_rate(&self) -> u32 {
45 self.reader().ident_hdr.audio_sample_rate
46 }
47
48 fn reset(&mut self) {
49 let reader = self.reader.take();
50 let mut source = reader.unwrap().into_inner().into_inner();
51 source.seek(SeekFrom::Start(0)).unwrap();
52 let reader = OggStreamReader::new(source).unwrap();
53 self.reader = Some(reader);
54 self.done = false;
55 let _ = self.reader_mut().read_dec_packet_itl().unwrap();
57 self.buffer = self
58 .reader_mut()
59 .read_dec_packet_itl()
60 .unwrap()
61 .unwrap_or_default()
62 .into_iter();
63 }
64 fn write_samples(&mut self, buffer: &mut [i16]) -> usize {
65 let mut i = 0;
66
67 'main: while i < buffer.len() {
68 if let Some(next) = self.buffer.next() {
69 buffer[i] = next;
70 i += 1;
71 } else {
72 while let Some(pck) = self.reader_mut().read_dec_packet_itl().unwrap() {
73 if !pck.is_empty() {
74 self.buffer = pck.into_iter();
75 continue 'main;
76 }
77 }
78 return i;
79 }
80 }
81
82 buffer.len()
83 }
84}