Files
sfml-streamer/Receiver.cpp
2026-06-26 22:53:15 +03:00

84 lines
1.9 KiB
C++

#include "Receiver.h"
#include <cstring>
#include <stdexcept>
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<std::mutex> 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<sf::Int16> samples(received / sizeof(sf::Int16));
std::memcpy(samples.data(), data, samples.size() * sizeof(sf::Int16));
{
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(std::move(samples));
}
m_cv.notify_one();
}
sf::sleep(sf::milliseconds(1));
}
}