/* * Copyright 2023 jacqueline * * SPDX-License-Identifier: GPL-3.0-only */ #include "audio_fsm.hpp" #include #include "audio_decoder.hpp" #include "audio_events.hpp" #include "audio_task.hpp" #include "fatfs_audio_input.hpp" #include "i2s_audio_output.hpp" #include "i2s_dac.hpp" #include "pipeline.hpp" namespace audio { drivers::GpioExpander* AudioState::sGpioExpander; std::shared_ptr AudioState::sDac; std::shared_ptr AudioState::sPots; std::weak_ptr AudioState::sDatabase; std::unique_ptr AudioState::sFileSource; std::unique_ptr AudioState::sI2SOutput; std::vector> AudioState::sPipeline; auto AudioState::Init(drivers::GpioExpander* gpio_expander, std::weak_ptr database) -> bool { sGpioExpander = gpio_expander; auto dac = drivers::I2SDac::create(gpio_expander); if (!dac) { return false; } sDac.reset(dac.value()); sPots.reset(new drivers::DigitalPot(gpio_expander)); sDatabase = database; sFileSource.reset(new FatfsAudioInput()); sI2SOutput.reset(new I2SAudioOutput(sGpioExpander, sDac, sPots)); // Perform initial pipeline configuration. // TODO(jacqueline): Factor this out once we have any kind of dynamic // reconfiguration. AudioDecoder* codec = new AudioDecoder(); sPipeline.emplace_back(codec); Pipeline* pipeline = new Pipeline(sPipeline.front().get()); pipeline->AddInput(sFileSource.get()); task::StartPipeline(pipeline, sI2SOutput.get()); return true; } namespace states { void Uninitialised::react(const system_fsm::BootComplete&) { transit(); } void Standby::react(const PlayFile& ev) { if (sFileSource->OpenFile(ev.filename)) { transit(); } } } // namespace states } // namespace audio FSM_INITIAL_STATE(audio::AudioState, audio::states::Uninitialised)