42namespace DiscordCoreAPI {
82 "ChannelData was deleted, you were kicked, voice server changed, or the main gateway session was dropped. Should not "
89 inline VoiceWebSocketClose& operator=(uint16_t valueNew) {
94 inline VoiceWebSocketClose(uint16_t value) {
98 inline operator std::string_view() {
99 return VoiceWebSocketClose::outputErrorValues[mappingValues[
static_cast<uint16_t
>(value)]];
102 inline operator bool() {
107 struct VoiceSocketReadyData {
108 jsonifier::vector<std::string> modes{};
114 struct VoiceSessionDescriptionData {
115 jsonifier::vector<uint8_t> secretKey{};
118 struct SpeakingData {
123 struct VoiceConnectionHelloData {
124 uint32_t heartBeatInterval{};
127 struct VoiceUserDisconnectData {
131 struct DiscordCoreAPI_Dll VoiceUser {
132 VoiceUser() =
default;
134 VoiceUser(Snowflake userId);
136 VoiceUser& operator=(VoiceUser&&) noexcept;
138 VoiceUser& operator=(const VoiceUser&) = delete;
140 VoiceUser(const VoiceUser&) = delete;
142 DiscordCoreInternal::OpusDecoderWrapper& getDecoder();
144 std::basic_string_view<uint8_t> extractPayload();
146 void insertPayload(std::basic_string_view<uint8_t>);
148 Snowflake getUserId();
151 DiscordCoreInternal::RingBuffer<uint8_t, 10> payloads{};
152 DiscordCoreInternal::OpusDecoderWrapper decoder{};
156 struct DiscordCoreAPI_Dll RTPPacketEncrypter {
157 RTPPacketEncrypter() =
default;
159 RTPPacketEncrypter(uint32_t ssrcNew,
const std::basic_string<uint8_t>& keysNew);
161 std::basic_string_view<uint8_t> encryptPacket(DiscordCoreInternal::EncoderReturnData& audioData);
164 std::basic_string<uint8_t> data{};
165 std::basic_string<uint8_t> keys{};
166 uint8_t version{ 0x80 };
167 uint8_t flags{ 0x78 };
168 uint32_t timeStamp{};
173 struct DiscordCoreAPI_Dll MovingAverager {
174 MovingAverager(uint64_t collectionCountNew);
176 MovingAverager operator+=(int64_t value);
181 std::deque<int64_t> values{};
182 uint64_t collectionCount{};
221 class DiscordCoreAPI_Dll VoiceConnectionBridge :
public DiscordCoreInternal::UDPConnection {
223 friend class VoiceConnection;
225 VoiceConnectionBridge(DiscordCoreClient* voiceConnectionNew, std::basic_string<uint8_t>& encryptionKeyNew, StreamType streamType,
const std::string& baseUrlNew,
228 inline void applyGainRamp(int64_t sampleCount);
230 void parseOutgoingVoiceData();
232 void handleAudioBuffer()
override;
236 void disconnect()
override;
239 std::coroutine_handle<DiscordCoreAPI::CoRoutine<void, false>::promise_type>* token{};
240 std::array<opus_int16, 23040> downSampledVector{};
241 std::basic_string<uint8_t> decryptedDataString{};
242 std::array<opus_int32, 23040> upSampledVector{};
243 std::basic_string<uint8_t> encryptionKey{};
244 MovingAverager voiceUserCountAverage{ 25 };
245 DiscordCoreClient* discordCoreClient{};
246 jsonifier::vector<uint8_t> resampleVector{};
253 class DiscordCoreAPI_Dll VoiceUDPConnection :
public DiscordCoreInternal::UDPConnection {
255 VoiceUDPConnection() =
default;
257 VoiceUDPConnection(
const std::string& baseUrlNew, uint16_t portNew, StreamType streamType, VoiceConnection* ptrNew,
260 void handleAudioBuffer()
override;
262 void disconnect()
override;
265 VoiceConnection* voiceConnection{};
273 class DiscordCoreAPI_Dll
VoiceConnection :
public DiscordCoreInternal::WebSocketCore {
275 friend class DiscordCoreInternal::BaseSocketAgent;
276 friend class DiscordCoreInternal::SoundCloudAPI;
277 friend class DiscordCoreInternal::YouTubeAPI;
278 friend class VoiceConnectionBridge;
279 friend class VoiceUDPConnection;
291 bool areWeConnected();
304 std::atomic<VoiceConnectionState> connectionState{ VoiceConnectionState::Collecting_Init_Data };
306 Nanoseconds intervalCount{
static_cast<int64_t
>(960.0l / 48000.0l * 1000000000.0l) };
307 std::coroutine_handle<DiscordCoreAPI::CoRoutine<void, false>::promise_type> token{};
308 std::atomic<VoiceActiveState> prevActiveState{ VoiceActiveState::Stopped };
309 std::atomic<VoiceActiveState> activeState{ VoiceActiveState::Connecting };
310 DiscordCoreInternal::VoiceConnectionData voiceConnectionData{};
311 UnorderedMap<uint64_t, UniquePtr<VoiceUser>> voiceUsers{};
313 DiscordCoreInternal::WebSocketClient* baseShard{};
316 std::basic_string<uint8_t> encryptionKey{};
318 int64_t sampleRatePerSecond{ 48000 };
319 RTPPacketEncrypter packetEncrypter{};
321 VoiceUDPConnection udpConnection{};
322 int64_t nsPerSecond{ 1000000000 };
323 std::string audioEncryptionMode{};
325 std::atomic_bool wasItAFail{};
326 std::atomic_bool* doWeQuit{};
327 std::atomic_bool doWeSkip{};
328 int64_t samplesPerPacket{};
329 std::string externalIp{};
330 int64_t msPerPacket{};
331 std::string voiceIp{};
332 std::string baseUrl{};
333 uint32_t audioSSRC{};
336 void parseIncomingVoiceData(std::basic_string_view<uint8_t> rawDataBufferNew);
340 void skipInternal(uint32_t currentRecursionDepth = 0);
342 void checkForAndSendHeartBeat(
const bool isImmedate);
344 void sendSpeakingMessage(
const bool isSpeaking);
346 bool onMessageReceived(std::string_view data);
350 void sendVoiceConnectionData();
352 bool areWeCurrentlyPlaying();
354 bool skip(
bool wasItAFail);
356 void connectInternal();
VoiceConnectionState
For the various connection states of the VoiceConnection class.
@ Collecting_Init_Data
Collecting initialization data.
@ Collecting_Ready
Collecting the client ready.
@ Sending_Identify
Sending the identify payload.
@ Collecting_Hello
Collecting the client hello.
@ Initializing_WebSocket
Initializing the WebSocket.
@ Initializing_DatagramSocket
Initializing the datagram udp socket.
@ Collecting_Session_Description
Collecting the session-description payload.
@ Sending_Select_Protocol
Sending the select-protocol payload.
VoiceSocketOpCodes
The various opcodes that could be sent/received by the voice-websocket.
@ Speaking
Indicate which users are speaking.
@ Ready_Server
Complete the websocket handshake.
@ Heartbeat
Keep the websocket connection alive.
@ Hello
Time to wait between sending heartbeats in milliseconds.
@ Identify
Begin a voice websocket connection.
@ Session_Description
Describe the session.
@ Heartbeat_ACK
Sent to acknowledge a received client heartbeat.
@ Resumed
Acknowledge a successful session resume.
@ Client_Disconnect
A client has disconnected from the voice channel.
@ Select_Protocol
Select the voice protocol.
@ Resume
Resume a connection.
VoiceActiveState
For the various active states of the VoiceConnection class.
A CoRoutine - representing a potentially asynchronous operation/function.
DiscordCoreClient - The main class for this library.
A discord Guild. Used to connect to/disconnect from voice.
Data structure representing a single Guild, for the purposes of populating the cache.
A class representing the Song APIs.
Voice Websocket close codes.
VoiceWebSocketCloseCode
Voice Websocket close codes.
@ Voice_Server_Crashed
The server crashed. Our bad! Try resuming.
@ Session_No_Longer_Valid
Your session is no longer valid.
@ Already_Authenticated
You sent more than one identify payload. Stahp.
@ Session_Timeout
Your session has timed out.
@ Unknown_Protocol
We didn't recognize the protocol you sent.
@ Authentication_Failed
The token you sent in your identify payload is incorrect.
@ Unknown_Opcode
You sent an invalid opcode.
@ Failed_To_Decode
You sent an invalid payload in your identifying to the Gateway.
@ Server_Not_Found
We can't find the server you're trying to connect to.
@ Unknown_Encryption_Mode
We didn't recognize your encryption.
@ Not_Authenticated
You sent a payload before identifying with the Gateway.
@ Normal_Close
Normal close.
@ Disconnected
ChannelData was deleted, you were kicked, voice server changed, or the main gateway session was dropp...
VoiceConnection class - represents the connection to a given voice ChannelData.
Wrapper class for the Opus audio encoder.
A class representing a Snowflake identifier with various operations.
A thread-safe messaging block for data-structures.
A smart pointer class that provides unique ownership semantics.
Represents a single frame of audio data.
For connecting to a voice-channel. "streamInfo" is used when a socket is created to connect this bot ...