init
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user