// nisps/modes/memlcelium.hpp — MEMLCelium dual-voice synth + 2-track ratio // sequencer mode binding. // // 4 abstract input channels → MLP[4, 10, 14, 18, 56] → MEMLCeliumEngine. // The engine handles sequencer ticks internally inside process(); the mode // surface adds set_playing()/update_bpm() helpers for platform glue. #pragma once #include #include #include #include #include "../core/concepts.hpp" #include "../core/perf.hpp" #include "../core/types.hpp" #include "../engines/memlcelium.hpp" #include "../ml/mlp.hpp" #include "base.hpp" #include "generated/memlcelium_schema.hpp" namespace nisps::modes { class MEMLCeliumMode : public ModeBase< MEMLCeliumMode, MEMLCeliumEngine, ml::MLP<4u, 10u, 14u, 18u, 56u>, 4u> { public: using Base = ModeBase, 4u>; using Base::Base; static constexpr std::string_view mode_id() noexcept { return generated::kMemlceliumModeId; } static constexpr const ParamSchema& param_schema() noexcept { return kSchema; } NISPS_FORCE_INLINE void set_playing(bool playing) noexcept { engine_.set_playing(playing); } NISPS_FORCE_INLINE void update_bpm(float bpm) noexcept { engine_.update_bpm(bpm); } private: static inline constexpr ParamSchema kSchema = ParamSchema{ generated::kMemlceliumModeId, generated::kMemlceliumEngineId, std::span(generated::kMemlceliumInputChannels), generated::kMemlceliumMLConfig.input_size, std::span(generated::kMemlceliumHiddenLayers), generated::kMemlceliumMLConfig.output_size, generated::kMemlceliumMLConfig.default_spread, generated::kMemlceliumMLConfig.default_learning_rate, generated::kMemlceliumMLConfig.default_max_iterations, std::span(generated::kMemlceliumParams), std::span(generated::kMemlceliumVoiceSpaces), generated::kMemlceliumUI, }; }; static_assert(Mode, "MEMLCeliumMode must satisfy nisps::Mode"); } // namespace nisps::modes