pub fn play_file<T>(start_time: Instant, rate: f64, path: T, recv: Receiver<bool>)
where
    T: AsRef<Path>,
{
    let host = cpal::default_host();
    let event_loop = host.event_loop();
    let device = host
        .default_output_device()
        .expect("no output device available");
    let mut supported_formats_range = device
        .supported_output_formats()
        .expect("error while querying formats");
    let format = supported_formats_range
        .next()
        .expect("no supported format?!")
        .with_max_sample_rate();
    let stream_id = event_loop.build_output_stream(&device, &format).unwrap();

    let sample_rate = f64::from(format.sample_rate.0);

    let mut ext = PathBuf::new();
    ext.push(&path);
    let (stream_sample_rate, samples) = match ext.extension() {
        Some(ext) => match ext.to_str() {
            Some("ogg") => decode_ogg(path),
            Some("mp3") => decode_mp3(path),
            Some("wav") => decode_wav(path),
            _ => panic!("unrecognized file type"),
        },
        _ => panic!("no file type found"),
    };

    let mut sample_index = 0.0;

    let to_sample_number = |dur: Duration| {
        dur.as_secs() as f64 * sample_rate
            + f64::from(dur.subsec_nanos()) * (sample_rate / 1_000_000_000.0)
    };

    let sample_factor = f64::from(stream_sample_rate) / sample_rate;

    let mut next_value = |time: Instant| {
        let now = Instant::now();
        if now > time {
            sample_index = (1.0 - CORRECTION_DEGREE) * (sample_index + 1.0)
                + CORRECTION_DEGREE * to_sample_number(now.duration_since(time));
            (sample_index * sample_factor * rate) as usize * 2
        } else {
            0
        }
    };

    event_loop
        .play_stream(stream_id.clone())
        .expect("failed to play_stream");

    event_loop.run(move |_, stream_result| {
        let data = match stream_result {
            Ok(data) => data,
            Err(err) => panic!("an error occurred on stream {:?}: {}", stream_id, err),
        };

        if let cpal::StreamData::Output {
            buffer: cpal::UnknownTypeOutputBuffer::F32(mut buffer),
        } = data
        {
            for sample in buffer.chunks_mut(format.channels as usize) {
                let value = next_value(start_time);
                for (i, out) in sample.iter_mut().enumerate() {
                    *out = f32::from(*samples.get(value + i).unwrap_or(&0))
                        / f32::from(i16::max_value());
                }
            }
            if recv.try_recv().is_ok() {
                panic!("Intentional panic");
            }
        }
    });
}
//Known issue: playback only operates correctly on two channel audio
//single channel audio needs to be accounted for
Known issue: playback only operates correctly on two channel audio
single channel audio needs to be accounted for
Known issue : playback only operates correctly on two channel audio single channel audio needs to be accounted for
pub fn play_file<T>(start_time: Instant, rate: f64, path: T, recv: Receiver<bool>)
where
    T: AsRef<Path>,
{
    let host = cpal::default_host();
    let event_loop = host.event_loop();
    let device = host
        .default_output_device()
        .expect("no output device available");
    let mut supported_formats_range = device
        .supported_output_formats()
        .expect("error while querying formats");
    let format = supported_formats_range
        .next()
        .expect("no supported format?!")
        .with_max_sample_rate();
    let stream_id = event_loop.build_output_stream(&device, &format).unwrap();
    let sample_rate = f64::from(format.sample_rate.0);
    let mut ext = PathBuf::new();
    ext.push(&path);
    let (stream_sample_rate, samples) = match ext.extension() {
        Some(ext) => match ext.to_str() {
            Some("ogg") => decode_ogg(path),
            Some("mp3") => decode_mp3(path),
            Some("wav") => decode_wav(path),
            _ => panic!("unrecognized file type"),
        },
        _ => panic!("no file type found"),
    };
    let mut sample_index = 0.0;
    let to_sample_number = |dur: Duration| {
        dur.as_secs() as f64 * sample_rate
            + f64::from(dur.subsec_nanos()) * (sample_rate / 1_000_000_000.0)
    };
    let sample_factor = f64::from(stream_sample_rate) / sample_rate;
    let mut next_value = |time: Instant| {
        let now = Instant::now();
        if now > time {
            sample_index = (1.0 - CORRECTION_DEGREE) * (sample_index + 1.0)
                + CORRECTION_DEGREE * to_sample_number(now.duration_since(time));
            (sample_index * sample_factor * rate) as usize * 2
        } else {
            0
        }
    };
    event_loop
        .play_stream(stream_id.clone())
        .expect("failed to play_stream");
    event_loop.run(move |_, stream_result| {
        let data = match stream_result {
            Ok(data) => data,
            Err(err) => panic!("an error occurred on stream {:?}: {}", stream_id, err),
        };
        if let cpal::StreamData::Output {
            buffer: cpal::UnknownTypeOutputBuffer::F32(mut buffer),
        } = data
        {
            for sample in buffer.chunks_mut(format.channels as usize) {
                let value = next_value(start_time);
                for (i, out) in sample.iter_mut().enumerate() {
                    *out = f32::from(*samples.get(value + i).unwrap_or(&0))
                        / f32::from(i16::max_value());
                }
            }
            if recv.try_recv().is_ok() {
                panic!("Intentional panic");
            }
        }
    });
}
pub fn play_file < T > ( start_time : Instant , rate : f64 , path : T , recv : Receiver < bool > ) where T : AsRef < Path > , { let host = cpal :: default_host ( ) ; let event_loop = host . event_loop ( ) ; let device = host . default_output_device ( ) . expect ( " " ) ; let mut supported_formats_range = device . supported_output_formats ( ) . expect ( " " ) ; let format = supported_formats_range . next ( ) . expect ( " " ) . with_max_sample_rate ( ) ; let stream_id = event_loop . build_output_stream ( & device , & format ) . unwrap ( ) ; let sample_rate = f64 :: from ( format . sample_rate . 0 ) ; let mut ext = PathBuf :: new ( ) ; ext . push ( & path ) ; let ( stream_sample_rate , samples ) = match ext . extension ( ) { Some ( ext ) => match ext . to_str ( ) { Some ( " " ) => decode_ogg ( path ) , Some ( " " ) => decode_mp3 ( path ) , Some ( " " ) => decode_wav ( path ) , _ => panic ! ( " " ) , } , _ => panic ! ( " " ) , } ; let mut sample_index = 0.0 ; let to_sample_number = | dur : Duration | { dur . as_secs ( ) as f64 * sample_rate + f64 :: from ( dur . subsec_nanos ( ) ) * ( sample_rate / 1_000_000_000.0 ) } ; let sample_factor = f64 :: from ( stream_sample_rate ) / sample_rate ; let mut next_value = | time : Instant | { let now = Instant :: now ( ) ; if now > time { sample_index = ( 1.0 - CORRECTION_DEGREE ) * ( sample_index + 1.0 ) + CORRECTION_DEGREE * to_sample_number ( now . duration_since ( time ) ) ; ( sample_index * sample_factor * rate ) as usize * 2 } else { 0 } } ; event_loop . play_stream ( stream_id . clone ( ) ) . expect ( " " ) ; event_loop . run ( move | _ , stream_result | { let data = match stream_result { Ok ( data ) => data , Err ( err ) => panic ! ( " " stream_id err ) , } ; if let cpal :: StreamData :: Output { buffer : cpal :: UnknownTypeOutputBuffer :: F32 ( mut buffer ) , } = data { for sample in buffer . chunks_mut ( format . channels as usize ) { let value = next_value ( start_time ) ; for ( i , out ) in sample . iter_mut ( ) . enumerate ( ) { * out = f32 :: from ( * samples . get ( value + i ) . unwrap_or ( & 0 ) ) / f32 :: from ( i16 :: max_value ( ) ) ; } } if recv . try_recv ( ) . is_ok ( ) { panic ! ( " " ) ; } } } ) ; }
Known issue: playback only operates correctly on two channel audio
single channel audio needs to be accounted for
Known issue : playback only operates correctly on two channel audio single channel audio needs to be accounted for
start_time
Instant
rate
f64
path
T
recv
Receiver<bool>
start_time
Instant
rate
f64
path
T
recv
Receiver<bool>