audio_settings.rs

  1use std::sync::atomic::{AtomicBool, Ordering};
  2
  3use gpui::App;
  4use settings::{Settings, SettingsStore};
  5
  6#[derive(Clone, Debug)]
  7pub struct AudioSettings {
  8    /// Opt into the new audio system.
  9    ///
 10    /// You need to rejoin a call for this setting to apply
 11    pub rodio_audio: bool, // default is false
 12    /// Requires 'rodio_audio: true'
 13    ///
 14    /// Automatically increase or decrease you microphone's volume. This affects how
 15    /// loud you sound to others.
 16    ///
 17    /// Recommended: off (default)
 18    /// Microphones are too quite in zed, until everyone is on experimental
 19    /// audio and has auto speaker volume on this will make you very loud
 20    /// compared to other speakers.
 21    pub auto_microphone_volume: bool,
 22    /// Requires 'rodio_audio: true'
 23    ///
 24    /// Automatically increate or decrease the volume of other call members.
 25    /// This only affects how things sound for you.
 26    pub auto_speaker_volume: bool,
 27    /// Requires 'rodio_audio: true'
 28    ///
 29    /// Remove background noises. Works great for typing, cars, dogs, AC. Does
 30    /// not work well on music.
 31    pub denoise: bool,
 32    /// Requires 'rodio_audio: true'
 33    ///
 34    /// Use audio parameters compatible with the previous versions of
 35    /// experimental audio and non-experimental audio. When this is false you
 36    /// will sound strange to anyone not on the latest experimental audio. In
 37    /// the future we will migrate by setting this to false
 38    ///
 39    /// You need to rejoin a call for this setting to apply
 40    pub legacy_audio_compatible: bool,
 41}
 42
 43/// Configuration of audio in Zed
 44impl Settings for AudioSettings {
 45    fn from_settings(content: &settings::SettingsContent) -> Self {
 46        let audio = &content.audio.as_ref().unwrap();
 47        AudioSettings {
 48            rodio_audio: audio.rodio_audio.unwrap(),
 49            auto_microphone_volume: audio.auto_microphone_volume.unwrap(),
 50            auto_speaker_volume: audio.auto_speaker_volume.unwrap(),
 51            denoise: audio.denoise.unwrap(),
 52            legacy_audio_compatible: audio.legacy_audio_compatible.unwrap(),
 53        }
 54    }
 55}
 56
 57/// See docs on [LIVE_SETTINGS]
 58pub(crate) struct LiveSettings {
 59    pub(crate) auto_microphone_volume: AtomicBool,
 60    pub(crate) auto_speaker_volume: AtomicBool,
 61    pub(crate) denoise: AtomicBool,
 62}
 63
 64impl LiveSettings {
 65    pub(crate) fn initialize(&self, cx: &mut App) {
 66        cx.observe_global::<SettingsStore>(move |cx| {
 67            LIVE_SETTINGS.auto_microphone_volume.store(
 68                AudioSettings::get_global(cx).auto_microphone_volume,
 69                Ordering::Relaxed,
 70            );
 71            LIVE_SETTINGS.auto_speaker_volume.store(
 72                AudioSettings::get_global(cx).auto_speaker_volume,
 73                Ordering::Relaxed,
 74            );
 75
 76            let denoise_enabled = AudioSettings::get_global(cx).denoise;
 77            #[cfg(debug_assertions)]
 78            {
 79                static DENOISE_WARNING_SEND: AtomicBool = AtomicBool::new(false);
 80                if denoise_enabled && !DENOISE_WARNING_SEND.load(Ordering::Relaxed) {
 81                    DENOISE_WARNING_SEND.store(true, Ordering::Relaxed);
 82                    log::warn!("Denoise does not work on debug builds, not enabling")
 83                }
 84            }
 85            #[cfg(not(debug_assertions))]
 86            LIVE_SETTINGS
 87                .denoise
 88                .store(denoise_enabled, Ordering::Relaxed);
 89        })
 90        .detach();
 91
 92        let init_settings = AudioSettings::get_global(cx);
 93        LIVE_SETTINGS
 94            .auto_microphone_volume
 95            .store(init_settings.auto_microphone_volume, Ordering::Relaxed);
 96        LIVE_SETTINGS
 97            .auto_speaker_volume
 98            .store(init_settings.auto_speaker_volume, Ordering::Relaxed);
 99        let denoise_enabled = AudioSettings::get_global(cx).denoise;
100        #[cfg(debug_assertions)]
101        if denoise_enabled {
102            log::warn!("Denoise does not work on debug builds, not enabling")
103        }
104        #[cfg(not(debug_assertions))]
105        LIVE_SETTINGS
106            .denoise
107            .store(denoise_enabled, Ordering::Relaxed);
108    }
109}
110
111/// Allows access to settings from the audio thread. Updated by
112/// observer of SettingsStore. Needed because audio playback and recording are
113/// real time and must each run in a dedicated OS thread, therefore we can not
114/// use the background executor.
115pub(crate) static LIVE_SETTINGS: LiveSettings = LiveSettings {
116    auto_microphone_volume: AtomicBool::new(true),
117    auto_speaker_volume: AtomicBool::new(true),
118    denoise: AtomicBool::new(true),
119};