Skip to content

Commit

Permalink
batching
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger committed Nov 30, 2024
1 parent 741b64b commit bf0aa61
Showing 1 changed file with 24 additions and 14 deletions.
38 changes: 24 additions & 14 deletions packages/desktop/src/providers/audio/audio_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
};

use anyhow::Context;
use crossbeam::channel;
use crossbeam::channel::{self, at, never};
use serde::{Deserialize, Serialize};
use tracing::{debug, info};
use windows::Win32::{
Expand Down Expand Up @@ -105,8 +105,6 @@ struct DeviceState {
pub struct AudioProvider {
common: CommonProviderState,
com_enumerator: Option<IMMDeviceEnumerator>,
last_emit: Instant,
pending_emission: bool,
default_playback_id: Option<String>,
default_recording_id: Option<String>,
device_states: HashMap<String, DeviceState>,
Expand All @@ -124,8 +122,6 @@ impl AudioProvider {
Self {
common,
com_enumerator: None,
last_emit: Instant::now(),
pending_emission: false,
default_playback_id: None,
default_recording_id: None,
device_states: HashMap::new(),
Expand Down Expand Up @@ -170,8 +166,19 @@ impl AudioProvider {
// Emit initial output.
self.emit_output();

// Audio events (especially volume changes) can be frequent, so we
// batch the emissions together.
let mut last_emit = Instant::now();
let mut pending_emission = false;
const BATCH_DELAY: Duration = Duration::from_millis(25);

// Listen to audio-related events.
loop {
let batch_timer = match pending_emission {
true => at(last_emit + BATCH_DELAY),
false => never(),
};

crossbeam::select! {
recv(self.event_rx) -> event => {
if let Ok(event) = event {
Expand All @@ -180,6 +187,14 @@ impl AudioProvider {
if let Err(err) = self.handle_event(event) {
tracing::warn!("Error handling audio event: {}", err);
}

// Check whether we should emit immediately or mark as pending.
if last_emit.elapsed() >= BATCH_DELAY {
self.emit_output();
last_emit = Instant::now();
} else {
pending_emission = true;
}
}
}
recv(self.common.input.sync_rx) -> input => {
Expand All @@ -197,11 +212,11 @@ impl AudioProvider {
_ => {}
}
}
default(Duration::from_millis(20)) => {
// Batch emissions to reduce overhead.
if self.pending_emission {
recv(batch_timer) -> _ => {
if pending_emission {
self.emit_output();
self.pending_emission = false;
last_emit = Instant::now();
pending_emission = false;
}
}
}
Expand Down Expand Up @@ -309,8 +324,6 @@ impl AudioProvider {
}

self.common.emitter.emit_output(Ok(output));
self.last_emit = Instant::now();
self.pending_emission = true;
}

/// Gets the default device ID for the given device type.
Expand Down Expand Up @@ -425,9 +438,6 @@ impl AudioProvider {
}
}

// Emit new output after handling the event.
self.emit_output();

Ok(())
}

Expand Down

0 comments on commit bf0aa61

Please sign in to comment.