From 1460a530d86ff19c8a8b456e91253373cca7e887 Mon Sep 17 00:00:00 2001 From: badaix Date: Sun, 16 Feb 2025 21:42:06 +0100 Subject: [PATCH] Add documentation --- client/decoder/flac_decoder.hpp | 22 +++++++++++++--------- client/decoder/null_decoder.hpp | 5 ++++- client/decoder/ogg_decoder.hpp | 22 +++++++++++++--------- client/decoder/opus_decoder.hpp | 8 ++++++-- client/decoder/pcm_decoder.cpp | 16 +++++++++++----- client/decoder/pcm_decoder.hpp | 5 ++++- client/player/wasapi_player.cpp | 1 + client/player/wasapi_player.hpp | 5 ++++- common/snap_exception.hpp | 7 ++++++- server/encoder/encoder.hpp | 4 ++-- server/encoder/encoder_factory.cpp | 6 +++--- server/encoder/encoder_factory.hpp | 7 ++++--- server/encoder/flac_encoder.cpp | 5 +++-- server/encoder/flac_encoder.hpp | 13 +++++++++---- server/encoder/null_encoder.cpp | 2 +- server/encoder/null_encoder.hpp | 8 +++++--- server/encoder/ogg_encoder.cpp | 3 ++- server/encoder/ogg_encoder.hpp | 24 +++++++++++++----------- server/encoder/opus_encoder.cpp | 2 +- server/encoder/opus_encoder.hpp | 9 ++++++--- server/encoder/pcm_encoder.cpp | 2 +- server/encoder/pcm_encoder.hpp | 9 ++++++--- server/streamreader/airplay_stream.hpp | 19 ++++++++----------- server/streamreader/asio_stream.hpp | 15 +++++++++++++-- server/streamreader/control_error.cpp | 1 + 25 files changed, 140 insertions(+), 80 deletions(-) diff --git a/client/decoder/flac_decoder.hpp b/client/decoder/flac_decoder.hpp index 9b87e399..c029ba95 100644 --- a/client/decoder/flac_decoder.hpp +++ b/client/decoder/flac_decoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -32,34 +32,38 @@ namespace decoder { + +/// Cache internal decoder status struct CacheInfo { - CacheInfo() : sampleRate_(0) - { - reset(); - } - + /// Reset current cache info void reset() { isCachedChunk_ = true; cachedBlocks_ = 0; } - bool isCachedChunk_; - size_t cachedBlocks_; - size_t sampleRate_; + bool isCachedChunk_{true}; ///< is the current block cached + size_t cachedBlocks_{0}; ///< number of cached blocks + size_t sampleRate_{0}; ///< sample rate of the block }; +/// Flac decoder class FlacDecoder : public Decoder { public: + /// c'tor FlacDecoder(); + /// d'tor ~FlacDecoder() override; + bool decode(msg::PcmChunk* chunk) override; SampleFormat setHeader(msg::CodecHeader* chunk) override; + /// Flac internal cache info CacheInfo cacheInfo_; + /// Last decoder error std::unique_ptr lastError_; private: diff --git a/client/decoder/null_decoder.hpp b/client/decoder/null_decoder.hpp index e83c30f7..e816ef86 100644 --- a/client/decoder/null_decoder.hpp +++ b/client/decoder/null_decoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2023 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -25,10 +25,13 @@ namespace decoder { +/// Dummy decoder, doing actually nothing class NullDecoder : public Decoder { public: + /// c'tor NullDecoder(); + bool decode(msg::PcmChunk* chunk) override; SampleFormat setHeader(msg::CodecHeader* chunk) override; }; diff --git a/client/decoder/ogg_decoder.hpp b/client/decoder/ogg_decoder.hpp index 9da91aac..bf9750e6 100644 --- a/client/decoder/ogg_decoder.hpp +++ b/client/decoder/ogg_decoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -36,11 +36,15 @@ namespace decoder { +/// Ogg decoder class OggDecoder : public Decoder { public: + /// c'tor OggDecoder(); + /// d'tor ~OggDecoder() override; + bool decode(msg::PcmChunk* chunk) override; SampleFormat setHeader(msg::CodecHeader* chunk) override; @@ -57,15 +61,15 @@ private: return static_cast(value); } - ogg_sync_state oy; /// sync and verify incoming physical bitstream - ogg_stream_state os; /// take physical pages, weld into a logical stream of packets - ogg_page og; /// one Ogg bitstream page. Vorbis packets are inside - ogg_packet op; /// one raw packet of data for decode + ogg_sync_state oy; ///< sync and verify incoming physical bitstream + ogg_stream_state os; ///< take physical pages, weld into a logical stream of packets + ogg_page og; ///< one Ogg bitstream page. Vorbis packets are inside + ogg_packet op; ///< one raw packet of data for decode - vorbis_info vi; /// struct that stores all the static vorbis bitstream settings - vorbis_comment vc; /// struct that stores all the bitstream user comments - vorbis_dsp_state vd; /// central working state for the packet->PCM decoder - vorbis_block vb; /// local working space for packet->PCM decode + vorbis_info vi; ///< struct that stores all the static vorbis bitstream settings + vorbis_comment vc; ///< struct that stores all the bitstream user comments + vorbis_dsp_state vd; ///< central working state for the packet->PCM decoder + vorbis_block vb; ///< local working space for packet->PCM decode SampleFormat sampleFormat_; std::mutex mutex_; diff --git a/client/decoder/opus_decoder.hpp b/client/decoder/opus_decoder.hpp index e23e3512..c0327a8a 100644 --- a/client/decoder/opus_decoder.hpp +++ b/client/decoder/opus_decoder.hpp @@ -1,7 +1,7 @@ /*** This file is part of snapcast Copyright (C) 2015 Hannes Ellinger - Copyright (C) 2016-2024 Johannes Pohl + Copyright (C) 2016-2025 Johannes Pohl 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 @@ -36,11 +36,15 @@ namespace decoder { +/// Opus decoder class OpusDecoder : public Decoder { public: + /// c'tor OpusDecoder(); - ~OpusDecoder(); + /// c'tor + ~OpusDecoder() override; + bool decode(msg::PcmChunk* chunk) override; SampleFormat setHeader(msg::CodecHeader* chunk) override; diff --git a/client/decoder/pcm_decoder.cpp b/client/decoder/pcm_decoder.cpp index e03245a3..4e75ec77 100644 --- a/client/decoder/pcm_decoder.cpp +++ b/client/decoder/pcm_decoder.cpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -32,14 +32,18 @@ static constexpr auto ID_WAVE = 0x45564157; static constexpr auto ID_FMT = 0x20746d66; static constexpr auto ID_DATA = 0x61746164; +/// RIFF wave header +/// See https://en.wikipedia.org/wiki/WAV struct riff_wave_header { - uint32_t riff_id; - uint32_t riff_sz; - uint32_t wave_id; + uint32_t riff_id; ///< "RIFF" + uint32_t riff_sz; ///< file size - 8 + uint32_t wave_id; ///< "WAVE" }; +/// Chunk header +/// See https://en.wikipedia.org/wiki/WAV struct chunk_header { uint32_t id; @@ -47,9 +51,11 @@ struct chunk_header }; +/// Chunk format +/// See https://en.wikipedia.org/wiki/WAV struct chunk_fmt { - uint16_t audio_format; + uint16_t audio_format; ///< uint16_t num_channels; uint32_t sample_rate; uint32_t byte_rate; diff --git a/client/decoder/pcm_decoder.hpp b/client/decoder/pcm_decoder.hpp index b69d6de3..16a365c6 100644 --- a/client/decoder/pcm_decoder.hpp +++ b/client/decoder/pcm_decoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -25,10 +25,13 @@ namespace decoder { +/// PCM decoder class PcmDecoder : public Decoder { public: + /// c'tor PcmDecoder(); + bool decode(msg::PcmChunk* chunk) override; SampleFormat setHeader(msg::CodecHeader* chunk) override; }; diff --git a/client/player/wasapi_player.cpp b/client/player/wasapi_player.cpp index c73ab2cb..1fc27b41 100644 --- a/client/player/wasapi_player.cpp +++ b/client/player/wasapi_player.cpp @@ -47,6 +47,7 @@ namespace player static constexpr auto LOG_TAG = "WASAPI"; +/// COMMemDeleter helper template struct COMMemDeleter { diff --git a/client/player/wasapi_player.hpp b/client/player/wasapi_player.hpp index cd9f74c3..d7ecb089 100644 --- a/client/player/wasapi_player.hpp +++ b/client/player/wasapi_player.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2022 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -33,6 +33,7 @@ namespace player { +/// Implementation of IAudioSessionEvents class AudioSessionEventListener : public IAudioSessionEvents { LONG _cRef; @@ -108,6 +109,7 @@ public: }; +/// Implementation of IAudioEndpointVolumeCallback class AudioEndpointVolumeCallback : public IAudioEndpointVolumeCallback { LONG _cRef; @@ -178,6 +180,7 @@ public: static constexpr auto WASAPI = "wasapi"; +/// WASAPI player class WASAPIPlayer : public Player { public: diff --git a/common/snap_exception.hpp b/common/snap_exception.hpp index d0bdae03..7dd915a8 100644 --- a/common/snap_exception.hpp +++ b/common/snap_exception.hpp @@ -22,28 +22,33 @@ #include #include -// text_exception uses a dynamically-allocated internal c-string for what(): +/// Snapcast specific exceptions class SnapException : public std::exception { std::string text_; int error_code_; public: + /// c'tor explicit SnapException(const char* text, int error_code = 0) : text_(text), error_code_(error_code) { } + /// c'tor explicit SnapException(const std::string& text, int error_code = 0) : SnapException(text.c_str(), error_code) { } + /// d'tor ~SnapException() override = default; + /// @return error code int code() const noexcept { return error_code_; } + /// @return the exception text const char* what() const noexcept override { return text_.c_str(); diff --git a/server/encoder/encoder.hpp b/server/encoder/encoder.hpp index ad9e0b49..ec78ff45 100644 --- a/server/encoder/encoder.hpp +++ b/server/encoder/encoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -45,7 +45,7 @@ public: /// c'tor /// Codec options (E.g. compression level) are passed as string and are codec dependend - Encoder(const std::string& codecOptions = "") : headerChunk_(nullptr), codecOptions_(codecOptions) + explicit Encoder(std::string codecOptions = "") : headerChunk_(nullptr), codecOptions_(std::move(codecOptions)) { } diff --git a/server/encoder/encoder_factory.cpp b/server/encoder/encoder_factory.cpp index cdcbd156..099bd1e1 100644 --- a/server/encoder/encoder_factory.cpp +++ b/server/encoder/encoder_factory.cpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -40,9 +40,9 @@ using namespace std; namespace encoder { -std::unique_ptr EncoderFactory::createEncoder(const std::string& codecSettings) const +std::unique_ptr EncoderFactory::createEncoder(const std::string& codec_settings) const { - std::string codec(codecSettings); + std::string codec(codec_settings); std::string codecOptions; if (codec.find(':') != std::string::npos) { diff --git a/server/encoder/encoder_factory.hpp b/server/encoder/encoder_factory.hpp index f4f6e056..b1476ca6 100644 --- a/server/encoder/encoder_factory.hpp +++ b/server/encoder/encoder_factory.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -29,11 +29,12 @@ namespace encoder { +/// Factory to create an encoder from an URI class EncoderFactory { public: - // EncoderFactory(const std::string& codecSettings); - std::unique_ptr createEncoder(const std::string& codecSettings) const; + /// @return Encoder from @p codec_settings + std::unique_ptr createEncoder(const std::string& codec_settings) const; }; } // namespace encoder diff --git a/server/encoder/flac_encoder.cpp b/server/encoder/flac_encoder.cpp index 5284de1d..50b22204 100644 --- a/server/encoder/flac_encoder.cpp +++ b/server/encoder/flac_encoder.cpp @@ -40,7 +40,8 @@ namespace encoder static constexpr auto LOG_TAG = "FlacEnc"; -FlacEncoder::FlacEncoder(const std::string& codecOptions) : Encoder(codecOptions), encoder_(nullptr), pcmBufferSize_(0), encodedSamples_(0), flacChunk_(nullptr) +FlacEncoder::FlacEncoder(std::string codecOptions) + : Encoder(std::move(codecOptions)), encoder_(nullptr), pcmBufferSize_(0), encodedSamples_(0), flacChunk_(nullptr) { headerChunk_ = std::make_shared("flac"); pcmBuffer_ = static_cast(malloc(pcmBufferSize_ * sizeof(FLAC__int32))); @@ -230,7 +231,7 @@ void FlacEncoder::initEncoder() throw SnapException("out of memory or tag error"); metadata_[1]->length = 1234; // set the padding length - ok = FLAC__stream_encoder_set_metadata(encoder_, metadata_, 2); + ok = FLAC__stream_encoder_set_metadata(encoder_, metadata_.data(), 2); if (ok == 0) throw SnapException("error setting meta data"); diff --git a/server/encoder/flac_encoder.hpp b/server/encoder/flac_encoder.hpp index 66d06e3e..a0cd6036 100644 --- a/server/encoder/flac_encoder.hpp +++ b/server/encoder/flac_encoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -32,24 +32,29 @@ namespace encoder { +/// Flac encoder class FlacEncoder : public Encoder { public: - explicit FlacEncoder(const std::string& codecOptions = ""); + /// c'tor + explicit FlacEncoder(std::string codecOptions); + /// d'tor ~FlacEncoder() override; + void encode(const msg::PcmChunk& chunk) override; std::string getAvailableOptions() const override; std::string getDefaultOptions() const override; std::string name() const override; + /// FLAC write callback FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder* encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame); -protected: +private: void initEncoder() override; FLAC__StreamEncoder* encoder_; - FLAC__StreamMetadata* metadata_[2]; + std::array metadata_; FLAC__int32* pcmBuffer_; int pcmBufferSize_; diff --git a/server/encoder/null_encoder.cpp b/server/encoder/null_encoder.cpp index 1bac913e..f10a5da1 100644 --- a/server/encoder/null_encoder.cpp +++ b/server/encoder/null_encoder.cpp @@ -31,7 +31,7 @@ namespace encoder static constexpr auto LOG_TAG = "NullEnc"; -NullEncoder::NullEncoder(const std::string& codecOptions) : Encoder(codecOptions) +NullEncoder::NullEncoder(std::string codecOptions) : Encoder(std::move(codecOptions)) { headerChunk_ = std::make_shared("null"); } diff --git a/server/encoder/null_encoder.hpp b/server/encoder/null_encoder.hpp index b55204e7..c9ccc08d 100644 --- a/server/encoder/null_encoder.hpp +++ b/server/encoder/null_encoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -37,11 +37,13 @@ namespace encoder class NullEncoder : public Encoder { public: - NullEncoder(const std::string& codecOptions = ""); + /// c'tor + explicit NullEncoder(std::string codecOptions); + void encode(const msg::PcmChunk& chunk) override; std::string name() const override; -protected: +private: void initEncoder() override; }; diff --git a/server/encoder/ogg_encoder.cpp b/server/encoder/ogg_encoder.cpp index 258f4ca3..6f59672b 100644 --- a/server/encoder/ogg_encoder.cpp +++ b/server/encoder/ogg_encoder.cpp @@ -38,7 +38,8 @@ namespace encoder static constexpr auto LOG_TAG = "OggEnc"; -OggEncoder::OggEncoder(const std::string& codecOptions) : Encoder(codecOptions), lastGranulepos_(0) + +OggEncoder::OggEncoder(std::string codecOptions) : Encoder(std::move(codecOptions)), lastGranulepos_(0) { } diff --git a/server/encoder/ogg_encoder.hpp b/server/encoder/ogg_encoder.hpp index c1fe6b3b..73b8d534 100644 --- a/server/encoder/ogg_encoder.hpp +++ b/server/encoder/ogg_encoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -29,10 +29,13 @@ namespace encoder { +/// Ogg encoder class OggEncoder : public Encoder { public: - OggEncoder(const std::string& codecOptions = ""); + /// c'tor + explicit OggEncoder(std::string codecOptions); + /// d'tor ~OggEncoder() override; void encode(const msg::PcmChunk& chunk) override; @@ -40,19 +43,18 @@ public: std::string getDefaultOptions() const override; std::string name() const override; -protected: +private: void initEncoder() override; -private: - ogg_stream_state os_; /// take physical pages, weld into a logical stream of packets - ogg_page og_; /// one Ogg bitstream page. Vorbis packets are inside - ogg_packet op_; /// one raw packet of data for decode + ogg_stream_state os_; ///< take physical pages, weld into a logical stream of packets + ogg_page og_; ///< one Ogg bitstream page. Vorbis packets are inside + ogg_packet op_; ///< one raw packet of data for decode - vorbis_info vi_; /// struct that stores all the static vorbis bitstream settings - vorbis_comment vc_; /// struct that stores all the user comments + vorbis_info vi_; ///< struct that stores all the static vorbis bitstream settings + vorbis_comment vc_; ///< struct that stores all the user comments - vorbis_dsp_state vd_; /// central working state for the packet->PCM decoder - vorbis_block vb_; /// local working space for packet->PCM decode + vorbis_dsp_state vd_; ///< central working state for the packet->PCM decoder + vorbis_block vb_; ///< local working space for packet->PCM decode ogg_int64_t lastGranulepos_; }; diff --git a/server/encoder/opus_encoder.cpp b/server/encoder/opus_encoder.cpp index 02741913..d40628da 100644 --- a/server/encoder/opus_encoder.cpp +++ b/server/encoder/opus_encoder.cpp @@ -50,7 +50,7 @@ void assign(void* pointer, T val) } // namespace -OpusEncoder::OpusEncoder(const std::string& codecOptions) : Encoder(codecOptions), enc_(nullptr), remainder_max_size_(0) +OpusEncoder::OpusEncoder(std::string codecOptions) : Encoder(std::move(codecOptions)), enc_(nullptr), remainder_max_size_(0) { headerChunk_ = make_unique("opus"); } diff --git a/server/encoder/opus_encoder.hpp b/server/encoder/opus_encoder.hpp index 254321dd..ff0bc7a0 100644 --- a/server/encoder/opus_encoder.hpp +++ b/server/encoder/opus_encoder.hpp @@ -1,7 +1,7 @@ /*** This file is part of snapcast Copyright (C) 2015 Hannes Ellinger - Copyright (C) 2016-2024 Johannes Pohl + Copyright (C) 2016-2025 Johannes Pohl 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 @@ -34,10 +34,13 @@ namespace encoder { +/// Opuse encoder class OpusEncoder : public Encoder { public: - OpusEncoder(const std::string& codecOptions = ""); + /// c'tor + explicit OpusEncoder(std::string codecOptions); + /// d'tor ~OpusEncoder() override; void encode(const msg::PcmChunk& chunk) override; @@ -45,7 +48,7 @@ public: std::string getDefaultOptions() const override; std::string name() const override; -protected: +private: void encode(const SampleFormat& format, const char* data, size_t size); void initEncoder() override; ::OpusEncoder* enc_; diff --git a/server/encoder/pcm_encoder.cpp b/server/encoder/pcm_encoder.cpp index 233e74fb..229b8849 100644 --- a/server/encoder/pcm_encoder.cpp +++ b/server/encoder/pcm_encoder.cpp @@ -48,7 +48,7 @@ void assign(void* pointer, T val) } // namespace -PcmEncoder::PcmEncoder(const std::string& codecOptions) : Encoder(codecOptions) +PcmEncoder::PcmEncoder(std::string codecOptions) : Encoder(std::move(codecOptions)) { headerChunk_ = std::make_shared("pcm"); } diff --git a/server/encoder/pcm_encoder.hpp b/server/encoder/pcm_encoder.hpp index 0aa975f5..18f91864 100644 --- a/server/encoder/pcm_encoder.hpp +++ b/server/encoder/pcm_encoder.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2020 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -25,14 +25,17 @@ namespace encoder { +/// PCM encoder class PcmEncoder : public Encoder { public: - PcmEncoder(const std::string& codecOptions = ""); + /// c'tor + explicit PcmEncoder(std::string codecOptions); + void encode(const msg::PcmChunk& chunk) override; std::string name() const override; -protected: +private: void initEncoder() override; }; diff --git a/server/streamreader/airplay_stream.hpp b/server/streamreader/airplay_stream.hpp index 939a1f6b..84566a89 100644 --- a/server/streamreader/airplay_stream.hpp +++ b/server/streamreader/airplay_stream.hpp @@ -1,6 +1,6 @@ /*** This file is part of snapcast - Copyright (C) 2014-2024 Johannes Pohl + Copyright (C) 2014-2025 Johannes Pohl 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 @@ -32,18 +32,14 @@ namespace streamreader { -class TageEntry +/// Tage entry?? +struct TageEntry { -public: - TageEntry() : isBase64(false), length(0) - { - } - std::string code; std::string type; std::string data; - bool isBase64; - int length; + bool isBase64{false}; + int length{0}; }; /// Starts shairport-sync and reads PCM data from stdout @@ -58,11 +54,12 @@ public: class AirplayStream : public ProcessStream { public: - /// ctor. Encoded PCM data is passed to the PipeListener + /// c'tor. Encoded PCM data is passed to the PipeListener AirplayStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); + /// d'tor ~AirplayStream() override; -protected: +private: #ifdef HAS_EXPAT XML_Parser parser_; std::unique_ptr entry_; diff --git a/server/streamreader/asio_stream.hpp b/server/streamreader/asio_stream.hpp index 72bd800b..27970a73 100644 --- a/server/streamreader/asio_stream.hpp +++ b/server/streamreader/asio_stream.hpp @@ -37,21 +37,26 @@ namespace streamreader using namespace std::chrono_literals; +/// Boost asio based stream class interface template class AsioStream : public PcmStream { public: - /// ctor. Encoded PCM data is passed to the PipeListener + /// c'tor. Encoded PCM data is passed to the PipeListener AsioStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); void start() override; void stop() override; protected: + /// connect to the stream virtual void connect() = 0; + /// disconnect from the stream virtual void disconnect(); + /// resets first chunk timer and starts reader loop virtual void on_connect(); + /// read from asio stream virtual void do_read(); /// Start a timer that will change the stream state to idle after \p duration void check_state(const std::chrono::steady_clock::duration& duration); @@ -62,12 +67,18 @@ protected: /// Cache last exception to avoid repeated error logging std::string lastException_; - timeval tv_chunk_; + /// Marker: next chunk is the first chunk bool first_; + + /// next read = current chunk start + chunk duration std::chrono::time_point nextTick_; + /// chunk read buffer uint32_t buffer_ms_; + /// read timer boost::asio::steady_timer read_timer_; + /// state timer: set stream to idle/playing on timeout boost::asio::steady_timer state_timer_; + /// the stream std::unique_ptr stream_; /// duration of the current silence period diff --git a/server/streamreader/control_error.cpp b/server/streamreader/control_error.cpp index a9784540..feeec99b 100644 --- a/server/streamreader/control_error.cpp +++ b/server/streamreader/control_error.cpp @@ -26,6 +26,7 @@ namespace snapcast::error::control namespace detail { +/// control error category struct category : public std::error_category { public: