summaryrefslogtreecommitdiff
path: root/src/discord
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2022-09-05 02:21:37 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2022-09-05 02:21:37 -0400
commite93b8715f9e42d25c0930becc22561f23a25a709 (patch)
treeb1371f3006f11a073de050d60a540e713389252a /src/discord
parentb7fffb8691c6010864d88b273f346419eb5a5d2b (diff)
downloadabaddon-portaudio-e93b8715f9e42d25c0930becc22561f23a25a709.tar.gz
abaddon-portaudio-e93b8715f9e42d25c0930becc22561f23a25a709.zip
basic voice capture + transmission
Diffstat (limited to 'src/discord')
-rw-r--r--src/discord/voiceclient.cpp38
-rw-r--r--src/discord/voiceclient.hpp19
2 files changed, 50 insertions, 7 deletions
diff --git a/src/discord/voiceclient.cpp b/src/discord/voiceclient.cpp
index d8855fd..3f38eea 100644
--- a/src/discord/voiceclient.cpp
+++ b/src/discord/voiceclient.cpp
@@ -43,11 +43,11 @@ void UDPSocket::SetSSRC(uint32_t ssrc) {
m_ssrc = ssrc;
}
-void UDPSocket::SendEncrypted(const std::vector<uint8_t> &data) {
+void UDPSocket::SendEncrypted(const uint8_t *data, size_t len) {
m_sequence++;
- m_timestamp += (48000 / 100) * 2;
+ m_timestamp += 480; // this is important
- std::vector<uint8_t> rtp(12, 0);
+ std::vector<uint8_t> rtp(12 + len + crypto_secretbox_MACBYTES, 0);
rtp[0] = 0x80; // ver 2
rtp[1] = 0x78; // payload type 0x78
rtp[2] = (m_sequence >> 8) & 0xFF;
@@ -63,14 +63,15 @@ void UDPSocket::SendEncrypted(const std::vector<uint8_t> &data) {
static std::array<uint8_t, 24> nonce = {};
std::memcpy(nonce.data(), rtp.data(), 12);
-
- std::vector<uint8_t> ciphertext(crypto_secretbox_MACBYTES + rtp.size(), 0);
- crypto_secretbox_easy(ciphertext.data(), rtp.data(), rtp.size(), nonce.data(), m_secret_key.data());
- rtp.insert(rtp.end(), ciphertext.begin(), ciphertext.end());
+ crypto_secretbox_easy(rtp.data() + 12, data, len, nonce.data(), m_secret_key.data());
Send(rtp.data(), rtp.size());
}
+void UDPSocket::SendEncrypted(const std::vector<uint8_t> &data) {
+ SendEncrypted(data.data(), data.size());
+}
+
void UDPSocket::Send(const uint8_t *data, size_t len) {
sendto(m_socket, reinterpret_cast<const char *>(data), static_cast<int>(len), 0, reinterpret_cast<sockaddr *>(&m_server), sizeof(m_server));
}
@@ -172,6 +173,14 @@ DiscordVoiceClient::~DiscordVoiceClient() {
void DiscordVoiceClient::Start() {
m_ws.StartConnection("wss://" + m_endpoint + "/?v=7");
+
+ // cant put in ctor or deadlock in singleton initialization
+ auto &aud = Abaddon::Get().GetAudio();
+ aud.SetOpusBuffer(m_opus_buffer.data());
+ aud.signal_opus_packet().connect([this](int payload_size) {
+ if (m_connected)
+ m_udp.SendEncrypted(m_opus_buffer.data(), payload_size);
+ });
}
void DiscordVoiceClient::SetSessionID(std::string_view session_id) {
@@ -241,6 +250,13 @@ void DiscordVoiceClient::HandleGatewaySessionDescription(const VoiceGatewayMessa
printf("%02X", b);
}
printf("\n");
+
+ VoiceSpeakingMessage msg;
+ msg.Delay = 0;
+ msg.SSRC = m_ssrc;
+ msg.Speaking = VoiceSpeakingMessage::Microphone;
+ m_ws.Send(msg);
+
m_secret_key = d.SecretKey;
m_udp.SetSSRC(m_ssrc);
m_udp.SetSecretKey(m_secret_key);
@@ -250,6 +266,7 @@ void DiscordVoiceClient::HandleGatewaySessionDescription(const VoiceGatewayMessa
m_udp.SendEncrypted({ 0xF8, 0xFF, 0xFE });
m_udp.SendEncrypted({ 0xF8, 0xFF, 0xFE });
m_udp.Run();
+ m_connected = true;
}
void DiscordVoiceClient::Identify() {
@@ -388,4 +405,11 @@ void from_json(const nlohmann::json &j, VoiceSessionDescriptionData &m) {
JS_D("mode", m.Mode);
JS_D("secret_key", m.SecretKey);
}
+
+void to_json(nlohmann::json &j, const VoiceSpeakingMessage &m) {
+ j["op"] = VoiceGatewayOp::Speaking;
+ j["d"]["speaking"] = m.Speaking;
+ j["d"]["delay"] = m.Delay;
+ j["d"]["ssrc"] = m.SSRC;
+}
#endif
diff --git a/src/discord/voiceclient.hpp b/src/discord/voiceclient.hpp
index 4b988d5..67919e5 100644
--- a/src/discord/voiceclient.hpp
+++ b/src/discord/voiceclient.hpp
@@ -110,6 +110,20 @@ struct VoiceSessionDescriptionData {
friend void from_json(const nlohmann::json &j, VoiceSessionDescriptionData &m);
};
+struct VoiceSpeakingMessage {
+ enum {
+ Microphone = 1 << 0,
+ Soundshare = 1 << 1,
+ Priority = 1 << 2,
+ };
+
+ int Speaking;
+ int Delay;
+ uint32_t SSRC;
+
+ friend void to_json(nlohmann::json &j, const VoiceSpeakingMessage &m);
+};
+
class UDPSocket {
public:
UDPSocket();
@@ -119,6 +133,7 @@ public:
void Run();
void SetSecretKey(std::array<uint8_t, 32> key);
void SetSSRC(uint32_t ssrc);
+ void SendEncrypted(const uint8_t *data, size_t len);
void SendEncrypted(const std::vector<uint8_t> &data);
void Send(const uint8_t *data, size_t len);
std::vector<uint8_t> Receive();
@@ -205,5 +220,9 @@ private:
int m_heartbeat_msec;
Waiter m_heartbeat_waiter;
std::thread m_heartbeat_thread;
+
+ std::array<uint8_t, 1275> m_opus_buffer;
+
+ std::atomic<bool> m_connected = false;
};
#endif