1- use std:: sync:: Arc ;
1+ use std:: mem:: MaybeUninit ;
2+ use std:: sync:: { Arc , Mutex } ;
23
34use opus:: { Decoder , Encoder } ;
45use protocol:: AudioFrame ;
5- use ringbuf:: { HeapRb , Rb } ;
6- use symphonia:: core:: audio:: { SampleBuffer } ;
7- use symphonia:: core:: codecs:: { DecoderOptions } ;
6+ use ringbuf:: { LocalRb , Rb } ;
7+ use symphonia:: core:: audio:: SampleBuffer ;
8+ use symphonia:: core:: codecs:: DecoderOptions ;
89use symphonia:: core:: errors:: Error as SymphoniaError ;
910use symphonia:: core:: formats:: FormatOptions ;
1011use symphonia:: core:: io:: MediaSourceStream ;
1112use symphonia:: core:: meta:: MetadataOptions ;
1213use symphonia:: core:: probe:: Hint ;
1314
1415use cpal:: traits:: { DeviceTrait , HostTrait , StreamTrait } ;
15- use cpal:: { Data , PlayStreamError , Sample , SampleFormat } ;
16- use rubato:: { Resampler , FftFixedIn } ;
16+ use cpal:: { Data , PlayStreamError , Sample , SampleFormat , Stream } ;
17+ use rubato:: { FftFixedIn , Resampler } ;
18+
1719pub struct Track {
1820 pub samples : Arc < Vec < f32 > > ,
1921 pub sample_rate : u32 ,
@@ -80,10 +82,10 @@ impl Track {
8082
8183 samples. copy_interleaved_ref ( decoded) ;
8284 for frame in samples. samples ( ) . chunks ( spec. channels . count ( ) ) {
83- for ( chan, sample) in frame. iter ( ) . enumerate ( ) {
84- song_samples[ chan] . push ( * sample)
85- }
86- }
85+ for ( chan, sample) in frame. iter ( ) . enumerate ( ) {
86+ song_samples[ chan] . push ( * sample)
87+ }
88+ }
8789 } else {
8890 eprintln ! ( "Empty packet encountered while loading song!" ) ;
8991 }
@@ -95,23 +97,20 @@ impl Track {
9597
9698 // resample to standard 48000 if needed
9799 let samples_correct_rate = if sample_rate != 48000 {
98-
99100 let l = samples_not_interleaved. as_ref ( ) . unwrap ( ) [ 0 ] . len ( ) . clone ( ) ;
100- let mut resampler = FftFixedIn :: < f32 > :: new (
101- sample_rate as usize ,
102- 48000 ,
103- l,
104- 100 ,
105- 2
106- ) . unwrap ( ) ;
107-
108- resampler. process ( & samples_not_interleaved. unwrap ( ) , None ) . unwrap ( )
101+ let mut resampler =
102+ FftFixedIn :: < f32 > :: new ( sample_rate as usize , 48000 , l, 100 , 2 ) . unwrap ( ) ;
103+
104+ resampler
105+ . process ( & samples_not_interleaved. unwrap ( ) , None )
106+ . unwrap ( )
109107 } else {
110108 samples_not_interleaved. unwrap ( )
111109 } ;
112110
113111 // now we have to interleave it since we had to use the resampling thing
114- let samples: Vec < f32 > = samples_correct_rate[ 0 ] . chunks ( 1 )
112+ let samples: Vec < f32 > = samples_correct_rate[ 0 ]
113+ . chunks ( 1 )
115114 . zip ( samples_correct_rate[ 1 ] . chunks ( 1 ) )
116115 . flat_map ( |( a, b) | a. into_iter ( ) . chain ( b) )
117116 . copied ( )
@@ -121,7 +120,8 @@ impl Track {
121120 // but since we read like.. 2 samples at a time idk how
122121 // the way it is it's just too slow for anything realistically-sized
123122
124- let mut encoder = opus:: Encoder :: new ( 48000 , opus:: Channels :: Stereo , opus:: Application :: Audio ) . unwrap ( ) ;
123+ let mut encoder =
124+ opus:: Encoder :: new ( 48000 , opus:: Channels :: Stereo , opus:: Application :: Audio ) . unwrap ( ) ;
125125 //encoder.set_bitrate(opus::Bitrate::Bits(256)).unwrap();
126126 Ok ( Self {
127127 samples : Arc :: new ( samples) ,
@@ -150,43 +150,32 @@ impl Track {
150150 }
151151}
152152
153+ type Ringbuf = LocalRb < f32 , Vec < MaybeUninit < f32 > > > ;
154+
153155pub struct Player {
154156 decoder : Decoder ,
155- buffer : HeapRb < Vec < u8 > > ,
157+ buffer : Arc < Mutex < Ringbuf > > ,
158+ stream : Option < Stream > ,
156159}
157160impl Player {
158161 pub fn new ( ) -> Self {
159162 Self {
160163 decoder : Decoder :: new ( 48000 , opus:: Channels :: Stereo ) . unwrap ( ) ,
161- buffer : HeapRb :: < Vec < u8 > > :: new ( 1000 ) ,
164+ buffer : Arc :: new ( Mutex :: new ( Ringbuf :: new ( 48000 * 10 ) ) ) , // 10s??
165+ stream : None ,
162166 }
163167 }
164- pub fn receive ( & mut self , data : Vec < u8 > ) {
165- self . buffer . push ( data) . unwrap ( ) ;
166- }
167- pub fn decode_frame ( & mut self ) -> [ f32 ; 960 ] {
168- let mut pcm = [ 0.0 ; 960 ] ;
169- let frame = self . buffer . pop ( ) . unwrap ( ) ;
170- let x = self . decoder . decode_float ( & frame, & mut pcm, false ) . unwrap ( ) ;
171- pcm
172- }
173168
174- pub fn debug_export ( & mut self ) {
175- let spec = hound:: WavSpec {
176- channels : 2 ,
177- sample_rate : 48000 ,
178- bits_per_sample : 32 ,
179- sample_format : hound:: SampleFormat :: Float ,
180- } ;
181- let mut writer = hound:: WavWriter :: create ( "blah.wav" , spec) . unwrap ( ) ;
182- loop {
183- let frame = self . decode_frame ( ) ;
184- for s in frame {
185- writer. write_sample ( s) . unwrap ( ) ;
186- }
187- }
169+ // decode opus data when received and buffer the samples
170+ pub fn receive ( & mut self , frame : Vec < u8 > ) {
171+ // allocate and decode into here
172+ let mut pcm = vec ! [ 0.0 ; 960 ] ;
173+ self . decoder . decode_float ( & frame, & mut pcm, false ) . unwrap ( ) ;
174+
175+ // copy to ringbuffer
176+ self . buffer . lock ( ) . unwrap ( ) . push_slice ( & pcm) ;
188177 }
189- /*
178+
190179 pub fn play ( & mut self ) {
191180 println ! ( "Initialising local audio..." ) ;
192181 let host = cpal:: default_host ( ) ;
@@ -200,25 +189,38 @@ impl Player {
200189 let supported_config = supported_configs_range
201190 . next ( )
202191 . expect ( "no supported config?!" )
203- .with_max_sample_rate();
192+ . with_sample_rate ( cpal:: SampleRate ( 48000 ) ) ;
193+ // .with_max_sample_rate(); //???
204194
205195 let err_fn = |err| eprintln ! ( "an error occurred on the output audio stream: {}" , err) ;
206196 let sample_format = supported_config. sample_format ( ) ;
197+ println ! ( "sample format is {:?}" , sample_format) ; //?? do we care about other sample formats
207198 let config = supported_config. into ( ) ;
208199
209- let stream = device.build_output_stream(
200+ let buffer_handle = self . buffer . clone ( ) ;
201+
202+ let stream = device
203+ . build_output_stream (
210204 & config,
211- move |data, info| Self:: write_audio::<f32>(data, info, &self.buffer ),
205+ move |data, info| write_audio :: < f32 > ( data, info, & buffer_handle ) ,
212206 err_fn,
213- None
214- ).unwrap();
207+ None ,
208+ )
209+ . unwrap ( ) ;
215210
216- println!("Starting audio stream");
217211 stream. play ( ) . unwrap ( ) ;
212+ println ! ( "Starting audio stream" ) ;
213+
214+ // dont let it be dropped
215+ self . stream = Some ( stream) ;
218216 }
217+ }
219218
220- fn write_audio<T: Sample>(data: &mut [f32], _: &cpal::OutputCallbackInfo, rb_audio: &HeapRb<Vec<u8>>) {
221- println!("Len {}", data.len());
222- // here you'd basically just
223- } */
219+ // callback when the audio output needs more data
220+ fn write_audio < T : Sample > (
221+ out_data : & mut [ f32 ] ,
222+ _: & cpal:: OutputCallbackInfo ,
223+ buffer : & Arc < Mutex < Ringbuf > > ,
224+ ) {
225+ buffer. lock ( ) . unwrap ( ) . pop_slice ( out_data) ;
224226}
0 commit comments