memlnaut-nisps/nisps/modes/channel_strip.hpp
w1n5t0n 429da1d1e4 feat(nisps/modes): all 8 concrete mode bindings (meml-beb)
One header per mode, each ~50-130 LOC built atop ModeBase:

  - `paf_synth.hpp` (4 inputs → 33 outputs, 7 voice spaces, note_on/off)
  - `channel_strip.hpp` (4 → 24, 6 voice spaces)
  - `xiasri.hpp` (4 → 24, 1 'Direct' voice space)
  - `verb_fx.hpp` (4 → 47, 12 voice spaces)
  - `memlcelium.hpp` (4 → 56, dual synth + 2-track sequencer; set_playing/update_bpm)
  - `breakor.hpp` (4 → 56, 8-track ratio sequencer; pumps engine NoteOn/Off/Clock
    events into ControlEvent ring buffer)
  - `elysiamorf.hpp` (4 → 40, 8-track FM-pair MIDI-CC sequencer; pumps CC events)
  - `sound_analysis_midi.hpp` (10 → 8; owns AnalysisEngine for input feature
    extraction PLUS NoOpEngine 'thru' for audio passthrough; ML outputs
    converted to MIDI CC events via on_post_inference; opts out of
    output→engine routing via ModeRoutesOutputsToEngine specialisation)

Every mode satisfies `nisps::Mode` (verified via `static_assert` in each
header). Schema `output_size` is verified against engine `param_count()`
at compile time inside ModeBase.

All hardware-specific glue (MEMLNaut::Instance, pico/util/queue, MIDIInOut,
display widgets, button callbacks) is intentionally absent — that lives in
firmware/glue and playground/src/modes per architecture.md §4.3.
2026-04-29 16:26:49 +03:00

56 lines
2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// nisps/modes/channel_strip.hpp — Channel-strip mode binding.
//
// 4 abstract input channels → MLP[4, 10, 10, 14, 24] → ChannelStripEngine
// (HPF/LPF + 2× peak EQ + low/high shelf + compressor + tanh saturation),
// dispatched through one of 6 console-emulation voice spaces.
#pragma once
#include <cstddef>
#include <span>
#include <string_view>
#include "../core/concepts.hpp"
#include "../core/types.hpp"
#include "../engines/channel_strip.hpp"
#include "../ml/mlp.hpp"
#include "base.hpp"
#include "generated/channel_strip_schema.hpp"
namespace nisps::modes {
class ChannelStripMode : public ModeBase<
ChannelStripMode,
ChannelStripEngine,
ml::MLP<4u, 10u, 10u, 14u, 24u>,
4u> {
public:
using Base = ModeBase<ChannelStripMode, ChannelStripEngine,
ml::MLP<4u, 10u, 10u, 14u, 24u>, 4u>;
using Base::Base;
static constexpr std::string_view mode_id() noexcept {
return generated::kChannelStripModeId;
}
static constexpr const ParamSchema& param_schema() noexcept { return kSchema; }
private:
static inline constexpr ParamSchema kSchema = ParamSchema{
generated::kChannelStripModeId,
generated::kChannelStripEngineId,
std::span<const std::string_view>(generated::kChannelStripInputChannels),
generated::kChannelStripMLConfig.input_size,
std::span<const std::size_t>(generated::kChannelStripHiddenLayers),
generated::kChannelStripMLConfig.output_size,
generated::kChannelStripMLConfig.default_spread,
generated::kChannelStripMLConfig.default_learning_rate,
generated::kChannelStripMLConfig.default_max_iterations,
std::span<const generated::Param>(generated::kChannelStripParams),
std::span<const std::string_view>(generated::kChannelStripVoiceSpaces),
generated::kChannelStripUI,
};
};
static_assert(Mode<ChannelStripMode>, "ChannelStripMode must satisfy nisps::Mode");
} // namespace nisps::modes