// If the audio format is not supported, returns b"fmt?" if the number of channels
// is not supported.
If the audio format is not supported, returns b"fmt?" if the number of channels
is not supported.
If the audio format is not supported returns b " fmt? " if the number of channels is not supported .
pub(crate) fn speaker(channels: u8) -> Result<AudioQueue, [u8; 4]> {
    RUN_LOOP.with(|run_loop| {
        let speaker_cx = Box::into_raw(Box::new(SpeakerContext {
            buffer: Mutex::new((Vec::new(), None)),
        }));
        let basic_desc = AudioStreamBasicDescription::new(channels.into());
        let mut audio_queue = std::mem::MaybeUninit::uninit();
        let status = unsafe {
            AudioQueueNewOutput(
                &basic_desc,
                speaker_callback,
                speaker_cx.cast(),
                *run_loop,
                std::ptr::null(),
                0,
                audio_queue.as_mut_ptr(),
            )
        };
        if status != 0 {
            return Err(status.to_ne_bytes());
        }
        let audio_queue = unsafe { audio_queue.assume_init() };
        // Create an empty buffer and enqueue the data.
        let mut audio_buffer = std::mem::MaybeUninit::uninit();
        let buf_byte_count =
            basic_desc.bytes_per_frame * crate::consts::PERIOD as u32;
        let status = unsafe {
            AudioQueueAllocateBuffer(
                audio_queue,
                buf_byte_count,
                audio_buffer.as_mut_ptr(),
            )
        };
        if status != 0 {
            panic!("Out of memory {}!", status);
        }
        let audio_buffer = unsafe { audio_buffer.assume_init() };
        // Set buffer length.
        unsafe {
            (*audio_buffer).audio_data_byte_size = buf_byte_count;
        }
        // Initialize to zero (silence).
        for i in 0..buf_byte_count {
            unsafe {
                let byte: *mut u8 = (*audio_buffer).audio_data.cast();
                *byte.offset(i as _) = 0;
            }
        }
        // Enqueue buffer to audio queue
        let status = unsafe {
            AudioQueueEnqueueBuffer(
                audio_queue,
                audio_buffer,
                0,
                std::ptr::null(),
            )
        };
        if status != 0 {
            return Err(status.to_ne_bytes());
        }
        // Now that we've created the audio queue an enqueued a buffer, we can start it.
        let status = unsafe { AudioQueueStart(audio_queue, std::ptr::null()) };
        if status != 0 {
            return Err(status.to_ne_bytes());
        }
        Ok(AudioQueue {
            audio_queue,
            speaker_cx,
        })
    })
}
pub ( crate ) fn speaker ( channels : u8 ) -> Result < AudioQueue , [ u8 ; 4 ] > { RUN_LOOP . with ( | run_loop | { let speaker_cx = Box :: into_raw ( Box :: new ( SpeakerContext { buffer : Mutex :: new ( ( Vec :: new ( ) , None ) ) , } ) ) ; let basic_desc = AudioStreamBasicDescription :: new ( channels . into ( ) ) ; let mut audio_queue = std :: mem :: MaybeUninit :: uninit ( ) ; let status = unsafe { AudioQueueNewOutput ( & basic_desc , speaker_callback , speaker_cx . cast ( ) , * run_loop , std :: ptr :: null ( ) , 0 , audio_queue . as_mut_ptr ( ) , ) } ; if status != 0 { return Err ( status . to_ne_bytes ( ) ) ; } let audio_queue = unsafe { audio_queue . assume_init ( ) } ; // Create an empty buffer and enqueue the data. let mut audio_buffer = std :: mem :: MaybeUninit :: uninit ( ) ; let buf_byte_count = basic_desc . bytes_per_frame * crate :: consts :: PERIOD as u32 ; let status = unsafe { AudioQueueAllocateBuffer ( audio_queue , buf_byte_count , audio_buffer . as_mut_ptr ( ) , ) } ; if status != 0 { panic ! ( " " status ) ; } let audio_buffer = unsafe { audio_buffer . assume_init ( ) } ; // Set buffer length. unsafe { ( * audio_buffer ) . audio_data_byte_size = buf_byte_count ; } // Initialize to zero (silence). for i in 0 .. buf_byte_count { unsafe { let byte : * mut u8 = ( * audio_buffer ) . audio_data . cast ( ) ; * byte . offset ( i as _ ) = 0 ; } } // Enqueue buffer to audio queue let status = unsafe { AudioQueueEnqueueBuffer ( audio_queue , audio_buffer , 0 , std :: ptr :: null ( ) , ) } ; if status != 0 { return Err ( status . to_ne_bytes ( ) ) ; } // Now that we've created the audio queue an enqueued a buffer, we can start it. let status = unsafe { AudioQueueStart ( audio_queue , std :: ptr :: null ( ) ) } ; if status != 0 { return Err ( status . to_ne_bytes ( ) ) ; } Ok ( AudioQueue { audio_queue , speaker_cx , } ) } ) }
If the audio format is not supported, returns b"fmt?"
If the audio format is not supported returns b " fmt? "
channels
u8