/* * Copyright 2023 jacqueline * * SPDX-License-Identifier: GPL-3.0-only */ #pragma once #include #include #include #include #include #include "audio/audio_sink.hpp" #include "tinyfsm.hpp" #include "database/track.hpp" #include "drivers/nvs.hpp" #include "types.hpp" namespace audio { /* * Struct encapsulating information about the decoder's current track. */ struct TrackInfo { /* * Audio tags extracted from the file. May be absent for files without any * parseable tags. */ std::shared_ptr tags; /* * URI that the current track was retrieved from. This is currently always a * file path on the SD card. */ std::string uri; /* * The length of this track in seconds. This is either retrieved from the * track's tags, or sometimes computed. It may therefore sometimes be * inaccurate or missing. */ std::optional duration; /* The offset in seconds that this file's decoding started from. */ std::optional start_offset; /* The approximate bitrate of this track in its original encoded form. */ std::optional bitrate_kbps; /* The encoded format of the this track. */ codecs::StreamType encoding; IAudioOutput::Format format; }; /* * Event emitted by the audio FSM when the state of the audio pipeline has * changed. This is usually once per second while a track is playing, plus one * event each when a track starts or finishes. */ struct PlaybackUpdate : tinyfsm::Event { /* * The track that is currently being decoded by the audio pipeline. May be * absent if there is no current track. */ std::shared_ptr current_track; /* * How long the current track has been playing for, in seconds. Will always * be present if current_track is present. */ std::optional track_position; /* Whether or not the current track is currently being output to a sink. */ bool paused; }; /* * Sets a new track to be decoded by the audio pipeline, replacing any * currently playing track. */ struct SetTrack : tinyfsm::Event { std::variant new_track; std::optional seek_to_second; }; struct PlaySineWave : tinyfsm::Event { uint32_t frequency; }; struct TogglePlayPause : tinyfsm::Event { std::optional set_to; }; struct QueueUpdate : tinyfsm::Event { bool current_changed; enum Reason { kExplicitUpdate, kRepeatingLastTrack, kTrackFinished, kDeserialised, kBulkLoadingUpdate, }; Reason reason; std::optional seek_to_second; }; struct StepUpVolume : tinyfsm::Event {}; struct StepDownVolume : tinyfsm::Event {}; struct SetVolume : tinyfsm::Event { std::optional percent; std::optional db; }; struct SetVolumeBalance : tinyfsm::Event { int left_bias; }; /* Event emitted when the hardware volume for a connected Bluetooth device has changed. */ struct RemoteVolumeChanged : tinyfsm::Event { uint_fast8_t value; // 0..127 }; struct VolumeChanged : tinyfsm::Event { uint_fast8_t percent; int db; }; struct VolumeBalanceChanged : tinyfsm::Event { int left_bias; }; struct VolumeLimitChanged : tinyfsm::Event { int new_limit_db; }; struct SetVolumeLimit : tinyfsm::Event { int limit_db; }; struct OutputModeChanged : tinyfsm::Event { std::optional set_to; }; struct TtsPlaybackChanged : tinyfsm::Event { bool is_playing; }; struct UnmountReady : tinyfsm::Event { bool idle; }; namespace internal { struct DecodingStarted : tinyfsm::Event { std::shared_ptr track; }; struct DecodingFailedToStart : tinyfsm::Event { std::shared_ptr track; }; struct DecodingCancelled : tinyfsm::Event { std::shared_ptr track; }; struct DecodingFinished : tinyfsm::Event { std::shared_ptr track; }; struct StreamStarted : tinyfsm::Event { std::shared_ptr track; IAudioOutput::Format sink_format; uint32_t cue_at_sample; }; struct StreamEnded : tinyfsm::Event { uint32_t cue_at_sample; }; struct StreamHeartbeat : tinyfsm::Event {}; } // namespace internal } // namespace audio