// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #pragma once #include "AbstractStream.hpp" #include "AudioFormat.hpp" #include #include #include #include namespace audio { class Endpoint { public: struct Traits { bool usesDMA = false; // optional constraints std::optional blockSizeConstraint = std::nullopt; std::optional timeConstraint = std::nullopt; }; Endpoint() = default; void connectStream(AbstractStream &stream); void disconnectStream(); bool isConnected() const noexcept; [[nodiscard]] virtual auto getTraits() const -> Traits = 0; auto isFormatSupported(const AudioFormat &format) -> bool; virtual auto getSupportedFormats() -> std::vector = 0; protected: AbstractStream *_stream = nullptr; }; class Sink : public Endpoint { public: virtual auto getSinkFormat() -> AudioFormat = 0; virtual void onDataSend() = 0; virtual void enableOutput() = 0; virtual void disableOutput() = 0; }; class Source : public Endpoint { public: virtual auto getSourceFormat() -> AudioFormat = 0; virtual void onDataReceive() = 0; virtual void enableInput() = 0; virtual void disableInput() = 0; }; class IOProxy : public Source, public Sink { public: inline bool isSinkConnected() const noexcept { return Sink::isConnected(); } inline bool isSourceConnected() const noexcept { return Source::isConnected(); } inline void connectOutputStream(AbstractStream &stream) { Sink::connectStream(stream); } inline void connectInputStream(AbstractStream &stream) { Source::connectStream(stream); } inline auto isFormatSupportedBySink(const AudioFormat &format) -> bool { return Sink::isFormatSupported(format); } inline auto isFormatSupportedBySource(const AudioFormat &format) -> bool { return Source::isFormatSupported(format); } }; class StreamConnection { public: StreamConnection() = default; StreamConnection(Source *source, Sink *sink, AbstractStream *stream); ~StreamConnection(); void enable(); void disable(); void destroy(); [[nodiscard]] Source *getSource() const noexcept; [[nodiscard]] Sink *getSink() const noexcept; [[nodiscard]] AbstractStream *getStream() const noexcept; [[nodiscard]] bool isEnabled() const noexcept; private: bool enabled = false; Sink *_sink = nullptr; Source *_source = nullptr; AbstractStream *_stream = nullptr; }; }; // namespace audio