84 lines
1.9 KiB
C++
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));
|
|
}
|
|
}
|