summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2023-01-16 22:52:39 -0500
committerouwou <26526779+ouwou@users.noreply.github.com>2023-01-16 22:52:39 -0500
commitea04035f0db8fa990dd7ca8dd1a64f56bceb82e2 (patch)
tree751a4f4e2cd33c19006d92547de4fcccc2a618ee /src
parent5e85d16cd61a9f28bd046d4c7921be8f6cc2b2fc (diff)
downloadabaddon-portaudio-ea04035f0db8fa990dd7ca8dd1a64f56bceb82e2.tar.gz
abaddon-portaudio-ea04035f0db8fa990dd7ca8dd1a64f56bceb82e2.zip
persist voice settings, handle volume w/ no ssrc
Diffstat (limited to 'src')
-rw-r--r--src/abaddon.cpp5
-rw-r--r--src/audio/manager.cpp23
-rw-r--r--src/audio/manager.hpp3
-rw-r--r--src/discord/discord.cpp4
-rw-r--r--src/discord/discord.hpp2
-rw-r--r--src/discord/voiceclient.cpp25
-rw-r--r--src/discord/voiceclient.hpp4
-rw-r--r--src/windows/voicewindow.cpp21
8 files changed, 74 insertions, 13 deletions
diff --git a/src/abaddon.cpp b/src/abaddon.cpp
index 5ed17be..417d7af 100644
--- a/src/abaddon.cpp
+++ b/src/abaddon.cpp
@@ -474,9 +474,8 @@ void Abaddon::ShowVoiceWindow() {
});
wnd->signal_user_volume_changed().connect([this](Snowflake id, double volume) {
- if (const auto ssrc = m_discord.GetSSRCOfUser(id); ssrc.has_value()) {
- m_audio->SetVolumeSSRC(*ssrc, volume);
- }
+ auto &vc = m_discord.GetVoiceClient();
+ vc.SetUserVolume(id, volume);
});
wnd->set_position(Gtk::WIN_POS_CENTER);
diff --git a/src/audio/manager.cpp b/src/audio/manager.cpp
index 1a7bda5..618773d 100644
--- a/src/audio/manager.cpp
+++ b/src/audio/manager.cpp
@@ -278,13 +278,21 @@ void AudioManager::SetPlayback(bool playback) {
}
void AudioManager::SetCaptureGate(double gate) {
- m_capture_gate = gate * 0.01;
+ m_capture_gate = gate;
}
void AudioManager::SetCaptureGain(double gain) {
m_capture_gain = gain;
}
+double AudioManager::GetCaptureGate() const noexcept {
+ return m_capture_gate;
+}
+
+double AudioManager::GetCaptureGain() const noexcept {
+ return m_capture_gain;
+}
+
void AudioManager::SetMuteSSRC(uint32_t ssrc, bool mute) {
std::lock_guard<std::mutex> _(m_mutex);
if (mute) {
@@ -296,9 +304,15 @@ void AudioManager::SetMuteSSRC(uint32_t ssrc, bool mute) {
void AudioManager::SetVolumeSSRC(uint32_t ssrc, double volume) {
std::lock_guard<std::mutex> _(m_mutex);
- volume *= 0.01;
- constexpr const double E = 2.71828182845904523536;
- m_volume_ssrc[ssrc] = (std::exp(volume) - 1) / (E - 1);
+ m_volume_ssrc[ssrc] = volume;
+}
+
+double AudioManager::GetVolumeSSRC(uint32_t ssrc) const {
+ std::lock_guard<std::mutex> _(m_mutex);
+ if (const auto iter = m_volume_ssrc.find(ssrc); iter != m_volume_ssrc.end()) {
+ return iter->second;
+ }
+ return 1.0;
}
void AudioManager::SetEncodingApplication(int application) {
@@ -463,4 +477,5 @@ AudioDevices &AudioManager::GetDevices() {
AudioManager::type_signal_opus_packet AudioManager::signal_opus_packet() {
return m_signal_opus_packet;
}
+
#endif
diff --git a/src/audio/manager.hpp b/src/audio/manager.hpp
index dbb0b6e..9cd7f42 100644
--- a/src/audio/manager.hpp
+++ b/src/audio/manager.hpp
@@ -40,9 +40,12 @@ public:
void SetCaptureGate(double gate);
void SetCaptureGain(double gain);
+ [[nodiscard]] double GetCaptureGate() const noexcept;
+ [[nodiscard]] double GetCaptureGain() const noexcept;
void SetMuteSSRC(uint32_t ssrc, bool mute);
void SetVolumeSSRC(uint32_t ssrc, double volume);
+ [[nodiscard]] double GetVolumeSSRC(uint32_t ssrc) const;
void SetEncodingApplication(int application);
[[nodiscard]] int GetEncodingApplication();
diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp
index 2c7358b..45e8919 100644
--- a/src/discord/discord.cpp
+++ b/src/discord/discord.cpp
@@ -1226,6 +1226,10 @@ std::optional<Snowflake> DiscordClient::GetVoiceState(Snowflake user_id) const {
return std::nullopt;
}
+DiscordVoiceClient &DiscordClient::GetVoiceClient() {
+ return m_voice;
+}
+
void DiscordClient::SetVoiceMuted(bool is_mute) {
m_mute_requested = is_mute;
SendVoiceStateUpdate();
diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp
index fa399cc..10b1d30 100644
--- a/src/discord/discord.hpp
+++ b/src/discord/discord.hpp
@@ -191,6 +191,8 @@ public:
[[nodiscard]] std::optional<uint32_t> GetSSRCOfUser(Snowflake id) const;
[[nodiscard]] std::optional<Snowflake> GetVoiceState(Snowflake user_id) const;
+ DiscordVoiceClient &GetVoiceClient();
+
void SetVoiceMuted(bool is_mute);
void SetVoiceDeafened(bool is_deaf);
#endif
diff --git a/src/discord/voiceclient.cpp b/src/discord/voiceclient.cpp
index ed83e3c..3d246b1 100644
--- a/src/discord/voiceclient.cpp
+++ b/src/discord/voiceclient.cpp
@@ -167,6 +167,7 @@ DiscordVoiceClient::~DiscordVoiceClient() {
void DiscordVoiceClient::Start() {
SetState(State::ConnectingToWebsocket);
+ m_ssrc_map.clear();
m_heartbeat_waiter.revive();
m_keepalive_waiter.revive();
m_ws.StartConnection("wss://" + m_endpoint + "/?v=7");
@@ -188,6 +189,8 @@ void DiscordVoiceClient::Stop() {
m_keepalive_waiter.kill();
if (m_keepalive_thread.joinable()) m_keepalive_thread.join();
+ m_ssrc_map.clear();
+
m_signal_disconnected.emit();
}
@@ -211,6 +214,20 @@ void DiscordVoiceClient::SetUserID(Snowflake id) {
m_user_id = id;
}
+void DiscordVoiceClient::SetUserVolume(Snowflake id, float volume) {
+ m_user_volumes[id] = volume;
+ if (const auto ssrc = GetSSRCOfUser(id); ssrc.has_value()) {
+ Abaddon::Get().GetAudio().SetVolumeSSRC(*ssrc, volume);
+ }
+}
+
+[[nodiscard]] float DiscordVoiceClient::GetUserVolume(Snowflake id) const {
+ if (const auto it = m_user_volumes.find(id); it != m_user_volumes.end()) {
+ return it->second;
+ }
+ return 1.0f;
+}
+
std::optional<uint32_t> DiscordVoiceClient::GetSSRCOfUser(Snowflake id) const {
if (const auto it = m_ssrc_map.find(id); it != m_ssrc_map.end()) {
return it->second;
@@ -315,6 +332,14 @@ void DiscordVoiceClient::HandleGatewaySessionDescription(const VoiceGatewayMessa
void DiscordVoiceClient::HandleGatewaySpeaking(const VoiceGatewayMessage &m) {
VoiceSpeakingData d = m.Data;
+
+ // set volume if already set but ssrc just found
+ if (const auto iter = m_user_volumes.find(d.UserID); iter != m_user_volumes.end()) {
+ if (m_ssrc_map.find(d.UserID) == m_ssrc_map.end()) {
+ Abaddon::Get().GetAudio().SetVolumeSSRC(d.SSRC, iter->second);
+ }
+ }
+
m_ssrc_map[d.UserID] = d.SSRC;
m_signal_speaking.emit(d);
}
diff --git a/src/discord/voiceclient.hpp b/src/discord/voiceclient.hpp
index 916d070..7bf4295 100644
--- a/src/discord/voiceclient.hpp
+++ b/src/discord/voiceclient.hpp
@@ -195,6 +195,9 @@ public:
void SetServerID(Snowflake id);
void SetUserID(Snowflake id);
+ // todo serialize
+ void SetUserVolume(Snowflake id, float volume);
+ [[nodiscard]] float GetUserVolume(Snowflake id) const;
[[nodiscard]] std::optional<uint32_t> GetSSRCOfUser(Snowflake id) const;
// Is a websocket and udp connection fully established
@@ -241,6 +244,7 @@ private:
Snowflake m_user_id;
std::unordered_map<Snowflake, uint32_t> m_ssrc_map;
+ std::unordered_map<Snowflake, float> m_user_volumes;
std::array<uint8_t, 32> m_secret_key;
diff --git a/src/windows/voicewindow.cpp b/src/windows/voicewindow.cpp
index 7c90e96..c82a0aa 100644
--- a/src/windows/voicewindow.cpp
+++ b/src/windows/voicewindow.cpp
@@ -24,7 +24,7 @@ public:
m_volume.set_value_pos(Gtk::POS_LEFT);
m_volume.set_value(100.0);
m_volume.signal_value_changed().connect([this]() {
- m_signal_volume.emit(m_volume.get_value());
+ m_signal_volume.emit(m_volume.get_value() * 0.01);
});
m_horz.add(m_avatar);
@@ -54,6 +54,10 @@ public:
m_meter.SetVolume(frac);
}
+ void RestoreGain(double frac) {
+ m_volume.set_value(frac * 100.0);
+ }
+
private:
Gtk::Box m_main;
Gtk::Box m_horz;
@@ -92,6 +96,8 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
set_default_size(300, 300);
auto &discord = Abaddon::Get().GetDiscordClient();
+ auto &audio = Abaddon::Get().GetAudio();
+
SetUsers(discord.GetUsersInVoiceChannel(m_channel_id));
discord.signal_voice_user_disconnect().connect(sigc::mem_fun(*this, &VoiceWindow::OnUserDisconnect));
@@ -108,17 +114,16 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
m_capture_gate.set_range(0.0, 100.0);
m_capture_gate.set_value_pos(Gtk::POS_LEFT);
- m_capture_gate.set_value(0.0);
+ m_capture_gate.set_value(audio.GetCaptureGate() * 100.0);
m_capture_gate.signal_value_changed().connect([this]() {
- // todo this should probably emit 0-1 i dont think the mgr should be responsible for scaling down
- const double val = m_capture_gate.get_value();
+ const double val = m_capture_gate.get_value() * 0.01;
m_signal_gate.emit(val);
- m_capture_volume.SetTick(val / 100.0);
+ m_capture_volume.SetTick(val);
});
m_capture_gain.set_range(0.0, 200.0);
m_capture_gain.set_value_pos(Gtk::POS_LEFT);
- m_capture_gain.set_value(100.0);
+ m_capture_gain.set_value(audio.GetCaptureGain() * 100.0);
m_capture_gain.signal_value_changed().connect([this]() {
const double val = m_capture_gain.get_value();
m_signal_gain.emit(val / 100.0);
@@ -174,7 +179,9 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
}
void VoiceWindow::SetUsers(const std::unordered_set<Snowflake> &user_ids) {
+ const auto me = Abaddon::Get().GetDiscordClient().GetUserData().ID;
for (auto id : user_ids) {
+ if (id == me) continue;
m_user_list.add(*CreateRow(id));
}
}
@@ -182,6 +189,8 @@ void VoiceWindow::SetUsers(const std::unordered_set<Snowflake> &user_ids) {
Gtk::ListBoxRow *VoiceWindow::CreateRow(Snowflake id) {
auto *row = Gtk::make_managed<VoiceWindowUserListEntry>(id);
m_rows[id] = row;
+ auto &vc = Abaddon::Get().GetDiscordClient().GetVoiceClient();
+ row->RestoreGain(vc.GetUserVolume(id));
row->signal_mute_cs().connect([this, id](bool is_muted) {
m_signal_mute_user_cs.emit(id, is_muted);
});