mirror of
https://github.com/uowuo/abaddon.git
synced 2024-11-10 06:00:10 +00:00
persist voice settings, handle volume w/ no ssrc
This commit is contained in:
parent
5e85d16cd6
commit
ea04035f0d
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user