feat(client_core): 🐛 Retry game audio thread in case of error

This commit is contained in:
Riccardo Zaglia 2023-10-16 18:46:43 +08:00
parent e04ff1aef3
commit 85990bee0d
4 changed files with 23 additions and 17 deletions

View File

@ -350,7 +350,7 @@ pub fn get_next_frame_batch(
// continuity will not be affected.
pub fn receive_samples_loop(
running: Arc<RelaxedAtomic>,
mut receiver: StreamReceiver<()>,
receiver: &mut StreamReceiver<()>,
sample_buffer: Arc<Mutex<VecDeque<f32>>>,
channels_count: usize,
batch_frames_count: usize,
@ -500,11 +500,11 @@ impl Iterator for StreamingSource {
pub fn play_audio_loop(
running: Arc<RelaxedAtomic>,
device: AudioDevice,
device: &AudioDevice,
channels_count: u16,
sample_rate: u32,
config: AudioBufferingConfig,
receiver: StreamReceiver<()>,
receiver: &mut StreamReceiver<()>,
) -> Result<()> {
// Size of a chunk of frames. It corresponds to the duration if a fade-in/out in frames.
let batch_frames_count = sample_rate as usize * config.batch_ms as usize / 1000;

View File

@ -51,6 +51,10 @@ impl AudioInputCallback for RecorderCallback {
fn on_error_before_close(&mut self, _: &mut dyn AudioInputStreamSafe, error: oboe::Error) {
*self.state.lock() = AudioRecordState::Err(Some(error.into()));
}
fn on_error_after_close(&mut self, _: &mut dyn AudioInputStreamSafe, error: oboe::Error) {
*self.state.lock() = AudioRecordState::Err(Some(error.into()));
}
}
#[allow(unused_variables)]
@ -131,11 +135,11 @@ impl AudioOutputCallback for PlayerCallback {
#[allow(unused_variables)]
pub fn play_audio_loop(
running: Arc<RelaxedAtomic>,
device: AudioDevice,
device: &AudioDevice,
channels_count: u16,
sample_rate: u32,
config: AudioBufferingConfig,
receiver: StreamReceiver<()>,
receiver: &mut StreamReceiver<()>,
) -> Result<()> {
// the client sends invalid sample rates sometimes, and we crash if we try and use one
// (batch_frames_count ends up zero and the audio callback gets confused)

View File

@ -273,7 +273,7 @@ fn connection_pipeline(
let mut video_receiver =
stream_socket.subscribe_to_stream::<VideoPacketHeader>(VIDEO, MAX_UNREAD_PACKETS);
let game_audio_receiver = stream_socket.subscribe_to_stream(AUDIO, MAX_UNREAD_PACKETS);
let mut game_audio_receiver = stream_socket.subscribe_to_stream(AUDIO, MAX_UNREAD_PACKETS);
let tracking_sender = stream_socket.request_stream(TRACKING);
let mut haptics_receiver =
stream_socket.subscribe_to_stream::<Haptics>(HAPTICS, MAX_UNREAD_PACKETS);
@ -343,14 +343,16 @@ fn connection_pipeline(
let device = AudioDevice::new_output(None, None).to_con()?;
thread::spawn(move || {
alvr_common::show_err(audio::play_audio_loop(
Arc::clone(&IS_STREAMING),
device,
2,
game_audio_sample_rate,
config.buffering,
game_audio_receiver,
));
while IS_STREAMING.value() {
alvr_common::show_err(audio::play_audio_loop(
Arc::clone(&IS_STREAMING),
&device,
2,
game_audio_sample_rate,
config.buffering.clone(),
&mut game_audio_receiver,
));
}
})
} else {
thread::spawn(|| ())

View File

@ -524,7 +524,7 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
let mut video_sender = stream_socket.request_stream(VIDEO);
let game_audio_sender = stream_socket.request_stream(AUDIO);
let microphone_receiver = stream_socket.subscribe_to_stream(AUDIO, MAX_UNREAD_PACKETS);
let mut microphone_receiver = stream_socket.subscribe_to_stream(AUDIO, MAX_UNREAD_PACKETS);
let mut tracking_receiver =
stream_socket.subscribe_to_stream::<Tracking>(TRACKING, MAX_UNREAD_PACKETS);
let haptics_sender = stream_socket.request_stream(HAPTICS);
@ -639,11 +639,11 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
thread::spawn(move || {
alvr_common::show_err(alvr_audio::play_audio_loop(
Arc::clone(&IS_STREAMING),
sink,
&sink,
1,
streaming_caps.microphone_sample_rate,
config.buffering,
microphone_receiver,
&mut microphone_receiver,
));
})
} else {