use std::fs::File; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use ringbuf::HeapRb; use rubato::{ Resampler, SincFixedIn, SincInterpolationParameters, SincInterpolationType, WindowFunction, }; use symphonia::core::{ audio::{AudioBufferRef, Signal}, codecs::{DecoderOptions, CODEC_TYPE_NULL}, formats::FormatOptions, io::MediaSourceStream, meta::MetadataOptions, probe::Hint, }; use tokio::{ sync::broadcast::{Receiver, Sender}, task, }; pub async fn play( audio_stream_sender: Sender, playing_to_base_sender: Sender, mut base_to_playing_receiver: Receiver, ) { let host = cpal::default_host(); let output_device = host.default_output_device().unwrap(); let output_device_config: cpal::StreamConfig = output_device.default_output_config().unwrap().into(); let output_device_sample_rate = output_device_config.sample_rate.0; let (mut audio_resampled_left, mut audio_resampled_right) = decode_audio(output_device_sample_rate); let total_ring_len = audio_resampled_left.len() + audio_resampled_right.len(); let (mut producer, mut receiver) = HeapRb::::new(total_ring_len).split(); for _ in 0..audio_resampled_left.clone().len() { producer .push(audio_resampled_left.pop().unwrap() as f32) .unwrap(); producer .push(audio_resampled_right.pop().unwrap() as f32) .unwrap(); } let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { for sample in data { let single = match receiver.pop() { Some(single) => { //println!("{}", single); single } None => 0.0, }; if audio_stream_sender.receiver_count() > 0 { let _ = audio_stream_sender.send(single); } *sample = single; } }; let output_stream = output_device .build_output_stream(&output_device_config, output_data_fn, err_fn, None) .unwrap(); output_stream.play().unwrap(); tokio::spawn(let_the_base_know(playing_to_base_sender.clone())); task::block_in_place(|| { let _ = base_to_playing_receiver.blocking_recv(); }); output_stream.pause().unwrap(); drop(output_stream); tokio::spawn(let_the_base_know(playing_to_base_sender)); } fn err_fn(err: cpal::StreamError) { eprintln!("Something Happened: {}", err); } async fn let_the_base_know(playing_to_base_sender: Sender) { let _ = playing_to_base_sender.send(true); } fn decode_audio(output_device_sample_rate: u32) -> (Vec, Vec) { let file = File::open("music.mp3").unwrap(); let mut audio_decoded_left = vec![]; let mut audio_decoded_right = vec![]; let media_source_stream = MediaSourceStream::new(Box::new(file), Default::default()); let hint = Hint::new(); let metadata_options = MetadataOptions::default(); let format_options = FormatOptions::default(); let probed = symphonia::default::get_probe() .format( &hint, media_source_stream, &format_options, &metadata_options, ) .unwrap(); let mut format = probed.format; let track = format .tracks() .iter() .find(|t| t.codec_params.codec != CODEC_TYPE_NULL) .unwrap(); let audio_sample_rate = track.codec_params.sample_rate.unwrap(); DecoderOptions::default(); let decoder_options = DecoderOptions::default(); let mut decoder = symphonia::default::get_codecs() .make(&track.codec_params, &decoder_options) .unwrap(); let track_id = track.id; loop { let packet = match format.next_packet() { Ok(packet) => packet, Err(_) => { break; } }; while !format.metadata().is_latest() { format.metadata().pop(); } if packet.track_id() != track_id { continue; } match decoder.decode(&packet) { Ok(decoded) => match decoded { AudioBufferRef::F32(buf) => { for (left, right) in buf.chan(0).iter().zip(buf.chan(1).iter()) { audio_decoded_left.push(*left as f64); audio_decoded_right.push(*right as f64); } } _ => {} }, Err(_) => { //eprintln!("Error: Sample Decode | {}", err_val); println!("End ?"); } } } let params = SincInterpolationParameters { sinc_len: 256, f_cutoff: 0.95, interpolation: SincInterpolationType::Linear, oversampling_factor: 256, window: WindowFunction::BlackmanHarris2, }; let mut resampler = SincFixedIn::::new( output_device_sample_rate as f64 / audio_sample_rate as f64, 2.0, params, audio_decoded_left.len(), 2, ) .unwrap(); let audio_decoded_channes_combined = vec![audio_decoded_left.clone(), audio_decoded_right.clone()]; let audio_resampled = resampler .process(&audio_decoded_channes_combined, None) .unwrap(); let mut audio_resampled_left = vec![]; let mut audio_resampled_right = vec![]; for sample in &audio_resampled[0] { audio_resampled_left.push(*sample); } for sample in &audio_resampled[1] { audio_resampled_right.push(*sample); } audio_resampled_left.reverse(); audio_resampled_right.reverse(); (audio_resampled_left, audio_resampled_right) }