@@ -18,28 +18,36 @@ const SAMPLE_BUFFER_SIZE: usize = SAMPLE_RATE * PRESENTER_AUDIO_BUF_SIZE / PRESE
1818pub struct SoundSampler {
1919 samples : Mutex < VecDeque < HeapMemU32 < { SAMPLE_BUFFER_SIZE } > > > ,
2020 cond_var : Condvar ,
21+ framelimit : bool ,
2122}
2223
2324impl SoundSampler {
24- pub fn new ( ) -> SoundSampler {
25+ pub fn new ( framelimit : bool ) -> SoundSampler {
2526 SoundSampler {
2627 samples : Mutex :: new ( VecDeque :: new ( ) ) ,
2728 cond_var : Condvar :: new ( ) ,
29+ framelimit,
2830 }
2931 }
3032
3133 fn push ( & self , samples : & [ u32 ] ) {
32- let mut queue = self . samples . lock ( ) . unwrap ( ) ;
33- if queue. len ( ) == 2 {
34- queue. swap ( 0 , 1 ) ;
35- let s = queue. back_mut ( ) . unwrap ( ) ;
36- s. copy_from_slice ( samples) ;
37- } else {
34+ {
35+ let mut queue = self . samples . lock ( ) . unwrap ( ) ;
36+ let mut queue = if queue. len ( ) == 4 {
37+ if self . framelimit {
38+ self . cond_var . wait_while ( queue, |queue| queue. len ( ) == 4 ) . unwrap ( )
39+ } else {
40+ queue. pop_front ( ) ;
41+ queue
42+ }
43+ } else {
44+ queue
45+ } ;
3846 let mut s = HeapMemU32 :: new ( ) ;
3947 s. copy_from_slice ( samples) ;
4048 queue. push_back ( s) ;
41- self . cond_var . notify_one ( ) ;
4249 }
50+ self . cond_var . notify_one ( ) ;
4351 }
4452
4553 pub fn consume ( & self , ret : & mut [ u32 ; PRESENTER_AUDIO_BUF_SIZE ] ) {
@@ -48,6 +56,7 @@ impl SoundSampler {
4856 let mut samples = self . cond_var . wait_while ( samples, |samples| samples. is_empty ( ) ) . unwrap ( ) ;
4957 samples. pop_front ( ) . unwrap ( )
5058 } ;
59+ self . cond_var . notify_one ( ) ;
5160 for i in 0 ..PRESENTER_AUDIO_BUF_SIZE {
5261 ret[ i] = samples[ i * SAMPLE_BUFFER_SIZE / PRESENTER_AUDIO_BUF_SIZE ] ;
5362 }
@@ -123,13 +132,14 @@ pub struct MainSoundCnt {
123132#[ derive( Copy , Clone , Default ) ]
124133pub struct SpuChannel {
125134 cnt : SoundCnt ,
135+ volume : u8 ,
126136 sad : u32 ,
127137 tmr : u16 ,
128138 pnt : u16 ,
129139 len : u32 ,
130140 snd_cap_cnt : u8 ,
131141 sad_current : u32 ,
132- tmr_current : u16 ,
142+ tmr_current : u32 ,
133143 adpcm_value : i32 ,
134144 adpcm_loop_value : i32 ,
135145 adpcm_index : i32 ,
@@ -161,6 +171,7 @@ pub struct Spu {
161171 pub audio_enabled : bool ,
162172 pub channels : [ SpuChannel ; CHANNEL_COUNT ] ,
163173 main_sound_cnt : MainSoundCnt ,
174+ master_volume : u8 ,
164175 sound_bias : u16 ,
165176 duty_cycles : [ i32 ; 6 ] ,
166177 noise_values : [ u16 ; 2 ] ,
@@ -174,6 +185,7 @@ impl Spu {
174185 audio_enabled : false ,
175186 channels : [ SpuChannel :: default ( ) ; CHANNEL_COUNT ] ,
176187 main_sound_cnt : MainSoundCnt :: from ( 0 ) ,
188+ master_volume : 0 ,
177189 sound_bias : 0 ,
178190 duty_cycles : [ 0 ; 6 ] ,
179191 noise_values : [ 0 ; 2 ] ,
@@ -203,6 +215,11 @@ impl Spu {
203215
204216 mask &= 0xFF7F837F ;
205217 self . channels [ channel] . cnt = ( ( u32:: from ( self . channels [ channel] . cnt ) & !mask) | ( value & mask) ) . into ( ) ;
218+ let mut volume = u8:: from ( self . channels [ channel] . cnt . volume_mul ( ) ) ;
219+ if volume == 127 {
220+ volume += 1 ;
221+ }
222+ self . channels [ channel] . volume = volume;
206223
207224 if was_disabled
208225 && bool:: from ( self . channels [ channel] . cnt . start_status ( ) )
@@ -246,6 +263,11 @@ impl Spu {
246263
247264 mask &= 0xBF7F ;
248265 self . main_sound_cnt = ( ( u16:: from ( self . main_sound_cnt ) & !mask) | ( value & mask) ) . into ( ) ;
266+ let mut volume = u8:: from ( self . main_sound_cnt . master_volume ( ) ) ;
267+ if volume == 127 {
268+ volume += 1 ;
269+ }
270+ self . master_volume = volume;
249271
250272 if was_disabled && bool:: from ( self . main_sound_cnt . master_enable ( ) ) {
251273 for i in 0 ..CHANNEL_COUNT {
@@ -280,7 +302,7 @@ impl Spu {
280302 fn start_channel ( & mut self , channel_num : usize , emu : & mut Emu ) {
281303 let channel = & mut self . channels [ channel_num] ;
282304 channel. sad_current = channel. sad ;
283- channel. tmr_current = channel. tmr ;
305+ channel. tmr_current = channel. tmr as u32 ;
284306
285307 match channel. cnt . get_format ( ) {
286308 SoundChannelFormat :: ImaAdpcm => {
@@ -381,7 +403,13 @@ impl Spu {
381403 for i in 0 ..CHANNEL_COUNT {
382404 get_channel_mut ! ( emu, i) . cnt . set_start_status ( u1:: new ( 0 ) ) ;
383405 }
384- get_cm_mut ! ( emu) . schedule ( 512 * 10 , EventType :: SpuSample ) ;
406+ let spu = get_spu_mut ! ( emu) ;
407+ spu. samples_buffer . push ( 0 ) ;
408+ if unlikely ( spu. samples_buffer . len ( ) == SAMPLE_BUFFER_SIZE ) {
409+ spu. sound_sampler . push ( spu. samples_buffer . as_slice ( ) ) ;
410+ spu. samples_buffer . clear ( ) ;
411+ }
412+ get_cm_mut ! ( emu) . schedule ( 512 * 2 , EventType :: SpuSample ) ;
385413 return ;
386414 }
387415
@@ -416,25 +444,15 @@ impl Spu {
416444 }
417445 } ;
418446
419- {
420- let channel = get_channel_mut ! ( emu, i) ;
421- channel. tmr_current = channel. tmr_current . wrapping_add ( 512 ) ;
422- }
423-
424- let mut overflow = get_channel ! ( emu, i) . tmr_current < 512 ;
425- while overflow {
426- {
427- let channel = get_channel_mut ! ( emu, i) ;
428- channel. tmr_current = channel. tmr_current . wrapping_add ( channel. tmr ) ;
429- }
430- overflow = get_channel ! ( emu, i) . tmr_current < get_channel ! ( emu, i) . tmr ;
447+ let mut tmr_current = get_channel ! ( emu, i) . tmr_current . wrapping_add ( 512 ) ;
448+ let tmr = get_channel ! ( emu, i) . tmr ;
449+ while tmr_current >> 16 != 0 {
450+ tmr_current = tmr as u32 + ( tmr_current - 0x10000 ) ;
431451
432452 match format {
433453 SoundChannelFormat :: Pcm8 | SoundChannelFormat :: Pcm16 => Self :: next_sample_pcm ( get_channel_mut ! ( emu, i) ) ,
434454 SoundChannelFormat :: ImaAdpcm => Self :: next_sample_adpcm ( get_channel_mut ! ( emu, i) , emu) ,
435- SoundChannelFormat :: PsgNoise => {
436- get_spu_mut ! ( emu) . next_sample_psg ( i) ;
437- }
455+ SoundChannelFormat :: PsgNoise => get_spu_mut ! ( emu) . next_sample_psg ( i) ,
438456 }
439457
440458 let channel = get_channel_mut ! ( emu, i) ;
@@ -454,19 +472,15 @@ impl Spu {
454472 }
455473 }
456474 }
475+ get_channel_mut ! ( emu, i) . tmr_current = tmr_current;
457476
458477 let channel = get_channel ! ( emu, i) ;
459- let mut volume_div = u8:: from ( channel. cnt . volume_div ( ) ) ;
460- if volume_div == 3 {
461- volume_div += 1 ;
462- }
463- data <<= 4 - volume_div;
478+ let volume_div = u8:: from ( channel. cnt . volume_div ( ) ) ;
479+ const VOLUME_DIVS : [ u8 ; 4 ] = [ 4 , 3 , 2 , 0 ] ;
480+ data <<= VOLUME_DIVS [ volume_div as usize ] ;
464481
465- let mut volume_mul = u8:: from ( channel. cnt . volume_mul ( ) ) as i64 ;
466- if volume_mul == 127 {
467- volume_mul += 1 ;
468- }
469- data = ( data << 7 ) * volume_mul / 128 ;
482+ let volume_mul = channel. volume as i64 ;
483+ data = ( ( data << 7 ) * volume_mul) >> 7 ;
470484
471485 let mut panning = u8:: from ( channel. cnt . panning ( ) ) as i64 ;
472486 if panning == 127 {
@@ -511,12 +525,9 @@ impl Spu {
511525 _ => unsafe { unreachable_unchecked ( ) } ,
512526 } ;
513527
514- let mut master_vol = u8:: from ( spu. main_sound_cnt . master_volume ( ) ) as i64 ;
515- if master_vol == 127 {
516- master_vol += 1 ;
517- }
518- let sample_left = ( sample_left * master_vol / 128 ) >> 8 ;
519- let sample_right = ( sample_right * master_vol / 128 ) >> 8 ;
528+ let master_volume = spu. master_volume as i64 ;
529+ let sample_left = ( ( sample_left * master_volume) >> 7 ) >> 8 ;
530+ let sample_right = ( ( sample_right * master_volume) >> 7 ) >> 8 ;
520531
521532 let sample_left = ( sample_left >> 6 ) + spu. sound_bias as i64 ;
522533 let sample_right = ( sample_right >> 6 ) + spu. sound_bias as i64 ;
0 commit comments