/* * Copyright 2023 jacqueline * * SPDX-License-Identifier: GPL-3.0-only */ #pragma once #include #include #include #include #include "audio/stream_cues.hpp" #include "drivers/pcm_buffer.hpp" #include "tinyfsm.hpp" #include "audio/audio_decoder.hpp" #include "audio/audio_events.hpp" #include "audio/audio_sink.hpp" #include "audio/bt_audio_output.hpp" #include "audio/fatfs_stream_factory.hpp" #include "audio/i2s_audio_output.hpp" #include "audio/track_queue.hpp" #include "database/database.hpp" #include "database/tag_parser.hpp" #include "database/track.hpp" #include "drivers/display.hpp" #include "drivers/gpios.hpp" #include "drivers/i2s_dac.hpp" #include "drivers/storage.hpp" #include "system_fsm/service_locator.hpp" #include "system_fsm/system_events.hpp" namespace audio { class AudioState : public tinyfsm::Fsm { public: virtual ~AudioState() {} virtual void entry() {} virtual void exit() {} /* Fallback event handler. Does nothing. */ void react(const tinyfsm::Event& ev) {} void react(const QueueUpdate&); void react(const PlaySineWave&); void react(const SetTrack&); void react(const TogglePlayPause&); void react(const TtsPlaybackChanged&); void react(const internal::DecodingFinished&); void react(const internal::StreamStarted&); void react(const internal::StreamEnded&); virtual void react(const internal::StreamHeartbeat&) {} void react(const StepUpVolume&); void react(const StepDownVolume&); void react(const SetVolume&); void react(const SetVolumeLimit&); void react(const SetVolumeBalance&); void react(const OutputModeChanged&); virtual void react(const system_fsm::BootComplete&) {} virtual void react(const system_fsm::UnmountRequest&) {} virtual void react(const system_fsm::SdStateChanged&) {} virtual void react(const system_fsm::BluetoothEvent&); virtual void react(const system_fsm::HasPhonesChanged&); protected: auto updateOutputMode() -> void; auto emitPlaybackUpdate(bool paused) -> void; auto commitVolume() -> void; auto updateSavedPosition(std::string uri, uint32_t position) -> void; auto incrementPlayCount(std::string uri) -> void; static std::shared_ptr sServices; static std::shared_ptr sStreamFactory; static std::unique_ptr sDecoder; static std::shared_ptr sSampleProcessor; static std::shared_ptr sI2SOutput; static std::shared_ptr sBtOutput; static std::shared_ptr sOutput; static std::unique_ptr sDrainBuffers; static StreamCues sStreamCues; static std::optional sDrainFormat; static bool sIsPaused; static uint8_t sUpdateCounter; static bool sIsTtsPlaying; private: auto updateTrackData(std::string uri, std::function) -> void; }; namespace states { class Uninitialised : public AudioState { public: void react(const system_fsm::BootComplete&) override; void react(const system_fsm::BluetoothEvent&) override{}; using AudioState::react; }; class Standby : public AudioState { public: void entry() override; void react(const system_fsm::UnmountRequest&) override; void react(const system_fsm::SdStateChanged&) override; using AudioState::react; }; class Playback : public AudioState { public: void entry() override; void exit() override; void react(const system_fsm::SdStateChanged&) override; void react(const internal::StreamHeartbeat&) override; using AudioState::react; }; } // namespace states } // namespace audio