Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/no user join ready dave #1289

Merged
11 changes: 0 additions & 11 deletions include/dpp/cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -1334,17 +1334,6 @@ class DPP_EXPORT cluster {
event_router_t<voice_buffer_send_t> on_voice_buffer_send;


/**
* @brief Called when a user is talking on a voice channel.
*
* @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr.
*
* @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID.
* The function signature for this event takes a single `const` reference of type voice_user_talking_t&, and returns void.
*/
event_router_t<voice_user_talking_t> on_voice_user_talking;


/**
* @brief Called when a voice channel is connected and ready to send audio.
* Note that this is not directly attached to the READY event of the websocket,
Expand Down
37 changes: 34 additions & 3 deletions include/dpp/discordvoiceclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ class DPP_EXPORT discord_voice_client : public websocket_client
*/
void cleanup();

/**
* @brief A frame of silence packet
*/
static constexpr uint8_t silence_packet[3] = { 0xf8, 0xff, 0xfe };

/**
* @brief Mutex for outbound packet stream
*/
Expand Down Expand Up @@ -434,6 +439,13 @@ class DPP_EXPORT discord_voice_client : public websocket_client
*/
bool paused;

/**
* @brief Whether has sent 5 frame of silence before stopping on pause.
*
* This is to avoid unintended Opus interpolation with subsequent transmissions.
*/
bool sent_stop_frames;

#ifdef HAVE_VOICE
/**
* @brief libopus encoder
Expand Down Expand Up @@ -650,8 +662,10 @@ class DPP_EXPORT discord_voice_client : public websocket_client
* @param packet packet data
* @param len length of packet
* @param duration duration of opus packet
* @param send_now send this packet right away without buffering.
* Do NOT set send_now to true outside write_ready.
*/
void send(const char* packet, size_t len, uint64_t duration);
void send(const char* packet, size_t len, uint64_t duration, bool send_now = false);

/**
* @brief Queue a message to be sent via the websocket
Expand Down Expand Up @@ -962,6 +976,10 @@ class DPP_EXPORT discord_voice_client : public websocket_client
* @param duration Generally duration is 2.5, 5, 10, 20, 40 or 60
* if the timescale is 1000000 (1ms)
*
* @param send_now Send this packet right away without buffering,
* this will skip duration calculation for the packet being sent
* and only safe to be set to true in write_ready.
*
* @return discord_voice_client& Reference to self
*
* @note It is your responsibility to ensure that packets of data
Expand All @@ -972,7 +990,7 @@ class DPP_EXPORT discord_voice_client : public websocket_client
*
* @throw dpp::voice_exception If data length is invalid or voice support not compiled into D++
*/
discord_voice_client& send_audio_opus(uint8_t* opus_packet, const size_t length, uint64_t duration);
discord_voice_client& send_audio_opus(const uint8_t* opus_packet, const size_t length, uint64_t duration, bool send_now = false);

/**
* @brief Send opus packets to the voice channel
Expand All @@ -999,7 +1017,7 @@ class DPP_EXPORT discord_voice_client : public websocket_client
*
* @throw dpp::voice_exception If data length is invalid or voice support not compiled into D++
*/
discord_voice_client& send_audio_opus(uint8_t* opus_packet, const size_t length);
discord_voice_client& send_audio_opus(const uint8_t* opus_packet, const size_t length);

/**
* @brief Send silence to the voice channel
Expand All @@ -1012,6 +1030,19 @@ class DPP_EXPORT discord_voice_client : public websocket_client
*/
discord_voice_client& send_silence(const uint64_t duration);

/**
* @brief Send stop frames to the voice channel.
*
* @param send_now send this packet right away without buffering.
* Do NOT set send_now to true outside write_ready.
* Also make sure you're not locking stream_mutex if you
* don't set send_now to true.
*
* @return discord_voice_client& Reference to self
* @throw dpp::voice_exception if voice support is not compiled into D++
*/
discord_voice_client& send_stop_frames(bool send_now = false);

/**
* @brief Sets the audio type that will be sent with send_audio_* methods.
*
Expand Down
25 changes: 1 addition & 24 deletions include/dpp/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -1989,30 +1989,7 @@ struct DPP_EXPORT voice_buffer_send_t : public event_dispatch_t {
};

/**
* @brief voice user talking
*/
struct DPP_EXPORT voice_user_talking_t : public event_dispatch_t {
using event_dispatch_t::event_dispatch_t;
using event_dispatch_t::operator=;

/**
* @brief voice client where user is talking
*/
class discord_voice_client* voice_client = nullptr;

/**
* @brief talking user id
*/
snowflake user_id = {};

/**
* @brief flags for talking user
*/
uint8_t talking_flags = 0;
};

/**
* @brief voice user talking
* @brief voice ready
*/
struct DPP_EXPORT voice_ready_t : public event_dispatch_t {
using event_dispatch_t::event_dispatch_t;
Expand Down
27 changes: 22 additions & 5 deletions src/dpp/discordvoiceclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*
************************************************************************************/

#include <cstdint>
#ifdef _WIN32
#include <WinSock2.h>
#include <WS2tcpip.h>
Expand Down Expand Up @@ -148,6 +149,9 @@ bool discord_voice_client::is_end_to_end_encrypted() const {

discord_voice_client& discord_voice_client::pause_audio(bool pause) {
this->paused = pause;
if (!this->paused) {
this->sent_stop_frames = false;
}
return *this;
}

Expand All @@ -172,10 +176,13 @@ dpp::utility::uptime discord_voice_client::get_remaining() {
}

discord_voice_client& discord_voice_client::stop_audio() {
std::lock_guard<std::mutex> lock(this->stream_mutex);
outbuf.clear();
track_meta.clear();
tracks = 0;
{
std::lock_guard<std::mutex> lock(this->stream_mutex);
outbuf.clear();
track_meta.clear();
tracks = 0;
}
this->send_stop_frames();
return *this;
}

Expand Down Expand Up @@ -398,7 +405,6 @@ discord_voice_client& discord_voice_client::skip_to_next_marker() {
}

discord_voice_client& discord_voice_client::send_silence(const uint64_t duration) {
uint8_t silence_packet[3] = { 0xf8, 0xff, 0xfe };
send_audio_opus(silence_packet, 3, duration);
return *this;
}
Expand Down Expand Up @@ -443,4 +449,15 @@ uint16_t discord_voice_client::get_iteration_interval() {
return this->iteration_interval;
}

discord_voice_client& discord_voice_client::send_stop_frames(bool send_now) {
uint8_t silence_frames[sizeof(silence_packet) / sizeof(*silence_packet) * 5];
for (size_t i = 0; i < sizeof(silence_frames) / sizeof(*silence_frames); i++) {
silence_frames[i] = silence_packet[i % 3];
}

this->send_audio_opus(silence_frames, sizeof(silence_frames) / sizeof(*silence_frames), 20, send_now);

return *this;
}

} // namespace dpp
Loading
Loading