From 11e4861082941fdefd26aac7b087130e88ed775e Mon Sep 17 00:00:00 2001 From: study-faraphel Date: Thu, 14 Nov 2024 13:24:49 +0100 Subject: [PATCH] improved latency before playing an audio prevented playing packets that are too old to avoid offset --- CMakeLists.txt | 2 ++ README.md | 5 ++++- source/behavior/events/audio/AudioEvent.cpp | 9 ++++++++- source/behavior/tasks/server/ServerTask.cpp | 19 +++++++++---------- source/utils/audio.cpp | 14 ++++++++++++++ source/utils/audio.hpp | 7 +++++++ source/utils/time/Chrony.cpp | 1 + source/utils/time/Chrony.hpp | 12 ++++++++++++ 8 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 source/utils/time/Chrony.cpp create mode 100644 source/utils/time/Chrony.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bdec8c3..17b4dd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ add_executable(M2-PT-DRP source/packets/base/SecurityMode.hpp source/packets/base/PacketData.hpp source/packets/info/InfoPacketData.hpp + source/utils/time/Chrony.cpp + source/utils/time/Chrony.hpp ) target_include_directories(M2-PT-DRP PRIVATE source diff --git a/README.md b/README.md index 820598d..50c3e07 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Debian ```bash +# Pre-requires +sudo apt install chrony + # Download sudo apt install -y git git clone https://git.faraphel.fr/study-faraphel/M2-PT-DRP @@ -17,6 +20,6 @@ cmake --build build cd build # Run -./M2-PT-DRP --host ff02::1 --ipv6 +sudo ./M2-PT-DRP --host ff02::1 --ipv6 ``` diff --git a/source/behavior/events/audio/AudioEvent.cpp b/source/behavior/events/audio/AudioEvent.cpp index 93a8884..6a187be 100644 --- a/source/behavior/events/audio/AudioEvent.cpp +++ b/source/behavior/events/audio/AudioEvent.cpp @@ -5,6 +5,7 @@ #include "packets/audio/AudioPacketData.hpp" #include "packets/base/PacketData.hpp" +#include "utils/audio.hpp" namespace drp::event { @@ -90,6 +91,12 @@ void AudioEvent::loopPlay() { // get the most recent audio chunk const auto audioPacket = this->audioQueue.top(); + // if the packet should have started playing before, skip it + if (audioPacket.timePlay < std::chrono::high_resolution_clock::now()) { + this->audioQueue.pop(); + continue; + } + // update the stream with the new audio settings this->updateAudioStream( audioPacket.channels, @@ -137,4 +144,4 @@ void AudioEvent::loopPlay() { } -} \ No newline at end of file +} diff --git a/source/behavior/tasks/server/ServerTask.cpp b/source/behavior/tasks/server/ServerTask.cpp index 46baf61..77f2142 100644 --- a/source/behavior/tasks/server/ServerTask.cpp +++ b/source/behavior/tasks/server/ServerTask.cpp @@ -57,10 +57,8 @@ ServerTask::~ServerTask() { void ServerTask::handle(Context& context) { // TODO(Faraphel): create a chrony server - // allow anybody to connect as a chrony client - FILE* chronyProcess = popen("chronyc allow all 2>&1", "r"); - if (pclose(chronyProcess) == -1) - std::cerr << "Could not allow chrony connection." << std::endl; + // get the time of the start of the processing + const auto startProcessingTime = std::chrono::high_resolution_clock::now(); // prepare the packet structure packet::base::Packet packet {}; @@ -116,12 +114,13 @@ void ServerTask::handle(Context& context) { std::cout << "[Task - Server] Sent: " << done << " bytes" << std::endl; - // wait for the duration of the audio chunk - std::this_thread::sleep_for(std::chrono::milliseconds(static_cast( - (1 / static_cast(this->sampleRate * this->channels * mpg123_encsize(this->encoding))) * - 1000 * - static_cast(done) - ))); + // wait for the duration of the audio chunk, since the start of the processing + std::this_thread::sleep_until(startProcessingTime + util::get_audio_chunk_duration( + this->sampleRate, + this->channels, + mpg123_encsize(this->encoding), + done + )); } diff --git a/source/utils/audio.cpp b/source/utils/audio.cpp index 75e4053..a811108 100644 --- a/source/utils/audio.cpp +++ b/source/utils/audio.cpp @@ -1,5 +1,6 @@ #include "audio.hpp" +#include #include #include @@ -30,4 +31,17 @@ std::uint32_t encoding_mpg123_to_PulseAudio(const int encoding_mpg123) { } +std::chrono::milliseconds get_audio_chunk_duration( + const long sampleRate, + const int channels, + const int encodingSize, + const std::size_t length +) { + return std::chrono::milliseconds(static_cast( + (1 / static_cast(sampleRate * channels * encodingSize)) * + 1000 * static_cast(length) + )); +} + + } \ No newline at end of file diff --git a/source/utils/audio.hpp b/source/utils/audio.hpp index a5e7ac4..d4ae37e 100644 --- a/source/utils/audio.hpp +++ b/source/utils/audio.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include @@ -8,5 +9,11 @@ namespace drp::util { std::uint32_t encoding_mpg123_to_PulseAudio(int encoding_mpg123); +std::chrono::milliseconds get_audio_chunk_duration( + long sampleRate, + int channels, + int encodingSize, + std::size_t length +); } \ No newline at end of file diff --git a/source/utils/time/Chrony.cpp b/source/utils/time/Chrony.cpp new file mode 100644 index 0000000..9ec6aae --- /dev/null +++ b/source/utils/time/Chrony.cpp @@ -0,0 +1 @@ +#include "Chrony.hpp" diff --git a/source/utils/time/Chrony.hpp b/source/utils/time/Chrony.hpp new file mode 100644 index 0000000..40fe00f --- /dev/null +++ b/source/utils/time/Chrony.hpp @@ -0,0 +1,12 @@ +#pragma once + + +namespace drp::util::time { + + +class Chrony { + +}; + + +} \ No newline at end of file