call: Play a different sound when a guest joins (#38987)

Cole Miller and David Kleingeld created

Release Notes:

- collab: A distinct sound effect is now used for when a guest joins a
call.
- collab: Fixed the "joined" sound being excessively loud when joining a
call that already has many participants.

---------

Co-authored-by: David Kleingeld <davidsk@zed.dev>

Change summary

assets/sounds/guest_joined_call.wav |  0 
crates/audio/src/audio.rs           |  2 ++
crates/call/src/call_impl/room.rs   | 16 ++++++++++++++--
3 files changed, 16 insertions(+), 2 deletions(-)

Detailed changes

crates/audio/src/audio.rs 🔗

@@ -55,6 +55,7 @@ pub fn init(cx: &mut App) {
 #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
 pub enum Sound {
     Joined,
+    GuestJoined,
     Leave,
     Mute,
     Unmute,
@@ -67,6 +68,7 @@ impl Sound {
     fn file(&self) -> &'static str {
         match self {
             Self::Joined => "joined_call",
+            Self::GuestJoined => "guest_joined_call",
             Self::Leave => "leave_call",
             Self::Mute => "mute",
             Self::Unmute => "unmute",

crates/call/src/call_impl/room.rs 🔗

@@ -23,7 +23,7 @@ use livekit_client::{self as livekit, AudioStream, TrackSid};
 use postage::{sink::Sink, stream::Stream, watch};
 use project::Project;
 use settings::Settings as _;
-use std::{future::Future, mem, rc::Rc, sync::Arc, time::Duration};
+use std::{future::Future, mem, rc::Rc, sync::Arc, time::Duration, time::Instant};
 use util::{ResultExt, TryFutureExt, paths::PathStyle, post_inc};
 
 pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
@@ -86,6 +86,7 @@ pub struct Room {
     room_update_completed_rx: watch::Receiver<Option<()>>,
     pending_room_update: Option<Task<()>>,
     maintain_connection: Option<Task<Option<()>>>,
+    created: Instant,
 }
 
 impl EventEmitter<Event> for Room {}
@@ -157,6 +158,7 @@ impl Room {
             maintain_connection: Some(maintain_connection),
             room_update_completed_tx,
             room_update_completed_rx,
+            created: cx.background_executor().now(),
         }
     }
 
@@ -827,7 +829,17 @@ impl Room {
                                 },
                             );
 
-                            Audio::play_sound(Sound::Joined, cx);
+                            // When joining a room start_room_connection gets
+                            // called but we have already played the join sound.
+                            // Dont play extra sounds over that.
+                            if this.created.elapsed() > Duration::from_millis(100) {
+                                if let proto::ChannelRole::Guest = role {
+                                    Audio::play_sound(Sound::GuestJoined, cx);
+                                } else {
+                                    Audio::play_sound(Sound::Joined, cx);
+                                }
+                            }
+
                             if let Some(livekit_participants) = &livekit_participants
                                 && let Some(livekit_participant) = livekit_participants
                                     .get(&ParticipantIdentity(user.id.to_string()))