@@ -11,34 +11,38 @@ use symphonia::core::errors::Error as SymphoniaError;
1111use symphonia:: core:: formats:: FormatOptions ;
1212use symphonia:: core:: io:: MediaSourceStream ;
1313use symphonia:: core:: meta:: MetadataOptions ;
14- use symphonia:: core:: probe:: Hint ;
14+ use symphonia:: core:: probe:: { Hint , ProbeResult } ;
1515
1616use cpal:: traits:: { DeviceTrait , HostTrait , StreamTrait } ;
17- use cpal:: { Data , PlayStreamError , Sample , SampleFormat , Stream } ;
17+ use cpal:: { Sample , Stream } ;
1818use rubato:: { FftFixedIn , Resampler } ;
1919
20- pub struct Track {
21- pub samples : Arc < Vec < f32 > > ,
22- pub sample_rate : u32 ,
23- pub channel_count : usize ,
24- pub position : usize ,
20+ type Ringbuf < T > = LocalRb < T , Vec < MaybeUninit < T > > > ;
21+
22+ pub struct AudioReader {
23+ probe_result : ProbeResult ,
24+ decoder : Box < dyn symphonia :: core :: codecs :: Decoder > ,
2525 encoder : Encoder ,
26+
27+ buffer : Ringbuf < f32 > ,
28+
29+ position : usize , // we might not actually need this for anything now?
30+ finished : bool ,
31+
32+ // not read until the first packet
33+ sample_rate : Option < u32 > ,
34+ channel_count : Option < usize > ,
2635}
2736
28- impl Track {
37+ impl AudioReader {
2938 pub fn load ( path : & str ) -> Result < Self , Box < dyn Error > > {
3039 let src = std:: fs:: File :: open ( path) ?;
3140
3241 let mss = MediaSourceStream :: new ( Box :: new ( src) , Default :: default ( ) ) ;
3342
34- let mut hint = Hint :: new ( ) ;
35- //hint.with_extension("mp3");
36-
37- let mut samples_not_interleaved: Option < Vec < Vec < f32 > > > = None ;
38- let mut sample_rate: u32 = 0 ;
39- let mut channel_count: usize = 0 ;
43+ let hint = Hint :: new ( ) ;
4044
41- let mut probe_result = symphonia:: default:: get_probe ( )
45+ let probe_result = symphonia:: default:: get_probe ( )
4246 . format (
4347 & hint,
4448 mss,
@@ -50,7 +54,7 @@ impl Track {
5054 )
5155 . unwrap ( ) ;
5256
53- let mut decoder = symphonia:: default:: get_codecs ( )
57+ let decoder = symphonia:: default:: get_codecs ( )
5458 . make (
5559 & probe_result
5660 . format
@@ -61,59 +65,100 @@ impl Track {
6165 )
6266 . unwrap ( ) ;
6367
64- println ! ( "loading into memory..." ) ;
68+ let encoder =
69+ opus:: Encoder :: new ( 48000 , opus:: Channels :: Stereo , opus:: Application :: Audio ) . unwrap ( ) ;
70+ //encoder.set_bitrate(opus::Bitrate::Bits(256)).unwrap();
71+
72+ Ok ( Self {
73+ probe_result,
74+ decoder,
75+ encoder,
76+
77+ buffer : Ringbuf :: new ( 16384 ) ,
78+
79+ position : 0 ,
80+ finished : false ,
81+
82+ sample_rate : None ,
83+ channel_count : None ,
84+ } )
85+ }
86+
87+ // Ok(true) if there's more to read
88+ fn read_packets ( & mut self ) -> Result < bool , Box < dyn Error > > {
89+ println ! ( "read_packet() called" ) ;
90+
91+ let mut has_more = true ;
92+ let mut channel_samples: Vec < Vec < f32 > > = vec ! [ Vec :: new( ) ; self . channel_count. unwrap_or( 0 ) ] ;
93+ let mut sample_count = 0 ;
6594
6695 loop {
67- match probe_result. format . next_packet ( ) {
96+ match self . probe_result . format . next_packet ( ) {
6897 Ok ( packet) => {
69- let decoded = decoder. decode ( & packet) . unwrap ( ) ;
98+ let decoded = self . decoder . decode ( & packet) . unwrap ( ) ;
7099 let spec = * decoded. spec ( ) ;
71- let song_samples = match & mut samples_not_interleaved {
72- Some ( s) => Some ( s) ,
73- None => {
74- samples_not_interleaved = Some ( vec ! [ Vec :: new( ) ; spec. channels. count( ) ] ) ;
75- sample_rate = spec. rate ;
76- channel_count = spec. channels . count ( ) ;
77- samples_not_interleaved. as_mut ( )
78- }
100+
101+ if self . sample_rate == None {
102+ self . sample_rate = Some ( spec. rate ) ;
103+ }
104+ if self . channel_count == None {
105+ self . channel_count = Some ( spec. channels . count ( ) ) ;
106+
107+ // we probably also need to allocate channel_samples now since this is the 1st packet we're processing
108+ channel_samples = vec ! [ Vec :: new( ) ; spec. channels. count( ) ] ;
79109 }
80- . unwrap ( ) ;
81110
82111 if decoded. frames ( ) > 0 {
83- let mut samples : SampleBuffer < f32 > =
112+ let mut sample_buffer : SampleBuffer < f32 > =
84113 SampleBuffer :: new ( decoded. frames ( ) as u64 , spec) ;
85114
86- samples. copy_interleaved_ref ( decoded) ;
87- for frame in samples. samples ( ) . chunks ( spec. channels . count ( ) ) {
115+ sample_buffer. copy_interleaved_ref ( decoded) ;
116+
117+ let samples = sample_buffer. samples ( ) ;
118+
119+ println ! ( "packet had {:?}" , samples. len( ) ) ;
120+ sample_count += samples. len ( ) ;
121+
122+ for frame in samples. chunks ( spec. channels . count ( ) ) {
88123 for ( chan, sample) in frame. iter ( ) . enumerate ( ) {
89- song_samples [ chan] . push ( * sample)
124+ channel_samples [ chan] . push ( * sample)
90125 }
91126 }
92127 } else {
93128 eprintln ! ( "Empty packet encountered while loading song!" ) ;
94129 }
95130 }
96- Err ( SymphoniaError :: IoError ( _) ) => break ,
131+ Err ( SymphoniaError :: IoError ( _) ) => {
132+ // no more packets
133+ has_more = false ;
134+ break ;
135+ }
97136 Err ( e) => return Err ( "failed to parse track" . into ( ) ) ,
98137 }
138+
139+ // we should stop after a reasonable number of samples
140+ // (a reasonable number --> nobody knows)
141+ // we probably want more than 960 so we can resample enough at once (does that matter?)
142+ if sample_count >= 2048 {
143+ break ;
144+ }
99145 }
100146
101147 println ! ( "resampling...." ) ;
102148
103149 // resample to standard 48000 if needed
104- let samples_correct_rate = if sample_rate != 48000 {
105- let l = samples_not_interleaved . as_ref ( ) . unwrap ( ) [ 0 ] . len ( ) . clone ( ) ;
150+ let samples_correct_rate = if self . sample_rate . unwrap ( ) != 48000 {
151+ let l = channel_samples [ 0 ] . len ( ) ;
106152 let mut resampler =
107- FftFixedIn :: < f32 > :: new ( sample_rate as usize , 48000 , l, 100 , 2 ) . unwrap ( ) ;
153+ FftFixedIn :: < f32 > :: new ( self . sample_rate . unwrap ( ) as usize , 48000 , l, 100 , 2 )
154+ . unwrap ( ) ;
108155
109- resampler
110- . process ( & samples_not_interleaved. unwrap ( ) , None )
111- . unwrap ( )
156+ resampler. process ( & channel_samples, None ) . unwrap ( )
112157 } else {
113- samples_not_interleaved . unwrap ( )
158+ channel_samples
114159 } ;
115160
116- println ! ( "interlacing ...." ) ;
161+ println ! ( "interleaving ...." ) ;
117162
118163 // now we have to interleave it since we had to use the resampling thing
119164 let samples: Vec < f32 > = samples_correct_rate[ 0 ]
@@ -123,38 +168,42 @@ impl Track {
123168 . copied ( )
124169 . collect ( ) ;
125170
126- // it would be really sick to do all that at once (while reading it)
127- // but since we read like.. 2 samples at a time idk how
128- // the way it is it's just too slow for anything realistically-sized
171+ println ! (
172+ "copying {:?} samples to the buffer which has {:?} free" ,
173+ samples. len( ) ,
174+ self . buffer. free_len( )
175+ ) ;
129176
130- let mut encoder =
131- opus:: Encoder :: new ( 48000 , opus:: Channels :: Stereo , opus:: Application :: Audio ) . unwrap ( ) ;
132- //encoder.set_bitrate(opus::Bitrate::Bits(256)).unwrap();
133- Ok ( Self {
134- samples : Arc :: new ( samples) ,
135- sample_rate,
136- channel_count,
137- position : 0 ,
138- encoder,
139- } )
177+ for sample in samples. iter ( ) {
178+ self . buffer . push ( * sample) . unwrap ( ) ;
179+ }
180+
181+ Ok ( has_more)
140182 }
141183
142184 pub fn encode_frame ( & mut self ) -> Result < AudioFrame , ( ) > {
143- const pcm_length: usize = 960 ;
144-
145- if pcm_length * ( self . position + 1 ) >= self . samples . len ( ) {
146- println ! (
147- "encode_frame was about to run out of samples at pos {}" ,
148- self . position
149- ) ;
150- return Err ( ( ) ) ;
185+ const PCM_LENGTH : usize = 960 ;
186+
187+ // we don't have enough samples buffered to encode an opus frame, read more packets
188+ if self . buffer . len ( ) < PCM_LENGTH {
189+ if let Ok ( has_more) = self . read_packets ( ) {
190+ if !has_more {
191+ // no more packets, fill with 0s until we have a multiple of 960 frames
192+ while self . buffer . len ( ) % 960 != 0 {
193+ self . buffer . push ( 0.0 ) . unwrap ( ) ;
194+ }
195+
196+ self . finished = true ;
197+ }
198+ } else {
199+ // unrecoverable error?
200+ return Err ( ( ) ) ;
201+ }
151202 }
152203
153- let mut pcm = [ 0.0 ; pcm_length ] ;
204+ let mut pcm = [ 0.0 ; PCM_LENGTH ] ;
154205
155- for i in 0 ..pcm_length {
156- pcm[ i] = self . samples [ i + pcm_length * self . position ] ;
157- }
206+ self . buffer . pop_slice ( & mut pcm) ;
158207
159208 let x = self . encoder . encode_vec_float ( & pcm, 256 ) . unwrap ( ) ;
160209 self . position += 1 ;
@@ -164,20 +213,22 @@ impl Track {
164213 data : x,
165214 } )
166215 }
167- }
168216
169- type Ringbuf = LocalRb < f32 , Vec < MaybeUninit < f32 > > > ;
217+ pub fn finished ( & self ) -> bool {
218+ self . finished
219+ }
220+ }
170221
171222pub struct Player {
172223 decoder : Decoder ,
173- buffer : Arc < Mutex < Ringbuf > > ,
224+ buffer : Arc < Mutex < Ringbuf < f32 > > > ,
174225 stream : Option < Stream > ,
175226}
176227impl Player {
177228 pub fn new ( ) -> Self {
178229 Self {
179230 decoder : Decoder :: new ( 48000 , opus:: Channels :: Stereo ) . unwrap ( ) ,
180- buffer : Arc :: new ( Mutex :: new ( Ringbuf :: new ( 48000 * 10 ) ) ) , // 10s??
231+ buffer : Arc :: new ( Mutex :: new ( Ringbuf :: < f32 > :: new ( 48000 * 10 ) ) ) , // 10s??
181232 stream : None ,
182233 }
183234 }
@@ -261,11 +312,15 @@ impl Player {
261312fn write_audio < T : Sample > (
262313 out_data : & mut [ f32 ] ,
263314 _: & cpal:: OutputCallbackInfo ,
264- buffer_mutex : & Arc < Mutex < Ringbuf > > ,
315+ buffer_mutex : & Arc < Mutex < Ringbuf < f32 > > > ,
265316) {
266317 let mut buffer = buffer_mutex. lock ( ) . unwrap ( ) ;
267318 if out_data. len ( ) < buffer. len ( ) {
268319 buffer. pop_slice ( out_data) ;
320+
321+ for sample in out_data. iter_mut ( ) {
322+ * sample = * sample * 0.1 ;
323+ }
269324 } else {
270325 // uhhhh
271326 println ! ( "write_audio: buffer underrun!! (but no panic)" ) ;
0 commit comments