@@ -373,13 +373,15 @@ extern "C" fn audio_callback_marshall<CB: AudioCallback>
373
373
use std:: slice:: from_raw_parts_mut;
374
374
use std:: mem:: size_of;
375
375
unsafe {
376
- let cb_userdata: & mut CB = & mut * ( userdata as * mut CB ) ;
376
+ let cb_userdata: & mut Option < CB > = & mut * ( userdata as * mut _ ) ;
377
377
let buf: & mut [ CB :: Channel ] = from_raw_parts_mut (
378
378
stream as * mut CB :: Channel ,
379
379
len as usize / size_of :: < CB :: Channel > ( )
380
380
) ;
381
381
382
- cb_userdata. callback ( buf) ;
382
+ if let Some ( cb) = cb_userdata {
383
+ cb. callback ( buf) ;
384
+ }
383
385
}
384
386
}
385
387
@@ -394,14 +396,13 @@ pub struct AudioSpecDesired {
394
396
}
395
397
396
398
impl AudioSpecDesired {
397
- fn convert_to_ll < CB , F , C , S > ( freq : F , channels : C , samples : S , userdata : * mut CB ) -> sys:: SDL_AudioSpec
399
+ fn convert_to_ll < CB , F , C , S > ( freq : F , channels : C , samples : S , userdata : * mut Option < CB > ) -> sys:: SDL_AudioSpec
398
400
where
399
401
CB : AudioCallback ,
400
402
F : Into < Option < i32 > > ,
401
403
C : Into < Option < u8 > > ,
402
404
S : Into < Option < u16 > > ,
403
405
{
404
- use std:: mem:: transmute;
405
406
406
407
let freq = freq. into ( ) ;
407
408
let channels = channels. into ( ) ;
@@ -413,22 +414,20 @@ impl AudioSpecDesired {
413
414
414
415
// A value of 0 means "fallback" or "default".
415
416
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
- }
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 : userdata as * mut _ ,
432
431
}
433
432
}
434
433
@@ -596,7 +595,7 @@ pub struct AudioDevice<CB: AudioCallback> {
596
595
device_id : AudioDeviceID ,
597
596
spec : AudioSpec ,
598
597
/// Store the callback to keep it alive for the entire duration of `AudioDevice`.
599
- userdata : Box < CB >
598
+ userdata : Box < Option < CB > >
600
599
}
601
600
602
601
impl < CB : AudioCallback > AudioDevice < CB > {
@@ -607,14 +606,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
607
606
D : Into < Option < & ' a str > > ,
608
607
{
609
608
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) ;
609
+ let mut userdata: Box < Option < CB > > = Box :: new ( None ) ;
610
+ let desired = AudioSpecDesired :: convert_to_ll ( spec. freq , spec. channels , spec. samples , & mut * userdata) ;
618
611
619
612
let mut obtained = unsafe { mem:: uninitialized :: < sys:: SDL_AudioSpec > ( ) } ;
620
613
unsafe {
@@ -636,10 +629,8 @@ impl<CB: AudioCallback> AudioDevice<CB> {
636
629
id => {
637
630
let device_id = AudioDeviceID :: PlaybackDevice ( id) ;
638
631
let spec = AudioSpec :: convert_from_ll ( obtained) ;
639
- let mut userdata: Box < CB > = mem:: transmute ( userdata) ;
640
632
641
- let garbage = mem:: replace ( & mut userdata as & mut CB , get_callback ( spec) ) ;
642
- mem:: forget ( garbage) ;
633
+ * userdata = Some ( get_callback ( spec) ) ;
643
634
644
635
Ok ( AudioDevice {
645
636
subsystem : a. clone ( ) ,
@@ -713,7 +704,7 @@ impl<CB: AudioCallback> AudioDevice<CB> {
713
704
/// but the callback data will be dropped.
714
705
pub fn close_and_get_callback ( self ) -> CB {
715
706
drop ( self . device_id ) ;
716
- * self . userdata
707
+ self . userdata . expect ( "Missing callback" )
717
708
}
718
709
}
719
710
@@ -725,11 +716,11 @@ pub struct AudioDeviceLockGuard<'a, CB> where CB: AudioCallback, CB: 'a {
725
716
726
717
impl < ' a , CB : AudioCallback > Deref for AudioDeviceLockGuard < ' a , CB > {
727
718
type Target = CB ;
728
- fn deref ( & self ) -> & CB { & self . device . userdata }
719
+ fn deref ( & self ) -> & CB { ( * self . device . userdata ) . as_ref ( ) . expect ( "Missing callback" ) }
729
720
}
730
721
731
722
impl < ' a , CB : AudioCallback > DerefMut for AudioDeviceLockGuard < ' a , CB > {
732
- fn deref_mut ( & mut self ) -> & mut CB { & mut self . device . userdata }
723
+ fn deref_mut ( & mut self ) -> & mut CB { ( * self . device . userdata ) . as_mut ( ) . expect ( "Missing callback" ) }
733
724
}
734
725
735
726
impl < ' a , CB : AudioCallback > Drop for AudioDeviceLockGuard < ' a , CB > {
@@ -835,7 +826,7 @@ mod test {
835
826
assert_eq ! ( new_buffer. len( ) , new_buffer_expected. len( ) , "capacity must be exactly equal to twice the original vec size" ) ;
836
827
837
828
// // 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
829
+ // // to maybe re-enable it someday
839
830
// assert_eq!(new_buffer, new_buffer_expected);
840
831
}
841
832
}
0 commit comments