// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once #include #include #include #include "Audio/AudioCommon.hpp" #include "Audio/AudioDeviceFactory.hpp" #include "Audio/AudioPlatform.hpp" #include "Audio/ServiceObserver.hpp" #include "Audio/Profiles/Profile.hpp" namespace audio { class Operation { public: explicit Operation(AudioServiceMessage::Callback callback, const PlaybackType &playbackType = PlaybackType::None) : playbackType(playbackType), serviceCallback(std::move(callback)), observer(serviceCallback) { factory = AudioPlatform::GetDeviceFactory(); factory->setObserver(&observer); } enum class State { Idle, Active, Paused }; enum class Type { Idle, Playback, Recorder, Router }; [[nodiscard]] static inline auto c_str(Type type) -> const char * { switch (type) { case Type::Idle: return "Idle"; case Type::Playback: return "Playback"; case Type::Recorder: return "Recorder"; case Type::Router: return "Router"; } return ""; } virtual ~Operation() = default; static std::unique_ptr Create(Type t, const std::string &filePath = "", const audio::PlaybackType &operations = audio::PlaybackType::None, AudioServiceMessage::Callback callback = nullptr); virtual audio::RetCode Start(audio::Token token) = 0; virtual audio::RetCode Stop() = 0; virtual audio::RetCode Pause() = 0; virtual audio::RetCode Resume() = 0; virtual audio::RetCode SendEvent(std::shared_ptr evt) = 0; virtual audio::RetCode SetOutputVolume(float vol) = 0; virtual audio::RetCode SetInputGain(float gain) = 0; virtual Position GetPosition() = 0; Volume GetOutputVolume() const { return (currentProfile != nullptr) ? currentProfile->GetOutputVolume() : Volume{}; } Gain GetInputGain() const { return currentProfile->GetInputGain(); } State GetState() const { return state; } const std::shared_ptr GetProfile() const { return currentProfile; } audio::PlaybackType GetPlaybackType() const noexcept { return playbackType; } const audio::Token &GetToken() const noexcept { return operationToken; } Type GetOperationType() const noexcept { return opType; } std::string GetFilePath() const noexcept { return filePath; } std::optional GetPriorityProfile() const; /** * @brief Switches operation to priority profile. */ virtual audio::RetCode SwitchToPriorityProfile(); /** * @brief Switches operation to priority profile. * * @param playbackType if it's callringtone and bluetooth a2dp is used then * ignore priorities and change profile to the earpeaker. Not needed otherwise. */ virtual audio::RetCode SwitchToPriorityProfile(audio::PlaybackType playbackType); protected: struct SupportedProfile { SupportedProfile(std::shared_ptr profile, bool isAvailable) : profile(std::move(profile)), isAvailable(isAvailable) {} std::shared_ptr profile; bool isAvailable; }; std::shared_ptr currentProfile; std::shared_ptr audioDevice; std::vector supportedProfiles; std::unique_ptr factory; State state = State::Idle; audio::Token operationToken; Type opType = Type::Idle; std::string filePath; audio::PlaybackType playbackType = audio::PlaybackType::None; AudioServiceMessage::Callback serviceCallback; ServiceObserver observer; std::function audioCallback = nullptr; void SetProfileAvailability(std::vector profiles, bool available); void AddProfile(const Profile::Type &profile, const PlaybackType &playback, bool isAvailable); virtual audio::RetCode SwitchProfile(const Profile::Type type) = 0; std::shared_ptr GetProfile(const Profile::Type type); std::shared_ptr CreateDevice(const Profile &profile); std::shared_ptr createCellularAudioDevice(); }; } // namespace audio