Rename PcmListener to PcmStream::Listener

Reorganize include order
This commit is contained in:
badaix 2021-12-12 12:19:46 +01:00
parent c49841cf6f
commit d326252268
30 changed files with 227 additions and 144 deletions

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2020 Johannes Pohl Copyright (C) 2014-2021 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,15 +19,18 @@
#ifndef CONTROLLER_HPP #ifndef CONTROLLER_HPP
#define CONTROLLER_HPP #define CONTROLLER_HPP
// local headers
#include "client_connection.hpp" #include "client_connection.hpp"
#include "client_settings.hpp" #include "client_settings.hpp"
#include "decoder/decoder.hpp" #include "decoder/decoder.hpp"
#include "message/message.hpp" #include "message/message.hpp"
#include "message/server_settings.hpp" #include "message/server_settings.hpp"
// #include "message/stream_tags.hpp"
// #include "metadata.hpp"
#include "player/player.hpp" #include "player/player.hpp"
#include "stream.hpp" #include "stream.hpp"
// 3rd party headers
// standard headers
#include <atomic> #include <atomic>
#include <thread> #include <thread>

View file

@ -16,14 +16,20 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "server.hpp" #include "server.hpp"
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "config.hpp" #include "config.hpp"
#include "message/client_info.hpp" #include "message/client_info.hpp"
#include "message/hello.hpp" #include "message/hello.hpp"
// #include "message/stream_tags.hpp"
#include "message/time.hpp" #include "message/time.hpp"
#include "stream_session_tcp.hpp" #include "stream_session_tcp.hpp"
// 3rd party headers
// standard headers
#include <iostream> #include <iostream>
using namespace std; using namespace std;

View file

@ -19,13 +19,7 @@
#ifndef SERVER_HPP #ifndef SERVER_HPP
#define SERVER_HPP #define SERVER_HPP
#include <boost/asio.hpp> // local headers
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <vector>
#include "common/queue.h" #include "common/queue.h"
#include "common/sample_format.hpp" #include "common/sample_format.hpp"
#include "control_server.hpp" #include "control_server.hpp"
@ -38,6 +32,17 @@
#include "stream_session.hpp" #include "stream_session.hpp"
#include "streamreader/stream_manager.hpp" #include "streamreader/stream_manager.hpp"
// 3rd party headers
#include <boost/asio.hpp>
// standard headers
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <vector>
using namespace streamreader; using namespace streamreader;
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
@ -45,14 +50,11 @@ using acceptor_ptr = std::unique_ptr<tcp::acceptor>;
using session_ptr = std::shared_ptr<StreamSession>; using session_ptr = std::shared_ptr<StreamSession>;
/// Forwars PCM data to the connected clients
/** /**
* Reads PCM data using PipeStream, implements PcmListener to get the (encoded) PCM stream. * Receives and routes PcmStreams
* Accepts and holds client connections (StreamSession) * Processes ControlSession messages
* Receives (via the StreamMessageReceiver interface) and answers messages from the clients
* Forwards PCM data to the clients
*/ */
class Server : public StreamMessageReceiver, public ControlMessageReceiver, public PcmListener class Server : public StreamMessageReceiver, public ControlMessageReceiver, public PcmStream::Listener
{ {
public: public:
// TODO: revise handler names // TODO: revise handler names
@ -77,7 +79,7 @@ private:
}; };
void onNewSession(std::shared_ptr<StreamSession> session) override; void onNewSession(std::shared_ptr<StreamSession> session) override;
/// Implementation of PcmListener /// Implementation of PcmStream::Listener
void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) override; void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) override;
void onStateChanged(const PcmStream* pcmStream, ReaderState state) override; void onStateChanged(const PcmStream* pcmStream, ReaderState state) override;
void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override; void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override;

View file

@ -16,14 +16,20 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "stream_server.hpp" #include "stream_server.hpp"
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "config.hpp" #include "config.hpp"
#include "message/client_info.hpp" #include "message/client_info.hpp"
#include "message/hello.hpp" #include "message/hello.hpp"
// #include "message/stream_tags.hpp"
#include "message/time.hpp" #include "message/time.hpp"
#include "stream_session_tcp.hpp" #include "stream_session_tcp.hpp"
// 3rd party headers
// standard headers
#include <iostream> #include <iostream>
using namespace std; using namespace std;

View file

@ -19,13 +19,7 @@
#ifndef STREAM_SERVER_HPP #ifndef STREAM_SERVER_HPP
#define STREAM_SERVER_HPP #define STREAM_SERVER_HPP
#include <boost/asio.hpp> // local headers
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <vector>
#include "common/queue.h" #include "common/queue.h"
#include "common/sample_format.hpp" #include "common/sample_format.hpp"
#include "control_server.hpp" #include "control_server.hpp"
@ -37,6 +31,17 @@
#include "stream_session.hpp" #include "stream_session.hpp"
#include "streamreader/stream_manager.hpp" #include "streamreader/stream_manager.hpp"
// 3rd party headers
#include <boost/asio.hpp>
// standard headers
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <vector>
using namespace streamreader; using namespace streamreader;
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
@ -46,7 +51,7 @@ using session_ptr = std::shared_ptr<StreamSession>;
/// Forwars PCM data to the connected clients /// Forwars PCM data to the connected clients
/** /**
* Reads PCM data using PipeStream, implements PcmListener to get the (encoded) PCM stream. * Reads PCM data from several StreamSessions
* Accepts and holds client connections (StreamSession) * Accepts and holds client connections (StreamSession)
* Receives (via the StreamMessageReceiver interface) and answers messages from the clients * Receives (via the StreamMessageReceiver interface) and answers messages from the clients
* Forwards PCM data to the clients * Forwards PCM data to the clients

View file

@ -16,7 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "airplay_stream.hpp" #include "airplay_stream.hpp"
// local headers
#include "base64.h" #include "base64.h"
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
@ -47,7 +50,7 @@ string hex2str(const string& input)
* Without HAS_EXPAT defined no parsing will occur. * Without HAS_EXPAT defined no parsing will occur.
*/ */
AirplayStream::AirplayStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) AirplayStream::AirplayStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: ProcessStream(pcmListener, ioc, server_settings, uri), port_(5000), pipe_open_timer_(ioc) : ProcessStream(pcmListener, ioc, server_settings, uri), port_(5000), pipe_open_timer_(ioc)
{ {
logStderr_ = true; logStderr_ = true;

View file

@ -19,12 +19,12 @@
#ifndef AIRPLAY_STREAM_HPP #ifndef AIRPLAY_STREAM_HPP
#define AIRPLAY_STREAM_HPP #define AIRPLAY_STREAM_HPP
// local headers
#include "process_stream.hpp" #include "process_stream.hpp"
/* // 3rd party headers
* Expat is used in metadata parsing from Shairport-sync. // Expat is used in metadata parsing from Shairport-sync.
* Without HAS_EXPAT defined no parsing will occur. // Without HAS_EXPAT defined no parsing will occur.
*/
#ifdef HAS_EXPAT #ifdef HAS_EXPAT
#include <expat.h> #include <expat.h>
#endif #endif
@ -51,7 +51,7 @@ public:
/** /**
* Starts librespot, reads PCM data from stdout, and passes the data to an encoder. * Starts librespot, reads PCM data from stdout, and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
* usage: * usage:
* snapserver -s "airplay:///shairport-sync?name=Airplay[&devicename=Snapcast][&port=5000]" * snapserver -s "airplay:///shairport-sync?name=Airplay[&devicename=Snapcast][&port=5000]"
*/ */
@ -59,7 +59,7 @@ class AirplayStream : public ProcessStream
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
AirplayStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); AirplayStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
~AirplayStream() override; ~AirplayStream() override;
protected: protected:

View file

@ -16,17 +16,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#include <cerrno> // prototype/interface header file
#include <fcntl.h> #include "alsa_stream.hpp"
#include <memory>
#include <sys/stat.h>
#include <unistd.h>
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/str_compat.hpp" #include "common/str_compat.hpp"
#include "alsa_stream.hpp" // standard headers
#include <cerrno>
#include <memory>
using namespace std; using namespace std;
@ -65,7 +65,7 @@ void wait(boost::asio::steady_timer& timer, const std::chrono::duration<Rep, Per
} // namespace } // namespace
AlsaStream::AlsaStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) AlsaStream::AlsaStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: PcmStream(pcmListener, ioc, server_settings, uri), handle_(nullptr), read_timer_(strand_), silence_(0ms) : PcmStream(pcmListener, ioc, server_settings, uri), handle_(nullptr), read_timer_(strand_), silence_(0ms)
{ {
device_ = uri_.getQuery("device", "hw:0"); device_ = uri_.getQuery("device", "hw:0");

View file

@ -19,7 +19,10 @@
#ifndef ALSA_STREAM_HPP #ifndef ALSA_STREAM_HPP
#define ALSA_STREAM_HPP #define ALSA_STREAM_HPP
// local headers
#include "pcm_stream.hpp" #include "pcm_stream.hpp"
// 3rd party headers
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -31,13 +34,13 @@ namespace streamreader
/** /**
* Reads PCM from an alsa audio device device and passes the data to an encoder. * Reads PCM from an alsa audio device device and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class AlsaStream : public PcmStream class AlsaStream : public PcmStream
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
AlsaStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); AlsaStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
void start() override; void start() override;
void stop() override; void stop() override;

View file

@ -19,12 +19,18 @@
#ifndef ASIO_STREAM_HPP #ifndef ASIO_STREAM_HPP
#define ASIO_STREAM_HPP #define ASIO_STREAM_HPP
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/str_compat.hpp" #include "common/str_compat.hpp"
#include "pcm_stream.hpp" #include "pcm_stream.hpp"
#include <atomic>
// 3rd party headers
#include <boost/asio.hpp> #include <boost/asio.hpp>
// standard headers
#include <atomic>
namespace streamreader namespace streamreader
{ {
@ -33,7 +39,7 @@ class AsioStream : public PcmStream
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
AsioStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); AsioStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
void start() override; void start() override;
void stop() override; void stop() override;
@ -82,7 +88,7 @@ void AsioStream<ReadStream>::wait(Timer& timer, const std::chrono::duration<Rep,
template <typename ReadStream> template <typename ReadStream>
AsioStream<ReadStream>::AsioStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) AsioStream<ReadStream>::AsioStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: PcmStream(pcmListener, ioc, server_settings, uri), read_timer_(strand_), state_timer_(strand_) : PcmStream(pcmListener, ioc, server_settings, uri), read_timer_(strand_), state_timer_(strand_)
{ {
chunk_ = std::make_unique<msg::PcmChunk>(sampleFormat_, chunk_ms_); chunk_ = std::make_unique<msg::PcmChunk>(sampleFormat_, chunk_ms_);

View file

@ -16,14 +16,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#include <fcntl.h> // prototype/interface header file
#include <memory> #include "file_stream.hpp"
#include <sys/stat.h>
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "encoder/encoder_factory.hpp" #include "encoder/encoder_factory.hpp"
#include "file_stream.hpp"
// 3rd party headers
#include <memory>
using namespace std; using namespace std;
@ -34,7 +36,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "FileStream"; static constexpr auto LOG_TAG = "FileStream";
FileStream::FileStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) FileStream::FileStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: PosixStream(pcmListener, ioc, server_settings, uri) : PosixStream(pcmListener, ioc, server_settings, uri)
{ {
struct stat buffer; struct stat buffer;

View file

@ -19,6 +19,7 @@
#ifndef FILE_STREAM_HPP #ifndef FILE_STREAM_HPP
#define FILE_STREAM_HPP #define FILE_STREAM_HPP
// local headers
#include "posix_stream.hpp" #include "posix_stream.hpp"
namespace streamreader namespace streamreader
@ -28,13 +29,13 @@ namespace streamreader
/** /**
* Reads PCM from a file and passes the data to an encoder. * Reads PCM from a file and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class FileStream : public PosixStream class FileStream : public PosixStream
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
FileStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); FileStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
protected: protected:
void do_connect() override; void do_connect() override;

View file

@ -16,11 +16,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "librespot_stream.hpp" #include "librespot_stream.hpp"
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/utils/string_utils.hpp" #include "common/utils/string_utils.hpp"
// standard headers
#include <regex> #include <regex>
@ -32,7 +37,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "LibrespotStream"; static constexpr auto LOG_TAG = "LibrespotStream";
LibrespotStream::LibrespotStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) LibrespotStream::LibrespotStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: ProcessStream(pcmListener, ioc, server_settings, uri) : ProcessStream(pcmListener, ioc, server_settings, uri)
{ {
wd_timeout_sec_ = cpt::stoul(uri_.getQuery("wd_timeout", "7800")); ///< 130min wd_timeout_sec_ = cpt::stoul(uri_.getQuery("wd_timeout", "7800")); ///< 130min

View file

@ -19,6 +19,7 @@
#ifndef SPOTIFY_STREAM_HPP #ifndef SPOTIFY_STREAM_HPP
#define SPOTIFY_STREAM_HPP #define SPOTIFY_STREAM_HPP
// local headers
#include "process_stream.hpp" #include "process_stream.hpp"
namespace streamreader namespace streamreader
@ -28,7 +29,7 @@ namespace streamreader
/** /**
* Starts librespot, reads PCM data from stdout, and passes the data to an encoder. * Starts librespot, reads PCM data from stdout, and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
* usage: * usage:
* snapserver -s "spotify:///librespot?name=Spotify&username=<my username>&password=<my password>[&devicename=Snapcast][&bitrate=320][&volume=<volume in * snapserver -s "spotify:///librespot?name=Spotify&username=<my username>&password=<my password>[&devicename=Snapcast][&bitrate=320][&volume=<volume in
* percent>][&cache=<cache dir>]" * percent>][&cache=<cache dir>]"
@ -37,7 +38,7 @@ class LibrespotStream : public ProcessStream
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
LibrespotStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); LibrespotStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
protected: protected:
bool killall_; bool killall_;

View file

@ -16,7 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "meta_stream.hpp" #include "meta_stream.hpp"
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/utils/string_utils.hpp" #include "common/utils/string_utils.hpp"
@ -32,7 +35,7 @@ static constexpr auto LOG_TAG = "MetaStream";
// static constexpr auto kResyncTolerance = 50ms; // static constexpr auto kResyncTolerance = 50ms;
MetaStream::MetaStream(PcmListener* pcmListener, const std::vector<std::shared_ptr<PcmStream>>& streams, boost::asio::io_context& ioc, MetaStream::MetaStream(PcmStream::Listener* pcmListener, const std::vector<std::shared_ptr<PcmStream>>& streams, boost::asio::io_context& ioc,
const ServerSettings& server_settings, const StreamUri& uri) const ServerSettings& server_settings, const StreamUri& uri)
: PcmStream(pcmListener, ioc, server_settings, uri), first_read_(true) : PcmStream(pcmListener, ioc, server_settings, uri), first_read_(true)
{ {

View file

@ -19,8 +19,11 @@
#ifndef META_STREAM_HPP #ifndef META_STREAM_HPP
#define META_STREAM_HPP #define META_STREAM_HPP
// local headers
#include "posix_stream.hpp" #include "posix_stream.hpp"
#include "resampler.hpp" #include "resampler.hpp"
// standard headers
#include <memory> #include <memory>
namespace streamreader namespace streamreader
@ -31,13 +34,13 @@ namespace streamreader
/** /**
* Reads PCM and passes the data to an encoder. * Reads PCM and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class MetaStream : public PcmStream, public PcmListener class MetaStream : public PcmStream, public PcmStream::Listener
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PcmListener /// ctor. Encoded PCM data is passed to the PcmStream::Listener
MetaStream(PcmListener* pcmListener, const std::vector<std::shared_ptr<PcmStream>>& streams, boost::asio::io_context& ioc, MetaStream(PcmStream::Listener* pcmListener, const std::vector<std::shared_ptr<PcmStream>>& streams, boost::asio::io_context& ioc,
const ServerSettings& server_settings, const StreamUri& uri); const ServerSettings& server_settings, const StreamUri& uri);
virtual ~MetaStream(); virtual ~MetaStream();
@ -61,7 +64,7 @@ public:
void play(ResultHandler handler) override; void play(ResultHandler handler) override;
protected: protected:
/// Implementation of PcmListener /// Implementation of PcmStream::Listener
void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) override; void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) override;
void onStateChanged(const PcmStream* pcmStream, ReaderState state) override; void onStateChanged(const PcmStream* pcmStream, ReaderState state) override;
void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override; void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override;

View file

@ -16,8 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "pcm_stream.hpp" #include "pcm_stream.hpp"
// local headers
#include "base64.h" #include "base64.h"
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/error_code.hpp" #include "common/error_code.hpp"
@ -27,11 +29,11 @@
#include "control_error.hpp" #include "control_error.hpp"
#include "encoder/encoder_factory.hpp" #include "encoder/encoder_factory.hpp"
// 3rd party headers
#include <boost/asio/ip/host_name.hpp> #include <boost/asio/ip/host_name.hpp>
#include <fcntl.h> // standard headers
#include <memory> #include <memory>
#include <sys/stat.h>
using namespace std; using namespace std;
@ -42,7 +44,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "PcmStream"; static constexpr auto LOG_TAG = "PcmStream";
PcmStream::PcmStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) PcmStream::PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: active_(false), strand_(net::make_strand(ioc.get_executor())), pcmListeners_{pcmListener}, uri_(uri), chunk_ms_(20), state_(ReaderState::kIdle), : active_(false), strand_(net::make_strand(ioc.get_executor())), pcmListeners_{pcmListener}, uri_(uri), chunk_ms_(20), state_(ReaderState::kIdle),
ioc_(ioc), server_settings_(server_settings), req_id_(0), property_timer_(strand_) ioc_(ioc), server_settings_(server_settings), req_id_(0), property_timer_(strand_)
{ {
@ -302,7 +304,7 @@ json PcmStream::toJson() const
} }
void PcmStream::addListener(PcmListener* pcmListener) void PcmStream::addListener(PcmStream::Listener* pcmListener)
{ {
pcmListeners_.push_back(pcmListener); pcmListeners_.push_back(pcmListener);
} }

View file

@ -19,15 +19,7 @@
#ifndef PCM_STREAM_HPP #ifndef PCM_STREAM_HPP
#define PCM_STREAM_HPP #define PCM_STREAM_HPP
#include <atomic> // local headers
#include <mutex>
#include <string>
#include <vector>
#include <boost/asio/io_context.hpp>
#include <boost/asio/read_until.hpp>
#include <boost/asio/steady_timer.hpp>
#include "common/error_code.hpp" #include "common/error_code.hpp"
#include "common/json.hpp" #include "common/json.hpp"
#include "common/sample_format.hpp" #include "common/sample_format.hpp"
@ -39,8 +31,18 @@
#include "stream_control.hpp" #include "stream_control.hpp"
#include "stream_uri.hpp" #include "stream_uri.hpp"
// 3rd party headers
#include <boost/asio/io_context.hpp>
#include <boost/asio/read_until.hpp>
#include <boost/asio/steady_timer.hpp>
// standard headers
#include <atomic>
#include <mutex>
#include <string>
#include <vector>
namespace bp = boost::process;
namespace net = boost::asio; namespace net = boost::asio;
using json = nlohmann::json; using json = nlohmann::json;
@ -92,35 +94,34 @@ static constexpr auto kUriChunkMs = "chunk_ms";
static constexpr auto kControlScript = "controlscript"; static constexpr auto kControlScript = "controlscript";
/// Callback interface for users of PcmStream
/**
* Users of PcmStream should implement this to get the data
*/
class PcmListener
{
public:
virtual void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) = 0;
virtual void onStateChanged(const PcmStream* pcmStream, ReaderState state) = 0;
virtual void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) = 0;
virtual void onChunkEncoded(const PcmStream* pcmStream, std::shared_ptr<msg::PcmChunk> chunk, double duration) = 0;
virtual void onResync(const PcmStream* pcmStream, double ms) = 0;
};
/// Reads and decodes PCM data /// Reads and decodes PCM data
/** /**
* Reads PCM and passes the data to an encoder. * Reads PCM and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class PcmStream class PcmStream
{ {
public: public:
/// Callback interface for users of PcmStream
/**
* Users of PcmStream should implement this to get the data
*/
class Listener
{
public:
virtual void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) = 0;
virtual void onStateChanged(const PcmStream* pcmStream, ReaderState state) = 0;
virtual void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) = 0;
virtual void onChunkEncoded(const PcmStream* pcmStream, std::shared_ptr<msg::PcmChunk> chunk, double duration) = 0;
virtual void onResync(const PcmStream* pcmStream, double ms) = 0;
};
using ResultHandler = std::function<void(const snapcast::ErrorCode& ec)>; using ResultHandler = std::function<void(const snapcast::ErrorCode& ec)>;
/// ctor. Encoded PCM data is passed to the PcmListener /// ctor. Encoded PCM data is passed to the PcmStream::Listener
PcmStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
virtual ~PcmStream(); virtual ~PcmStream();
virtual void start(); virtual void start();
@ -155,7 +156,7 @@ public:
virtual ReaderState getState() const; virtual ReaderState getState() const;
virtual json toJson() const; virtual json toJson() const;
void addListener(PcmListener* pcmListener); void addListener(PcmStream::Listener* pcmListener);
protected: protected:
std::atomic<bool> active_; std::atomic<bool> active_;
@ -181,7 +182,7 @@ protected:
net::strand<net::any_io_executor> strand_; net::strand<net::any_io_executor> strand_;
std::chrono::time_point<std::chrono::steady_clock> tvEncodedChunk_; std::chrono::time_point<std::chrono::steady_clock> tvEncodedChunk_;
std::vector<PcmListener*> pcmListeners_; std::vector<PcmStream::Listener*> pcmListeners_;
StreamUri uri_; StreamUri uri_;
SampleFormat sampleFormat_; SampleFormat sampleFormat_;
size_t chunk_ms_; size_t chunk_ms_;

View file

@ -16,16 +16,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#include <cerrno> // prototype/interface header file
#include <fcntl.h> #include "pipe_stream.hpp"
#include <memory>
#include <sys/stat.h>
#include <unistd.h>
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/str_compat.hpp" #include "common/str_compat.hpp"
#include "pipe_stream.hpp"
// standard headers
#include <cerrno>
#include <memory>
using namespace std; using namespace std;
@ -36,7 +37,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "PipeStream"; static constexpr auto LOG_TAG = "PipeStream";
PipeStream::PipeStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) PipeStream::PipeStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: PosixStream(pcmListener, ioc, server_settings, uri) : PosixStream(pcmListener, ioc, server_settings, uri)
{ {
umask(0); umask(0);

View file

@ -19,6 +19,7 @@
#ifndef PIPE_STREAM_HPP #ifndef PIPE_STREAM_HPP
#define PIPE_STREAM_HPP #define PIPE_STREAM_HPP
// local headers
#include "posix_stream.hpp" #include "posix_stream.hpp"
namespace streamreader namespace streamreader
@ -31,13 +32,13 @@ using boost::asio::posix::stream_descriptor;
/** /**
* Reads PCM from a named pipe and passes the data to an encoder. * Reads PCM from a named pipe and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class PipeStream : public PosixStream class PipeStream : public PosixStream
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
PipeStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); PipeStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
protected: protected:
void do_connect() override; void do_connect() override;

View file

@ -16,16 +16,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#include <cerrno> // prototype/interface header file
#include <fcntl.h> #include "posix_stream.hpp"
#include <memory>
#include <sys/stat.h>
#include <unistd.h>
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/str_compat.hpp" #include "common/str_compat.hpp"
#include "posix_stream.hpp"
// standard headers
#include <cerrno>
#include <memory>
using namespace std; using namespace std;
@ -37,7 +38,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "PosixStream"; static constexpr auto LOG_TAG = "PosixStream";
static constexpr auto kResyncTolerance = 50ms; static constexpr auto kResyncTolerance = 50ms;
PosixStream::PosixStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) PosixStream::PosixStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: AsioStream<stream_descriptor>(pcmListener, ioc, server_settings, uri) : AsioStream<stream_descriptor>(pcmListener, ioc, server_settings, uri)
{ {
if (uri_.query.find("dryout_ms") != uri_.query.end()) if (uri_.query.find("dryout_ms") != uri_.query.end())

View file

@ -19,6 +19,7 @@
#ifndef POSIX_STREAM_HPP #ifndef POSIX_STREAM_HPP
#define POSIX_STREAM_HPP #define POSIX_STREAM_HPP
// local headers
#include "asio_stream.hpp" #include "asio_stream.hpp"
namespace streamreader namespace streamreader
@ -31,13 +32,13 @@ using boost::asio::posix::stream_descriptor;
/** /**
* Reads PCM from a file descriptor and passes the data to an encoder. * Reads PCM from a file descriptor and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class PosixStream : public AsioStream<stream_descriptor> class PosixStream : public AsioStream<stream_descriptor>
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
PosixStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); PosixStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
protected: protected:
void connect() override; void connect() override;

View file

@ -17,14 +17,17 @@
***/ ***/
// prototype/interface header file
#include "process_stream.hpp" #include "process_stream.hpp"
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/utils/string_utils.hpp" #include "common/utils/string_utils.hpp"
// standard headers
#include <climits> #include <climits>
#include <fcntl.h>
#include <sys/stat.h>
using namespace std; using namespace std;
@ -35,7 +38,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "ProcessStream"; static constexpr auto LOG_TAG = "ProcessStream";
ProcessStream::ProcessStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) ProcessStream::ProcessStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: PosixStream(pcmListener, ioc, server_settings, uri) : PosixStream(pcmListener, ioc, server_settings, uri)
{ {
params_ = uri_.getQuery("params"); params_ = uri_.getQuery("params");

View file

@ -19,13 +19,15 @@
#ifndef PROCESS_STREAM_HPP #ifndef PROCESS_STREAM_HPP
#define PROCESS_STREAM_HPP #define PROCESS_STREAM_HPP
// local headers
#include "posix_stream.hpp"
#include "watchdog.hpp"
// standard headers
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "posix_stream.hpp"
#include "watchdog.hpp"
namespace bp = boost::process; namespace bp = boost::process;
@ -37,13 +39,13 @@ namespace streamreader
/** /**
* Starts an external process, reads PCM data from stdout, and passes the data to an encoder. * Starts an external process, reads PCM data from stdout, and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class ProcessStream : public PosixStream, public WatchdogListener class ProcessStream : public PosixStream, public WatchdogListener
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
ProcessStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); ProcessStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
~ProcessStream() override = default; ~ProcessStream() override = default;
protected: protected:

View file

@ -16,16 +16,20 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#include <fcntl.h> // prototype/interface header file
#include <memory> #include "stream_control.hpp"
#include <sys/stat.h>
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/str_compat.hpp" #include "common/str_compat.hpp"
#include "common/utils/string_utils.hpp" #include "common/utils/string_utils.hpp"
#include "encoder/encoder_factory.hpp" #include "encoder/encoder_factory.hpp"
#include "stream_control.hpp"
// 3rd party headers
// standard headers
#include <memory>
using namespace std; using namespace std;

View file

@ -19,6 +19,11 @@
#ifndef STREAM_CONTROL_HPP #ifndef STREAM_CONTROL_HPP
#define STREAM_CONTROL_HPP #define STREAM_CONTROL_HPP
// local headers
#include "jsonrpcpp.hpp"
#include "server_settings.hpp"
// 3rd party headers
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" #pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunused-result" #pragma GCC diagnostic ignored "-Wunused-result"
@ -28,13 +33,11 @@
#pragma GCC diagnostic ignored "-Wc++11-narrowing" #pragma GCC diagnostic ignored "-Wc++11-narrowing"
#include <boost/process.hpp> #include <boost/process.hpp>
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#include <map>
#include <string>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "jsonrpcpp.hpp" // standard headers
#include "server_settings.hpp" #include <map>
#include <string>
namespace bp = boost::process; namespace bp = boost::process;

View file

@ -16,7 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
// prototype/interface header file
#include "stream_manager.hpp" #include "stream_manager.hpp"
// local headers
#include "airplay_stream.hpp" #include "airplay_stream.hpp"
#ifdef HAS_ALSA #ifdef HAS_ALSA
#include "alsa_stream.hpp" #include "alsa_stream.hpp"
@ -32,13 +35,17 @@
#include "process_stream.hpp" #include "process_stream.hpp"
#include "tcp_stream.hpp" #include "tcp_stream.hpp"
// 3rd party headers
// standard headers
using namespace std; using namespace std;
namespace streamreader namespace streamreader
{ {
StreamManager::StreamManager(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& settings) StreamManager::StreamManager(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& settings)
// const std::string& defaultSampleFormat, const std::string& defaultCodec, size_t defaultChunkBufferMs) // const std::string& defaultSampleFormat, const std::string& defaultCodec, size_t defaultChunkBufferMs)
: pcmListener_(pcmListener), settings_(settings), ioc_(ioc) : pcmListener_(pcmListener), settings_(settings), ioc_(ioc)
{ {

View file

@ -19,10 +19,14 @@
#ifndef STREAM_MANAGER_HPP #ifndef STREAM_MANAGER_HPP
#define STREAM_MANAGER_HPP #define STREAM_MANAGER_HPP
// local headers
#include "pcm_stream.hpp" #include "pcm_stream.hpp"
#include "server_settings.hpp" #include "server_settings.hpp"
// 3rd party headers
#include <boost/asio/io_context.hpp> #include <boost/asio/io_context.hpp>
// standard headers
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -35,7 +39,7 @@ using PcmStreamPtr = std::shared_ptr<PcmStream>;
class StreamManager class StreamManager
{ {
public: public:
StreamManager(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& settings); StreamManager(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& settings);
PcmStreamPtr addStream(const std::string& uri); PcmStreamPtr addStream(const std::string& uri);
PcmStreamPtr addStream(StreamUri& streamUri); PcmStreamPtr addStream(StreamUri& streamUri);
@ -49,7 +53,7 @@ public:
private: private:
std::vector<PcmStreamPtr> streams_; std::vector<PcmStreamPtr> streams_;
PcmListener* pcmListener_; PcmStream::Listener* pcmListener_;
ServerSettings settings_; ServerSettings settings_;
boost::asio::io_context& ioc_; boost::asio::io_context& ioc_;
}; };

View file

@ -16,18 +16,21 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#include <cerrno> // prototype/interface header file
#include <fcntl.h> #include "tcp_stream.hpp"
#include <memory>
#include <sys/stat.h>
#include <unistd.h>
// local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/str_compat.hpp" #include "common/str_compat.hpp"
#include "common/utils/string_utils.hpp" #include "common/utils/string_utils.hpp"
#include "encoder/encoder_factory.hpp" #include "encoder/encoder_factory.hpp"
#include "tcp_stream.hpp"
// 3rd party headers
// standard headers
#include <cerrno>
#include <memory>
using namespace std; using namespace std;
@ -37,7 +40,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "TcpStream"; static constexpr auto LOG_TAG = "TcpStream";
TcpStream::TcpStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) TcpStream::TcpStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri)
: AsioStream<tcp::socket>(pcmListener, ioc, server_settings, uri), reconnect_timer_(ioc) : AsioStream<tcp::socket>(pcmListener, ioc, server_settings, uri), reconnect_timer_(ioc)
{ {
host_ = uri_.host; host_ = uri_.host;

View file

@ -19,6 +19,7 @@
#ifndef TCP_STREAM_HPP #ifndef TCP_STREAM_HPP
#define TCP_STREAM_HPP #define TCP_STREAM_HPP
// local headers
#include "asio_stream.hpp" #include "asio_stream.hpp"
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
@ -30,13 +31,13 @@ namespace streamreader
/** /**
* Reads PCM from a named pipe and passes the data to an encoder. * Reads PCM from a named pipe and passes the data to an encoder.
* Implements EncoderListener to get the encoded data. * Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener * Data is passed to the PcmStream::Listener
*/ */
class TcpStream : public AsioStream<tcp::socket> class TcpStream : public AsioStream<tcp::socket>
{ {
public: public:
/// ctor. Encoded PCM data is passed to the PipeListener /// ctor. Encoded PCM data is passed to the PipeListener
TcpStream(PcmListener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); TcpStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri);
protected: protected:
void do_connect() override; void do_connect() override;