#include "Receiver.h" #include #include Receiver::Receiver(unsigned short port) { initialize(1, 44100); m_socket.setBlocking(false); if (m_socket.bind(port) != sf::Socket::Done) { throw std::runtime_error("Cannot bind UDP port"); } } Receiver::~Receiver() { stopReceiver(); } void Receiver::start() { if (m_running.exchange(true)) { return; } m_receiverThread = std::thread(&Receiver::receiveLoop, this); play(); } void Receiver::stopReceiver() { if (!m_running.exchange(false) && !m_receiverThread.joinable()) { return; } m_cv.notify_all(); stop(); if (m_receiverThread.joinable()) { m_receiverThread.join(); } } bool Receiver::onGetData(Chunk& chunk) { std::unique_lock lock(m_mutex); m_cv.wait(lock, [&] { return !m_queue.empty() || !m_running.load(); }); if (!m_running.load() && m_queue.empty()) { return false; } m_current = std::move(m_queue.front()); m_queue.pop(); chunk.samples = m_current.data(); chunk.sampleCount = m_current.size(); return true; } void Receiver::onSeek(sf::Time) { } void Receiver::receiveLoop() { while (m_running.load()) { char data[4096]; std::size_t received = 0; sf::IpAddress sender; unsigned short senderPort = 0; const auto status = m_socket.receive(data, sizeof(data), received, sender, senderPort); if (status == sf::Socket::Done && received > 0) { std::vector samples(received / sizeof(sf::Int16)); std::memcpy(samples.data(), data, samples.size() * sizeof(sf::Int16)); { std::lock_guard lock(m_mutex); m_queue.push(std::move(samples)); } m_cv.notify_one(); } sf::sleep(sf::milliseconds(1)); } }