pub fn start_audio_thread(mut audio_buffer_size: cpal::BufferSize) -> Result<Audio, AudioThreadError> {
    let device = cpal::default_output_device().ok_or(AudioThreadError::NoOutputDevice)?;

    println!("Using device {}", device.name());

    let format = device.default_output_format()?;

    let event_loop = cpal::EventLoop::new();
    let stream_id = event_loop.build_output_stream(&device, &format, &mut audio_buffer_size)?;
    println!("Using audio buffer size {:?}", audio_buffer_size);
    event_loop.play_stream(stream_id.clone());

    let (request_playhead_tx, request_playhead_rx) = mpsc::sync_channel(1);
    let (request_status_tx, request_status_rx) = mpsc::sync_channel(1);
    let (send_playhead_tx, send_playhead_rx) = mpsc::sync_channel(4);
    let (send_status_tx, send_status_rx) = mpsc::sync_channel(4);
    let (music_tx, music_rx) = mpsc::sync_channel(2);
    let (effect_tx, effect_rx) = mpsc::sync_channel::<(f32, ArcIter<f32>)>(128);

    let channel_count = format.channels as usize;
    let sample_rate = format.sample_rate.0;

    // Spawn the audio thread
    thread::spawn(move || {
        // (f64, ArcIter<f32>) = (volume, effect_stream_samples_iterator)
        let mut effects: VecDeque<(f32, Peekable<ArcIter<f32>>)> = VecDeque::with_capacity(128);
        let mut music: Option<MusicStream> = None;

        // hopefully u64 is big enough and no one tries to play a 3 million year 192kHz audio file
        let mut current_music_frame_index: u64 = 0;

        // Audio loop
        event_loop.run(move |_, data| {
            while let Ok((volume, effect)) = effect_rx.try_recv() {
                effects.push_back((volume, effect.peekable()));
                // TODO do things (i forgot what this was supposed to do maybe I already did them?)
            }
            while let Ok(m) = music_rx.try_recv() {
                music = Some(m);
                current_music_frame_index = 0;
            }
            // If a playhead request was sent, send the playhead
            if request_playhead_rx.try_recv().is_ok() {
                if send_playhead_tx
                    .try_send((time::Instant::now(), current_music_frame_index as f64 / sample_rate as f64))
                    .is_err()
                {
                    remani_warn!("Failed to send audio playhead"); // this isn't supposed to happen, but just in case?
                }

            }
            // If a status request was sent, send the status
            if request_status_rx.try_recv().is_ok() {
                if send_status_tx
                    .try_send(AudioStatus { is_playing_music: music.is_some() })
                    .is_err()
                {
                    remani_warn!("Failed to send audio status"); // this isn't supposed to happen, but just in case?
                }
            }

            // Get samples and mix them
            // TODO use SIMD
            let mut s = |effects: &mut VecDeque<(f32, Peekable<ArcIter<f32>>)>| {
                let mut s = match music {
                    Some(ref mut m) => match m.next() {
                        Some(n) => n,
                        None => {
                            music = None;
                            0.0
                        }
                    }
                    None => 0.0
                };
                for (volume, effect) in effects.iter_mut() {
                    if let Some(sample) = effect.next() {
                        s += sample.to_f32() * *volume;
                    }
                }
                s / 2.0 // TODO don't do this and maybe have a volume setting control this? ¯\_(ツ)_/¯
            };

            match data { // TODO vectorize?
                cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::U16(mut buffer) } => {
                    for frame in buffer.chunks_mut(channel_count) {
                        for sample in frame.iter_mut() {
                            *sample = s(&mut effects).to_u16();
                        }
                        current_music_frame_index += 1;
                    }
                },

                cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::I16(mut buffer) } => {
                    for frame in buffer.chunks_mut(channel_count) {
                        for sample in frame.iter_mut() {
                            *sample = s(&mut effects).to_i16();
                        }
                        current_music_frame_index += 1;
                    }
                },

                cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::F32(mut buffer) } => {
                    for frame in buffer.chunks_mut(channel_count) {
                        for sample in frame.iter_mut() {
                            *sample = s(&mut effects);
                        }
                        current_music_frame_index += 1;
                    }
                },
                _ => (),
            }

            // Remove any effects that are finished playing
            let mut i = 0;
            while i < effects.len() {

                // Check if there are any samples left in the effect
                if effects[i].1.peek().is_none() {
                    effects.swap_remove_back(i);
                } else {
                    i += 1;
                }
            }
        });
    });

    Ok(Audio {
        effect_sender: effect_tx,
        music_sender: music_tx,

        request_playhead_sender: request_playhead_tx,
        playhead_rcv: send_playhead_rx,
        request_status_sender: request_status_tx,
        status_rcv: send_status_rx,

        format,
    })
}
/// Starts the audio thread and returns an object that can be used to communicate with the audio
/// thread.
Starts the audio thread and returns an object that can be used to communicate with the audio
thread.
Starts the audio thread and returns an object that can be used to communicate with the audio thread .
pub fn start_audio_thread(mut audio_buffer_size: cpal::BufferSize) -> Result<Audio, AudioThreadError> {
    let device = cpal::default_output_device().ok_or(AudioThreadError::NoOutputDevice)?;
    println!("Using device {}", device.name());
    let format = device.default_output_format()?;
    let event_loop = cpal::EventLoop::new();
    let stream_id = event_loop.build_output_stream(&device, &format, &mut audio_buffer_size)?;
    println!("Using audio buffer size {:?}", audio_buffer_size);
    event_loop.play_stream(stream_id.clone());
    let (request_playhead_tx, request_playhead_rx) = mpsc::sync_channel(1);
    let (request_status_tx, request_status_rx) = mpsc::sync_channel(1);
    let (send_playhead_tx, send_playhead_rx) = mpsc::sync_channel(4);
    let (send_status_tx, send_status_rx) = mpsc::sync_channel(4);
    let (music_tx, music_rx) = mpsc::sync_channel(2);
    let (effect_tx, effect_rx) = mpsc::sync_channel::<(f32, ArcIter<f32>)>(128);
    let channel_count = format.channels as usize;
    let sample_rate = format.sample_rate.0;
    // Spawn the audio thread
    thread::spawn(move || {
        // (f64, ArcIter<f32>) = (volume, effect_stream_samples_iterator)
        let mut effects: VecDeque<(f32, Peekable<ArcIter<f32>>)> = VecDeque::with_capacity(128);
        let mut music: Option<MusicStream> = None;
        // hopefully u64 is big enough and no one tries to play a 3 million year 192kHz audio file
        let mut current_music_frame_index: u64 = 0;
        // Audio loop
        event_loop.run(move |_, data| {
            while let Ok((volume, effect)) = effect_rx.try_recv() {
                effects.push_back((volume, effect.peekable()));
                // TODO do things (i forgot what this was supposed to do maybe I already did them?)
            }
            while let Ok(m) = music_rx.try_recv() {
                music = Some(m);
                current_music_frame_index = 0;
            }
            // If a playhead request was sent, send the playhead
            if request_playhead_rx.try_recv().is_ok() {
                if send_playhead_tx
                    .try_send((time::Instant::now(), current_music_frame_index as f64 / sample_rate as f64))
                    .is_err()
                {
                    remani_warn!("Failed to send audio playhead"); // this isn't supposed to happen, but just in case?
                }
            }
            // If a status request was sent, send the status
            if request_status_rx.try_recv().is_ok() {
                if send_status_tx
                    .try_send(AudioStatus { is_playing_music: music.is_some() })
                    .is_err()
                {
                    remani_warn!("Failed to send audio status"); // this isn't supposed to happen, but just in case?
                }
            }
            // Get samples and mix them
            // TODO use SIMD
            let mut s = |effects: &mut VecDeque<(f32, Peekable<ArcIter<f32>>)>| {
                let mut s = match music {
                    Some(ref mut m) => match m.next() {
                        Some(n) => n,
                        None => {
                            music = None;
                            0.0
                        }
                    }
                    None => 0.0
                };
                for (volume, effect) in effects.iter_mut() {
                    if let Some(sample) = effect.next() {
                        s += sample.to_f32() * *volume;
                    }
                }
                s / 2.0 // TODO don't do this and maybe have a volume setting control this? ¯\_(ツ)_/¯
            };
            match data { // TODO vectorize?
                cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::U16(mut buffer) } => {
                    for frame in buffer.chunks_mut(channel_count) {
                        for sample in frame.iter_mut() {
                            *sample = s(&mut effects).to_u16();
                        }
                        current_music_frame_index += 1;
                    }
                },
                cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::I16(mut buffer) } => {
                    for frame in buffer.chunks_mut(channel_count) {
                        for sample in frame.iter_mut() {
                            *sample = s(&mut effects).to_i16();
                        }
                        current_music_frame_index += 1;
                    }
                },
                cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::F32(mut buffer) } => {
                    for frame in buffer.chunks_mut(channel_count) {
                        for sample in frame.iter_mut() {
                            *sample = s(&mut effects);
                        }
                        current_music_frame_index += 1;
                    }
                },
                _ => (),
            }
            // Remove any effects that are finished playing
            let mut i = 0;
            while i < effects.len() {
                // Check if there are any samples left in the effect
                if effects[i].1.peek().is_none() {
                    effects.swap_remove_back(i);
                } else {
                    i += 1;
                }
            }
        });
    });
    Ok(Audio {
        effect_sender: effect_tx,
        music_sender: music_tx,
        request_playhead_sender: request_playhead_tx,
        playhead_rcv: send_playhead_rx,
        request_status_sender: request_status_tx,
        status_rcv: send_status_rx,
        format,
    })
}
pub fn start_audio_thread ( mut audio_buffer_size : cpal :: BufferSize ) -> Result < Audio , AudioThreadError > { let device = cpal :: default_output_device ( ) . ok_or ( AudioThreadError :: NoOutputDevice ) ? ; println ! ( " " device name ( ) ) ; let format = device . default_output_format ( ) ? ; let event_loop = cpal :: EventLoop :: new ( ) ; let stream_id = event_loop . build_output_stream ( & device , & format , & mut audio_buffer_size ) ? ; println ! ( " " audio_buffer_size ) ; event_loop . play_stream ( stream_id . clone ( ) ) ; let ( request_playhead_tx , request_playhead_rx ) = mpsc :: sync_channel ( 1 ) ; let ( request_status_tx , request_status_rx ) = mpsc :: sync_channel ( 1 ) ; let ( send_playhead_tx , send_playhead_rx ) = mpsc :: sync_channel ( 4 ) ; let ( send_status_tx , send_status_rx ) = mpsc :: sync_channel ( 4 ) ; let ( music_tx , music_rx ) = mpsc :: sync_channel ( 2 ) ; let ( effect_tx , effect_rx ) = mpsc :: sync_channel :: < ( f32 , ArcIter < f32 > ) > ( 128 ) ; let channel_count = format . channels as usize ; let sample_rate = format . sample_rate . 0 ; // Spawn the audio thread thread :: spawn ( move | | { // (f64, ArcIter<f32>) = (volume, effect_stream_samples_iterator) let mut effects : VecDeque < ( f32 , Peekable < ArcIter < f32 > > ) > = VecDeque :: with_capacity ( 128 ) ; let mut music : Option < MusicStream > = None ; // hopefully u64 is big enough and no one tries to play a 3 million year 192kHz audio file let mut current_music_frame_index : u64 = 0 ; // Audio loop event_loop . run ( move | _ , data | { while let Ok ( ( volume , effect ) ) = effect_rx . try_recv ( ) { effects . push_back ( ( volume , effect . peekable ( ) ) ) ; // TODO do things (i forgot what this was supposed to do maybe I already did them?) } while let Ok ( m ) = music_rx . try_recv ( ) { music = Some ( m ) ; current_music_frame_index = 0 ; } // If a playhead request was sent, send the playhead if request_playhead_rx . try_recv ( ) . is_ok ( ) { if send_playhead_tx . try_send ( ( time :: Instant :: now ( ) , current_music_frame_index as f64 / sample_rate as f64 ) ) . is_err ( ) { remani_warn ! ( " " ) ; // this isn't supposed to happen, but just in case? } } // If a status request was sent, send the status if request_status_rx . try_recv ( ) . is_ok ( ) { if send_status_tx . try_send ( AudioStatus { is_playing_music : music . is_some ( ) } ) . is_err ( ) { remani_warn ! ( " " ) ; // this isn't supposed to happen, but just in case? } } // Get samples and mix them // TODO use SIMD let mut s = | effects : & mut VecDeque < ( f32 , Peekable < ArcIter < f32 > > ) > | { let mut s = match music { Some ( ref mut m ) => match m . next ( ) { Some ( n ) => n , None => { music = None ; 0.0 } } None => 0.0 } ; for ( volume , effect ) in effects . iter_mut ( ) { if let Some ( sample ) = effect . next ( ) { s += sample . to_f32 ( ) * * volume ; } } s / 2.0 // TODO don't do this and maybe have a volume setting control this? ¯\_(ツ)_/¯ } ; match data { // TODO vectorize? cpal :: StreamData :: Output { buffer : cpal :: UnknownTypeOutputBuffer :: U16 ( mut buffer ) } => { for frame in buffer . chunks_mut ( channel_count ) { for sample in frame . iter_mut ( ) { * sample = s ( & mut effects ) . to_u16 ( ) ; } current_music_frame_index += 1 ; } } , cpal :: StreamData :: Output { buffer : cpal :: UnknownTypeOutputBuffer :: I16 ( mut buffer ) } => { for frame in buffer . chunks_mut ( channel_count ) { for sample in frame . iter_mut ( ) { * sample = s ( & mut effects ) . to_i16 ( ) ; } current_music_frame_index += 1 ; } } , cpal :: StreamData :: Output { buffer : cpal :: UnknownTypeOutputBuffer :: F32 ( mut buffer ) } => { for frame in buffer . chunks_mut ( channel_count ) { for sample in frame . iter_mut ( ) { * sample = s ( & mut effects ) ; } current_music_frame_index += 1 ; } } , _ => ( ) , } // Remove any effects that are finished playing let mut i = 0 ; while i < effects . len ( ) { // Check if there are any samples left in the effect if effects [ i ] . 1 . peek ( ) . is_none ( ) { effects . swap_remove_back ( i ) ; } else { i += 1 ; } } } ) ; } ) ; Ok ( Audio { effect_sender : effect_tx , music_sender : music_tx , request_playhead_sender : request_playhead_tx , playhead_rcv : send_playhead_rx , request_status_sender : request_status_tx , status_rcv : send_status_rx , format , } ) }
Starts the audio thread and returns an object that can be used to communicate with the audio
thread.
Starts the audio thread and returns an object that can be used to communicate with the audio thread .
audio_buffer_size
cpal::BufferSize
audio_buffer_size
cpal::BufferSize