This commit is contained in:
2025-07-20 04:17:44 +02:00
parent a1f829e2e6
commit d7a7af9eb4
7 changed files with 359 additions and 211 deletions

View File

@@ -1,8 +1,10 @@
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread::JoinHandle;
use std::time::Instant;
use cpal::{default_host, BufferSize, Device, SampleRate, Stream, StreamConfig, SupportedStreamConfig};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use crate::core::mixer::AudioMixer;
use crate::domain::event::{Event, EventBus};
use crate::utils::real_time_event::RealTimeEvent;
@@ -17,7 +19,7 @@ pub struct AudioPlayback {
running: Arc<AtomicBool>,
stream: Option<Stream>,
worker: Option<JoinHandle<()>>,
next_tick: RealTimeEvent
mixer: AudioMixer
}
impl Speaker {
@@ -33,16 +35,16 @@ impl Speaker {
Speaker::new(device)
}
pub fn get_input_config(&self) -> SupportedStreamConfig {
pub fn get_output_config(&self) -> SupportedStreamConfig {
self.device.default_output_config().unwrap()
}
pub fn get_stream_config(&self) -> StreamConfig {
let config = self.get_input_config();
let config = self.get_output_config();
let mut stream_config: StreamConfig = config.into();
stream_config.channels = 2;
stream_config.sample_rate = SampleRate(48000);
stream_config.buffer_size = BufferSize::Fixed(1920);
stream_config.buffer_size = BufferSize::Fixed(960);
stream_config
}
@@ -58,40 +60,57 @@ impl Speaker {
|err| println!("Error output stream: {err}"),
None
).unwrap()
}
}
impl AudioPlayback {
pub fn new(event_bus: EventBus, speaker: Speaker) -> Self {
pub fn new(event_bus: EventBus, speaker: Speaker, mixer: AudioMixer) -> Self {
Self {
event_bus,
speaker,
running: Arc::new(AtomicBool::new(false)),
stream: None,
worker: None,
next_tick: RealTimeEvent::new(),
mixer
}
}
pub fn default(event_bus: EventBus) -> Self {
pub fn default(event_bus: EventBus, mixer: AudioMixer) -> Self {
let speaker = Speaker::default();
AudioPlayback::new(event_bus, speaker)
AudioPlayback::new(event_bus, speaker, mixer)
}
pub async fn start(&mut self) {
self.running.store(true, Ordering::SeqCst);
let stream_running = self.running.clone();
let event_bus = self.event_bus.clone();
let mixer = self.mixer.clone();
// stream cpal
println!("Setting up audio playback stream...");
let stream = self.speaker.build_stream(move |data, _| {
let last_time = Mutex::new(Instant::now());
let stream = self.speaker.build_stream(move |data, info| {
println!(
"CALLBACK : reçu {} samples, type info = {:?}",
data.len(),
info
);
let now = Instant::now();
let mut last = last_time.lock().unwrap();
let dt = now.duration_since(*last);
println!("Callback audio appelée chaque {:?} ms (≈ {:.1} Hz)", dt.as_millis(), 1000.0 / dt.as_millis().max(1) as f32);
*last = now;
if !stream_running.load(Ordering::Relaxed){
return;
}
// aller récupérer 1920 sur un buffer
// écrire le contenu dans data
println!("Audio playback stream tick");
let _ = event_bus.emit(Event::PlaybackTick);
let audio_mixer = mixer.read(data.len());
data.copy_from_slice(&audio_mixer);
// println!("data content : {:?}", data);
let _ = event_bus.emit_sync(Event::PlaybackTick(data.len()));
});
stream.play().unwrap();
self.stream = Some(stream);
@@ -99,7 +118,7 @@ impl AudioPlayback {
}
pub async fn stop(&mut self) {
self.running.store(false, std::sync::atomic::Ordering::SeqCst);
self.running.store(false, Ordering::SeqCst);
}
}