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};