60 lines
2.0 KiB
C++
60 lines
2.0 KiB
C++
#ifndef RECEIVER_H
|
||
#define RECEIVER_H
|
||
|
||
#include <SFML/Audio.hpp>
|
||
#include <SFML/Network.hpp>
|
||
|
||
#include <atomic>
|
||
#include <condition_variable>
|
||
#include <mutex>
|
||
#include <queue>
|
||
#include <thread>
|
||
#include <vector>
|
||
|
||
/**
|
||
* @brief Получает PCM mono 44100 Hz по UDP и воспроизводит поток локально.
|
||
*/
|
||
class Receiver : public sf::SoundStream {
|
||
public:
|
||
/**
|
||
* @brief Создает receiver и привязывает UDP-сокет к заданному порту.
|
||
* @param port Локальный UDP-порт для приема аудио.
|
||
*/
|
||
explicit Receiver(unsigned short port);
|
||
|
||
/**
|
||
* @brief Останавливает прием и воспроизведение.
|
||
*/
|
||
~Receiver();
|
||
|
||
/**
|
||
* @brief Запускает прием UDP-аудио и локальное воспроизведение.
|
||
*/
|
||
void start();
|
||
|
||
/**
|
||
* @brief Останавливает прием UDP-аудио и локальное воспроизведение.
|
||
*/
|
||
void stopReceiver();
|
||
|
||
protected:
|
||
bool onGetData(Chunk& chunk) override; //!< Перегрузка.
|
||
void onSeek(sf::Time timeOffset) override; //!< Перегрузка.
|
||
|
||
private:
|
||
void receiveLoop();
|
||
|
||
sf::UdpSocket m_socket; //!< UDP-сокет для приема аудиопакетов.
|
||
std::atomic<bool> m_running {false}; //!< Флаг активного состояния receiver.
|
||
std::thread m_receiverThread; //!< Поток фонового приема UDP-пакетов.
|
||
|
||
std::queue<std::vector<sf::Int16>> m_queue; //!< Очередь принятых аудиочанков.
|
||
std::vector<sf::Int16> m_current; //!< Текущий чанк, отданный в `sf::SoundStream`.
|
||
|
||
std::mutex m_mutex; //!< Общая блокировка внутреннего состояния receiver.
|
||
std::condition_variable m_cv; //!< Уведомление о поступлении новых аудиоданных.
|
||
};
|
||
|
||
|
||
#endif //RECEIVER_H
|