Closed MysticCoss closed 3 years ago
You guessed right, the packets are indeed sent slower than they should, mainly because the code didn't care how long it actually takes to send a packet and therefore created an additional delay. I did some modifications on the audio sending code based on your suggestion and pushed it to the development branch. Feel free to check it out. Please let me know if that fixes the issue for you.
Thank you for that useful code. That is a step further to fix this issue. It took me half a month testing and trying various methods to achieve the best audio quality. My guess is right, our target is the sleep function, i was surprise that whatever library it comes from(boost::chrono, boost::asio::steady_timer, std etc...), it has the same core function provided by the OS(mine is window, i have no experience with Linux yet). I met this piece of code on the internet but i lost its link as credit. A bit explain about this piece of code:
So we use a mix of 2 method above. Detail you can see in the code, which is easy to understand. I just change the sleep function, the result is very well, the music is not broken anymore. Don't forget to config opus expected packet loss, because life is not dream Code:
#include <math.h>
#include <chrono>
#include <window.h>
static void timerSleep(double seconds) {
using namespace std::chrono;
static HANDLE timer = CreateWaitableTimer(NULL, FALSE, NULL);
static double estimate = 5e-3;
static double mean = 5e-3;
static double m2 = 0;
static int64_t count = 1;
while (seconds - estimate > 1e-7) {
double toWait = seconds - estimate;
LARGE_INTEGER due;
due.QuadPart = -int64_t(toWait * 1e7);
auto start = high_resolution_clock::now();
SetWaitableTimerEx(timer, &due, 0, NULL, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
auto end = high_resolution_clock::now();
double observed = (end - start).count() / 1e9;
seconds -= observed;
++count;
double error = observed - toWait;
double delta = error - mean;
mean += delta / count;
m2 += delta * (error - mean);
double stddev = sqrt(m2 / (count - 1));
estimate = mean + stddev;
}
// spin lock
auto start = high_resolution_clock::now();
while ((high_resolution_clock::now() - start).count() / 1e9 < seconds);
}
Link to my post on stackoverflow which contain bigger code which maybe useful: https://stackoverflow.com/questions/66707126/voice-data-sent-over-udp-is-choppy?noredirect=1#comment117921947_66707126 Thanks
Hello, i had a look at opus encoder options recently. Setting the expected packet loss rate as you suggested brought some improvements. Additionally enabling the inband error correction finally did the trick. The voice client is now working as expected on both my windows and my linux machines, so i'm closing this issue now. Again thanks for report and your suggestions.
I have tried the way you send the udp packets here:
the music is so "broken" My guess the cause: packets are sent slower than they should because sleep_for is not accurate. I have tried to modify above code:
The result is better but it's not as smooth as i expect, the music broken sometimes, not all the time. There are 2 possible causes: