@@ -60,7 +60,6 @@ use std::ops::{Deref, DerefMut};
60
60
use std:: path:: Path ;
61
61
use std:: marker:: PhantomData ;
62
62
use std:: mem;
63
- use std:: mem:: transmute;
64
63
use std:: ptr;
65
64
66
65
use AudioSubsystem ;
@@ -209,12 +208,16 @@ pub enum AudioStatus {
209
208
impl FromPrimitive for AudioStatus {
210
209
fn from_i64 ( n : i64 ) -> Option < AudioStatus > {
211
210
use self :: AudioStatus :: * ;
212
- let n = n as u32 ;
213
211
214
- Some ( match unsafe { transmute :: < u32 , sys:: SDL_AudioStatus > ( n) } {
215
- sys:: SDL_AudioStatus :: SDL_AUDIO_STOPPED => Stopped ,
216
- sys:: SDL_AudioStatus :: SDL_AUDIO_PLAYING => Playing ,
217
- sys:: SDL_AudioStatus :: SDL_AUDIO_PAUSED => Paused ,
212
+ const STOPPED : i64 = sys:: SDL_AudioStatus :: SDL_AUDIO_STOPPED as i64 ;
213
+ const PLAYING : i64 = sys:: SDL_AudioStatus :: SDL_AUDIO_PLAYING as i64 ;
214
+ const PAUSED : i64 = sys:: SDL_AudioStatus :: SDL_AUDIO_PAUSED as i64 ;
215
+
216
+ Some ( match n {
217
+ STOPPED => Stopped ,
218
+ PLAYING => Playing ,
219
+ PAUSED => Paused ,
220
+ _ => return None ,
218
221
} )
219
222
}
220
223
@@ -373,13 +376,15 @@ extern "C" fn audio_callback_marshall<CB: AudioCallback>
373
376
use std:: slice:: from_raw_parts_mut;
374
377
use std:: mem:: size_of;
375
378
unsafe {
376
- let cb_userdata: & mut CB = & mut * ( userdata as * mut CB ) ;
379
+ let cb_userdata: & mut Option < CB > = & mut * ( userdata as * mut _ ) ;
377
380
let buf: & mut [ CB :: Channel ] = from_raw_parts_mut (
378
381
stream as * mut CB :: Channel ,
379
382
len as usize / size_of :: < CB :: Channel > ( )
380
383
) ;
381
384
382
- cb_userdata. callback ( buf) ;
385
+ if let Some ( cb) = cb_userdata {
386
+ cb. callback ( buf) ;
387
+ }
383
388
}
384
389
}
385
390
@@ -394,14 +399,13 @@ pub struct AudioSpecDesired {
394
399
}
395
400
396
401
impl AudioSpecDesired {
397
- fn convert_to_ll < CB , F , C , S > ( freq : F , channels : C , samples : S , userdata : * mut CB ) -> sys:: SDL_AudioSpec
402
+ fn convert_to_ll < CB , F , C , S > ( freq : F , channels : C , samples : S , userdata : * mut Option < CB > ) -> sys:: SDL_AudioSpec
398
403
where
399
404
CB : AudioCallback ,
400
405
F : Into < Option < i32 > > ,
401
406
C : Into < Option < u8 > > ,
402
407
S : Into < Option < u16 > > ,
403
408
{
404
- use std:: mem:: transmute;
405
409
406
410
let freq = freq. into ( ) ;
407
411
let channels = channels. into ( ) ;
@@ -413,22 +417,20 @@ impl AudioSpecDesired {
413
417
414
418
// A value of 0 means "fallback" or "default".
415
419
416
- unsafe {
417
- sys:: SDL_AudioSpec {
418
- freq : freq. unwrap_or ( 0 ) ,
419
- format : <CB :: Channel as AudioFormatNum >:: audio_format ( ) . to_ll ( ) ,
420
- channels : channels. unwrap_or ( 0 ) ,
421
- silence : 0 ,
422
- samples : samples. unwrap_or ( 0 ) ,
423
- padding : 0 ,
424
- size : 0 ,
425
- callback : Some ( audio_callback_marshall :: < CB >
426
- as extern "C" fn
427
- ( arg1 : * mut c_void ,
428
- arg2 : * mut uint8_t ,
429
- arg3 : c_int ) ) ,
430
- userdata : transmute ( userdata)
431
- }
420
+ sys:: SDL_AudioSpec {
421
+ freq : freq. unwrap_or ( 0 ) ,
422
+ format : <CB :: Channel as AudioFormatNum >:: audio_format ( ) . to_ll ( ) ,
423
+ channels : channels. unwrap_or ( 0 ) ,
424
+ silence : 0 ,
425
+ samples : samples. unwrap_or ( 0 ) ,
426
+ padding : 0 ,
427
+ size : 0 ,
428
+ callback : Some ( audio_callback_marshall :: < CB >
429
+ as extern "C" fn
430
+ ( arg1 : * mut c_void ,
431
+ arg2 : * mut uint8_t ,
432
+ arg3 : c_int ) ) ,
433
+ userdata : userdata as * mut _ ,
432
434
}
433
435
}
434
436
@@ -596,7 +598,7 @@ pub struct AudioDevice<CB: AudioCallback> {
596
598
device_id : AudioDeviceID ,
597
599
spec : AudioSpec ,
598
600
/// Store the callback to keep it alive for the entire duration of `AudioDevice`.
599
- userdata : Box < CB >
601
+ userdata : Box < Option < CB > >
600
602
}
601
603
602
604
impl < CB : AudioCallback > AudioDevice < CB > {
@@ -607,14 +609,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
607
609
D : Into < Option < & ' a str > > ,
608
610
{
609
611
610
- // SDL_OpenAudioDevice needs a userdata pointer, but we can't initialize the
611
- // callback without the obtained AudioSpec.
612
- // Create an uninitialized box that will be initialized after SDL_OpenAudioDevice.
613
- let userdata: * mut CB = unsafe {
614
- let b: Box < CB > = Box :: new ( mem:: uninitialized ( ) ) ;
615
- mem:: transmute ( b)
616
- } ;
617
- let desired = AudioSpecDesired :: convert_to_ll ( spec. freq , spec. channels , spec. samples , userdata) ;
612
+ let mut userdata: Box < Option < CB > > = Box :: new ( None ) ;
613
+ let desired = AudioSpecDesired :: convert_to_ll ( spec. freq , spec. channels , spec. samples , & mut * userdata) ;
618
614
619
615
let mut obtained = unsafe { mem:: uninitialized :: < sys:: SDL_AudioSpec > ( ) } ;
620
616
unsafe {
@@ -636,10 +632,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
636
632
id => {
637
633
let device_id = AudioDeviceID :: PlaybackDevice ( id) ;
638
634
let spec = AudioSpec :: convert_from_ll ( obtained) ;
639
- let mut userdata: Box < CB > = mem:: transmute ( userdata) ;
640
635
641
- let garbage = mem:: replace ( & mut userdata as & mut CB , get_callback ( spec) ) ;
642
- mem:: forget ( garbage) ;
636
+ * userdata = Some ( get_callback ( spec) ) ;
643
637
644
638
Ok ( AudioDevice {
645
639
subsystem : a. clone ( ) ,
@@ -713,7 +707,7 @@ impl<CB: AudioCallback> AudioDevice<CB> {
713
707
/// but the callback data will be dropped.
714
708
pub fn close_and_get_callback ( self ) -> CB {
715
709
drop ( self . device_id ) ;
716
- * self . userdata
710
+ self . userdata . expect ( "Missing callback" )
717
711
}
718
712
}
719
713
@@ -725,11 +719,11 @@ pub struct AudioDeviceLockGuard<'a, CB> where CB: AudioCallback, CB: 'a {
725
719
726
720
impl < ' a , CB : AudioCallback > Deref for AudioDeviceLockGuard < ' a , CB > {
727
721
type Target = CB ;
728
- fn deref ( & self ) -> & CB { & self . device . userdata }
722
+ fn deref ( & self ) -> & CB { ( * self . device . userdata ) . as_ref ( ) . expect ( "Missing callback" ) }
729
723
}
730
724
731
725
impl < ' a , CB : AudioCallback > DerefMut for AudioDeviceLockGuard < ' a , CB > {
732
- fn deref_mut ( & mut self ) -> & mut CB { & mut self . device . userdata }
726
+ fn deref_mut ( & mut self ) -> & mut CB { ( * self . device . userdata ) . as_mut ( ) . expect ( "Missing callback" ) }
733
727
}
734
728
735
729
impl < ' a , CB : AudioCallback > Drop for AudioDeviceLockGuard < ' a , CB > {
@@ -835,7 +829,7 @@ mod test {
835
829
assert_eq ! ( new_buffer. len( ) , new_buffer_expected. len( ) , "capacity must be exactly equal to twice the original vec size" ) ;
836
830
837
831
// // this has been commented, see https://discourse.libsdl.org/t/change-of-behavior-in-audiocvt-sdl-convertaudio-from-2-0-5-to-2-0-6/24682
838
- // // to maybe re-enable it someday
832
+ // // to maybe re-enable it someday
839
833
// assert_eq!(new_buffer, new_buffer_expected);
840
834
}
841
835
}
0 commit comments