diff --git a/MEMLNaut-NISPS.ino b/MEMLNaut-NISPS.ino index 64b3a6a..35195ff 100644 --- a/MEMLNaut-NISPS.ino +++ b/MEMLNaut-NISPS.ino @@ -13,7 +13,7 @@ #include "ChannelStripAudioApp.hpp" //interface -#include "src/memllib/examples/InterfaceRL.hpp" +// #include "src/memllib/examples/InterfaceRL.hpp" #include "src/memllib/hardware/memlnaut/display/XYPadView.hpp" #include "src/memllib/hardware/memlnaut/display/MessageView.hpp" #include "src/memllib/hardware/memlnaut/display/VoiceSpaceSelectView.hpp" @@ -24,7 +24,7 @@ #include "modes/MEMLNautModeChannelStrip.hpp" #include "modes/MEMLNautModeSoundAnalysisMIDI.hpp" -#define INTERFACE_TYPE InterfaceRL +// #define INTERFACE_TYPE InterfaceRL #define MEMLNAUT_MODE_TYPE MEMLNautModeSoundAnalysisMIDI @@ -54,7 +54,7 @@ uint32_t get_rosc_entropy_seed(int bits) { // Global objects -std::shared_ptr APP_SRAM interface; +// std::shared_ptr APP_SRAM interface; std::shared_ptr APP_SRAM midi_interf; @@ -99,32 +99,32 @@ void setup() { MEMLNaut::Initialize(); pinMode(33, OUTPUT); - { - auto temp_interface = std::make_shared(); + // { + // auto temp_interface = std::make_shared(); - // temp_interface->setup(kN_InputParams, PAFSynthAudioApp<>::kN_Params); - // temp_interface->setup(kN_InputParams, ChannelStripAudioApp<>::kN_Params); - temp_interface->setup(currentMode->kN_InputParams, currentMode->getNParams()); + // // temp_interface->setup(kN_InputParams, PAFSynthAudioApp<>::kN_Params); + // // temp_interface->setup(kN_InputParams, ChannelStripAudioApp<>::kN_Params); + // temp_interface->setup(currentMode->kN_InputParams, currentMode->getNParams()); - MEMORY_BARRIER(); - interface = temp_interface; - MEMORY_BARRIER(); - } + // MEMORY_BARRIER(); + // interface = temp_interface; + // MEMORY_BARRIER(); + // } + currentMode->setupInterface(); // Setup interface with memory barrier protection WRITE_VOLATILE(interface_ready, true); // Bind interface after ensuring it's fully initialized - interface->bindInterface(true); + //TODO: control this from the mode + // interface->bindInterface(true); Serial.println("Bound interface to MEMLNaut."); midi_interf = std::make_shared(); - midi_interf->Setup(currentMode->getNMIDICtrlOutputs()); - midi_interf->SetMIDISendChannel(1); Serial.println("MIDI setup complete."); if (midi_interf) { currentMode->setupMIDI(midi_interf); - interface->bindMIDI(midi_interf); + // interface->bindMIDI(midi_interf); } @@ -135,26 +135,10 @@ void setup() { delay(1); } - std::shared_ptr voiceSpaceSelectView; - voiceSpaceSelectView = std::make_shared("Voice Spaces"); - - MEMLNaut::Instance()->disp->InsertViewAfter(interface->rlStatsView, voiceSpaceSelectView); - // voiceSpaceSelectView->setOptions(voiceSpaceList); //set by core 1 on startup - // voiceSpaceSelectView->setOptions(voiceSpaceList_chstrip); //set by core 1 on startup - voiceSpaceSelectView->setOptions(currentMode->getVoiceSpaceList()); //set by core 1 on startup - voiceSpaceSelectView->setNewVoiceCallback( - [](size_t idx) { - // Serial.println(idx); - // audio_app_chstrip->setVoiceSpace(idx); - // audioAppChannelStrip.setVoiceSpace(idx); - // audio_app->setVoiceSpace(idx); - currentMode->setVoiceSpace(idx); - }); currentMode->addViews(); std::shared_ptr helpView = std::make_shared("Help"); - // helpView->post("PAF synth NISPS"); String title = currentMode->getHelpTitle(); helpView->post(title); helpView->post("TA: Down: Clear replay memory"); @@ -181,7 +165,8 @@ void loop() { PERIODIC_RUN_US( PERF_BEGIN(MLSTATS); - currentMode->processAnalysisParams(interface); + // currentMode->processAnalysisParams(interface); + currentMode->processAnalysisParams(); MEMLNaut::Instance()->loop(); PERF_END(MLSTATS); , ML_INFERENCE_PERIOD_US) @@ -219,6 +204,10 @@ void AUDIO_FUNC(audio_block_callback)(float in[][kBufferSize], float out[][kBuff out[0][i] = y.L; out[1][i] = y.R; + // PERIODIC_RUN( + // Serial.printf("x: %f\n", x.L + x.R); + // , 100); + currentMode->analyse(x); } } @@ -236,40 +225,12 @@ void setup1() { } - // Create audio app with memory barrier protection - { - // PAFSynthAudioApp<>* audio_raw = new (audio_app_mem) PAFSynthAudioApp<>(); - // audio_raw->Setup(AudioDriver::GetSampleRate(), interface); - - // // shared_ptr with custom deleter calling only the destructor (control block still allocates) - // auto audio_deleter = [](PAFSynthAudioApp<>* p) { - // if (p) p->~PAFSynthAudioApp<>(); - // }; - // std::shared_ptr> temp_audio_app(audio_raw, audio_deleter); - // ChannelStripAudioApp<>* audio_raw = new (audio_app_mem_chstrip) ChannelStripAudioApp<>(); - // audio_raw->Setup(AudioDriver::GetSampleRate(), interface); - - // // shared_ptr with custom deleter calling only the destructor (control block still allocates) - // auto audio_deleter = [](ChannelStripAudioApp<>* p) { - // if (p) p->~ChannelStripAudioApp<>(); - // }; - // std::shared_ptr> temp_audio_app(audio_raw, audio_deleter); - - // MEMORY_BARRIER(); - // audio_app_chstrip = temp_audio_app; - // MEMORY_BARRIER(); - } - // audioAppChannelStrip.Setup(AudioDriver::GetSampleRate(), interface); - currentMode->Setup(AudioDriver::GetSampleRate(), interface); + currentMode->setupAudio(AudioDriver::GetSampleRate()); AudioDriver::SetBlockCallback(audio_block_callback); - // AudioDriver::SetBlockCallback(currentMode->getAudioCallBack()); + // Start audio driver AudioDriver::Setup(); - // AudioDriver::SetBlockCallback(audio_block_callback); - // voiceSpaceList = audio_app->getVoiceSpaceNames(); - // voiceSpaceList_chstrip = audio_app_chstrip->getVoiceSpaceNames(); - // voiceSpaceList_chstrip = audioAppChannelStrip.getVoiceSpaceNames(); WRITE_VOLATILE(core_1_ready, true); while (!READ_VOLATILE(core_0_ready)) { diff --git a/ThruAudioApp.hpp b/ThruAudioApp.hpp index 72e5755..0e890b2 100644 --- a/ThruAudioApp.hpp +++ b/ThruAudioApp.hpp @@ -54,6 +54,9 @@ public: __attribute__((hot)) stereosample_t __force_inline Process(const stereosample_t x) override { + // float y = x.L + x.R; + // y = filt.play(y); + // return stereosample_t{y, y}; return x; } @@ -61,6 +64,7 @@ public: { AudioAppBase::Setup(sample_rate, interface); maxiSettings::sampleRate = sample_rate; + filt.set(maxiBiquad::filterTypes::HIGHPASS, 20.f, 0.707f, 0); } __attribute__((always_inline)) void ProcessParams(const std::array& params) @@ -71,6 +75,8 @@ public: protected: + maxiBiquad filt; + }; #endif diff --git a/XiasriAnalysis.cpp b/XiasriAnalysis.cpp index c85bf5f..099c06a 100644 --- a/XiasriAnalysis.cpp +++ b/XiasriAnalysis.cpp @@ -13,7 +13,7 @@ XiasriAnalysis::XiasriAnalysis(const float sample_rate) : zc_median_filter_(kZC_MedianFilterSize) { // Initialize filters and detectors - common_hpf_.set(maxiBiquad::filterTypes::HIGHPASS, 30.f, 0.707f, 0); + common_hpf_.set(maxiBiquad::filterTypes::HIGHPASS, 20.f, 0.707f, 0); // Zero crossing zc_lpf_.set(maxiBiquad::filterTypes::LOWPASS, 4000.0f, 0.707f, 0); elapsed_samples_ = 0; @@ -31,6 +31,22 @@ XiasriAnalysis::XiasriAnalysis(const float sample_rate) : } } +void XiasriAnalysis::ReinitFilters() { + // Reinitialize all filters with correct maxiSettings sample rate + common_hpf_.set(maxiBiquad::filterTypes::HIGHPASS, 20.f, 0.707f, 0); + zc_lpf_.set(maxiBiquad::filterTypes::LOWPASS, 4000.0f, 0.707f, 0); + br_lpf1_.set(maxiBiquad::filterTypes::LOWPASS, 1000.0f, 0.707f, 0); + br_hpf2_.set(maxiBiquad::filterTypes::HIGHPASS, 1000.0f, 0.707f, 0); + br_lpf2_.set(maxiBiquad::filterTypes::LOWPASS, 4000.0f, 0.707f, 0); +} + +// Use fast approximation (~10 cycles): +__force_inline float fast_log2(float x) { + static constexpr float INV_MANTISSA_SCALE = 1.0f / 8388608.0f; // 1/(2^23) + union { float f; uint32_t i; } u = {x}; + return (float)(((u.i >> 23) & 0xFF) - 127) + + (float)(u.i & 0x7FFFFF) * INV_MANTISSA_SCALE; // Multiply instead of divide +} inline float logEnvelopeFast(float linearEnv) { // -60 dBFS corresponds to a linear amplitude ratio of 10^(-60/20) = 10^(-3) = 0.001 @@ -53,8 +69,7 @@ inline float logEnvelopeFast(float linearEnv) { // Clamp input to minimum envelope value linearEnv = (linearEnv > MIN_ENV) ? linearEnv : MIN_ENV; - // Precise logarithmic conversion - float log2_val = std::log2f(linearEnv); + float log2_val = fast_log2(linearEnv); // Map to [0,1]: (log2_val - log2_min) / (log2_max - log2_min) float y = (log2_val - LOG2_MIN_ENV) * INV_LOG_RANGE; @@ -66,12 +81,13 @@ inline float logEnvelopeFast(float linearEnv) { return y; } +__attribute__((hot, flatten)) XiasriAnalysis::parameters_t AUDIO_FUNC(XiasriAnalysis::Process)(const float x) { parameters_t params = {}; - + // Pre-filter float pre_filtered = common_hpf_.play(x); - + // Zero crossing detection float zc_y = zc_lpf_.play(pre_filtered); bool positive_zero_crossing = zc_detector_.zx(zc_y); @@ -80,70 +96,60 @@ XiasriAnalysis::parameters_t AUDIO_FUNC(XiasriAnalysis::Process)(const float x) zc_buffer_.push(median_elapsed_samples); elapsed_samples_ = 0; } + // Convert zero crossing value to pitch size_t zc_value = zc_buffer_[zc_buffer_.size() - 1]; - float pitch = 1.0f / (zc_value * one_over_sample_rate_); - // Map [100..800] hz to [0..1] range - float normalized_pitch; - if (pitch <= kPitchMin) { - normalized_pitch = 0.0f; - } else if (pitch >= kPitchMax) { - normalized_pitch = 1.0f; - } else { - normalized_pitch = (pitch - kPitchMin) * kPitchScale; - } + + // OPTIMIZED: Direct division instead of divide-after-multiply + float pitch = sample_rate_ / static_cast(zc_value); + float normalized_pitch = maxiMap::clamp((pitch - kPitchMin) * kPitchScale, 0.0f, 1.0f); + elapsed_samples_++; + // Aperiodicity calculation float zc_copy[kZC_ZCBufferSize]; - // Copy contents of circular buffer to float array for (size_t i = 0; i < kZC_ZCBufferSize; ++i) { zc_copy[i] = static_cast(zc_buffer_[i]); } float mad = meanAbsoluteDeviation(zc_copy, kZC_ZCBufferSize); - // Scale MAD relative to median period + + // OPTIMIZED: Multiply by reciprocal float medianPeriod = static_cast(zc_value); - float relativeMad = mad / (medianPeriod + 1.0f); // +1 to avoid div/0 - - // Typical relative MAD ranges from 0 to 0.3 for musical sounds - static constexpr float ONE_OVER_RELATIVE_MAD_MAX = 1/0.3f; - float normalizedAperiodicity = std::min(1.0f, relativeMad * ONE_OVER_RELATIVE_MAD_MAX); - + float medianPeriodRcpr = 1.0f / (medianPeriod + 1.0f); + float relativeMad = mad * medianPeriodRcpr; + + static constexpr float ONE_OVER_RELATIVE_MAD_MAX = 1.0f / 0.3f; + float normalizedAperiodicity = fminf(1.0f, relativeMad * ONE_OVER_RELATIVE_MAD_MAX); + // Envelope follower float ef_y = ef_follower_.play(pre_filtered); - // Convert to log ef_y = logEnvelopeFast(ef_y); + float ef_d_dy = ef_y - ef_deriv_y_; ef_deriv_y_ = ef_y; - // Half-wave rectify the derivative - if (ef_d_dy < 0) { - ef_d_dy = 0; - } - // Scale to [0..1] range - ef_d_dy = std::min(ef_d_dy * 10.0f, 1.0f); - - + + // OPTIMIZED: Branchless rectify and scale + ef_d_dy = fmaxf(0.0f, fminf(ef_d_dy * 10.0f, 1.0f)); + // Brightness calculation float br_low = br_lpf1_.play(pre_filtered); float br_high = br_hpf2_.play(pre_filtered); br_high = br_lpf2_.play(br_high); - + br_low = br_follower_[0].play(br_low); br_high = br_follower_[1].play(br_high); - // brightness = high_band_energy / (low_band_energy + high_band_energy) - float br_energy = br_low + br_high; - if (br_energy > 0.0f) { - br_high /= br_energy; - } else { - br_high = 0.0f; // Avoid division by zero - } - + + // OPTIMIZED: Branchless with reciprocal + float br_energy = br_low + br_high + 1e-8f; + br_high = fminf(br_high / br_energy, 1.0f); // Compiler may optimize this division + // Fill parameters params.pitch = normalized_pitch; params.aperiodicity = normalizedAperiodicity; params.energy = ef_y; params.attack = ef_d_dy; params.brightness = br_high; - params.energy_crude = std::abs(x); - + params.energy_crude = fabsf(x); // Use fabsf instead of std::abs + return params; } \ No newline at end of file diff --git a/XiasriAnalysis.hpp b/XiasriAnalysis.hpp index 4a41c3a..cd85cf8 100644 --- a/XiasriAnalysis.hpp +++ b/XiasriAnalysis.hpp @@ -26,6 +26,9 @@ public: parameters_t Process(const float x); + // Reinitialize filters after maxiSettings is properly configured + void ReinitFilters(); + protected: const float sample_rate_; const float one_over_sample_rate_; diff --git a/modes/MEMLNautMode.hpp b/modes/MEMLNautMode.hpp index a8346d9..ad8c52a 100644 --- a/modes/MEMLNautMode.hpp +++ b/modes/MEMLNautMode.hpp @@ -11,16 +11,17 @@ template concept MEMLNautMode = requires(T proc) { {proc.getHelpTitle()} -> std::same_as; - {proc.getNParams()} -> std::same_as; - {proc.setVoiceSpace(size_t{})} -> std::same_as; + // {proc.getNParams()} -> std::same_as; + // {proc.setVoiceSpace(size_t{})} -> std::same_as; {proc.setupMIDI(std::shared_ptr{})} -> std::same_as; {proc.addViews()} -> std::same_as; - {proc.Setup(float{}, std::shared_ptr{})} -> std::same_as; + {proc.setupAudio(float{})} -> std::same_as; {proc.loop()} -> std::same_as; - {proc.getVoiceSpaceList()} -> std::same_as>; + // {proc.getVoiceSpaceList()} -> std::same_as>; {proc.process(stereosample_t{})} -> std::same_as; {proc.analyse(stereosample_t{})} -> std::same_as; - {proc.processAnalysisParams(std::shared_ptr{})} -> std::same_as; - {proc.getNMIDICtrlOutputs()} -> std::same_as; + {proc.processAnalysisParams()} -> std::same_as; + // {proc.getNMIDICtrlOutputs()} -> std::same_as; + {proc.setupInterface()} -> std::same_as; requires std::same_as; }; diff --git a/modes/MEMLNautModeChannelStrip.hpp b/modes/MEMLNautModeChannelStrip.hpp index 1678289..e40e613 100644 --- a/modes/MEMLNautModeChannelStrip.hpp +++ b/modes/MEMLNautModeChannelStrip.hpp @@ -2,7 +2,9 @@ #include "../src/memllib/interface/MIDIInOut.hpp" #include "../ChannelStripAudioApp.hpp" +#include "../src/memllib/examples/InterfaceRL.hpp" #include "MEMLNautMode.hpp" +#include "../src/memllib/PicoDefs.hpp" #include #include @@ -11,21 +13,29 @@ public: constexpr static size_t kN_InputParams = 3; // joystick x, y, rotate ChannelStripAudioApp<> audioAppChannelStrip; std::array::nVoiceSpaces> voiceSpaceList; + InterfaceRL interface; + std::shared_ptr interfacePtr; + + void setupInterface() { + interface.setup(kN_InputParams, ChannelStripAudioApp<>::kN_Params); + interface.bindInterface(InterfaceRL::INPUT_MODES::JOYSTICK); + interfacePtr = make_non_owning(interface); +} String getHelpTitle() { return "Channel Strip Mode"; } - size_t getNParams() { - return ChannelStripAudioApp<>::kN_Params; - } + // size_t getNParams() { + // return ChannelStripAudioApp<>::kN_Params; + // } - void setVoiceSpace(size_t i) { - audioAppChannelStrip.setVoiceSpace(i); - } + // void setVoiceSpace(size_t i) { + // audioAppChannelStrip.setVoiceSpace(i); + // } - std::span getVoiceSpaceList() { - return voiceSpaceList; - } + // std::span getVoiceSpaceList() { + // return voiceSpaceList; + // } __force_inline stereosample_t process(stereosample_t x) { return audioAppChannelStrip.Process(x); @@ -35,11 +45,20 @@ public: } void addViews() { + std::shared_ptr voiceSpaceSelectView; + voiceSpaceSelectView = std::make_shared("Voice Spaces"); + + MEMLNaut::Instance()->disp->InsertViewAfter(interface.rlStatsView, voiceSpaceSelectView); + voiceSpaceSelectView->setOptions(voiceSpaceList); //set by core 1 on startup + voiceSpaceSelectView->setNewVoiceCallback( + [this](size_t idx) { + audioAppChannelStrip.setVoiceSpace(idx); + }); }; - void Setup(float sample_rate, std::shared_ptr interface) { - audioAppChannelStrip.Setup(sample_rate, interface); + void setupAudio(float sample_rate) { + audioAppChannelStrip.Setup(sample_rate, interfacePtr); voiceSpaceList = audioAppChannelStrip.getVoiceSpaceNames(); } @@ -50,7 +69,7 @@ public: size_t getNMIDICtrlOutputs() { return 0; } - - inline void processAnalysisParams(std::shared_ptr interface) {} + + inline void processAnalysisParams() {} }; diff --git a/modes/MEMLNautModePAFSynth.hpp b/modes/MEMLNautModePAFSynth.hpp index ad8ed2d..f1db8a1 100644 --- a/modes/MEMLNautModePAFSynth.hpp +++ b/modes/MEMLNautModePAFSynth.hpp @@ -4,6 +4,8 @@ #include "../src/memllib/hardware/memlnaut/display/XYPadView.hpp" #include "../src/memllib/hardware/memlnaut/MEMLNaut.hpp" #include "../PAFSynthAudioApp.hpp" +#include "../src/memllib/examples/InterfaceRL.hpp" +#include "../src/memllib/PicoDefs.hpp" #include "MEMLNautMode.hpp" #include #include @@ -15,27 +17,36 @@ public: inline static PAFSynthAudioApp<> audioAppPAFSynth; std::array::nVoiceSpaces> voiceSpaceList; + InterfaceRL interface; + std::shared_ptr interfacePtr; + + void setupInterface() { + interface.setup(kN_InputParams, PAFSynthAudioApp<>::kN_Params); + interface.bindInterface(InterfaceRL::INPUT_MODES::JOYSTICK); + interfacePtr = make_non_owning(interface); + } + String getHelpTitle() { return "PAF Synth Mode"; } - size_t getNParams() { - return PAFSynthAudioApp<>::kN_Params; - } + // size_t getNParams() { + // return PAFSynthAudioApp<>::kN_Params; + // } - void setVoiceSpace(size_t i) { - audioAppPAFSynth.setVoiceSpace(i); - } + // void setVoiceSpace(size_t i) { + // audioAppPAFSynth.setVoiceSpace(i); + // } - std::span getVoiceSpaceList() { - return voiceSpaceList; - } + // std::span getVoiceSpaceList() { + // return voiceSpaceList; + // } __force_inline stereosample_t process(stereosample_t x) { return audioAppPAFSynth.Process(x); } - void Setup(float sample_rate, std::shared_ptr interface) { - audioAppPAFSynth.Setup(sample_rate, interface); + void setupAudio(float sample_rate) { + audioAppPAFSynth.Setup(sample_rate, interfacePtr); voiceSpaceList = audioAppPAFSynth.getVoiceSpaceNames(); } @@ -47,6 +58,10 @@ public: void setupMIDI(std::shared_ptr new_midi_interf) { midi_interf = new_midi_interf; + midi_interf->Setup(16); + midi_interf->SetMIDISendChannel(1); + interface.bindMIDI(midi_interf); + midi_interf->SetNoteCallback([this](bool noteon, uint8_t note_number, uint8_t vel_value) { if (noteon) { uint8_t midimsg[2] = { note_number, vel_value }; @@ -61,6 +76,17 @@ public: } void addViews() { + std::shared_ptr voiceSpaceSelectView; + voiceSpaceSelectView = std::make_shared("Voice Spaces"); + + MEMLNaut::Instance()->disp->InsertViewAfter(interface.rlStatsView, voiceSpaceSelectView); + voiceSpaceSelectView->setOptions(voiceSpaceList); //set by core 1 on startup + voiceSpaceSelectView->setNewVoiceCallback( + [this](size_t idx) { + audioAppPAFSynth.setVoiceSpace(idx); + }); + + std::shared_ptr noteTrigView = std::make_shared("Play", TFT_SILVER); // Cache MIDI notes being echoed @@ -92,10 +118,10 @@ public: MEMLNaut::Instance()->disp->AddView(noteTrigView); }; - size_t getNMIDICtrlOutputs() { - return 16; - } + // size_t getNMIDICtrlOutputs() { + // return 16; + // } - inline void processAnalysisParams(std::shared_ptr interface) {} + inline void processAnalysisParams() {} }; diff --git a/modes/MEMLNautModeSoundAnalysisMIDI.hpp b/modes/MEMLNautModeSoundAnalysisMIDI.hpp index 9c7f0cb..ea06092 100644 --- a/modes/MEMLNautModeSoundAnalysisMIDI.hpp +++ b/modes/MEMLNautModeSoundAnalysisMIDI.hpp @@ -8,11 +8,16 @@ #include "../XiasriAnalysis.hpp" #include "../src/memllib/utils/sharedMem.hpp" #include "../src/memllib/audio/AudioDriver.hpp" +#include "../src/memllib/examples/InterfaceRL.hpp" +#include "../src/memllib/PicoDefs.hpp" + class MEMLNautModeSoundAnalysisMIDI { public: - constexpr static size_t kN_InputParams = XiasriAnalysis::kN_Params; // joystick x, y, rotate + constexpr static size_t kN_InputParams = XiasriAnalysis::kN_Params + 3; //ML + joystick + InterfaceRL interface; + std::shared_ptr interfacePtr; XiasriAnalysis mlAnalysis{kSampleRate}; SharedBuffer machine_list_buffer; @@ -20,42 +25,41 @@ public: std::array::nVoiceSpaces> voiceSpaceList; std::shared_ptr midi_interf; + void setupInterface() { + interface.setup(kN_InputParams, ThruAudioApp<>::kN_Params); + interface.bindInterface(InterfaceRL::INPUT_MODES::JOYSTICK_AND_MACHINE_LISTENING); + interfacePtr = make_non_owning(interface); + } + String getHelpTitle() { return "Sound Analysis MIDI Mode"; } - size_t getNParams() { - return ThruAudioApp<>::kN_Params; - } - - void setVoiceSpace(size_t i) { - audioAppSoundAnalysisMIDI.setVoiceSpace(i); - } - - std::span getVoiceSpaceList() { - return voiceSpaceList; - } - + __force_inline stereosample_t process(stereosample_t x) { return audioAppSoundAnalysisMIDI.Process(x); } void setupMIDI(std::shared_ptr new_midi_interf) { midi_interf = new_midi_interf; + midi_interf->Setup(8); + midi_interf->SetMIDISendChannel(1); + interface.bindMIDI(midi_interf); } void addViews() { }; - void Setup(float sample_rate, std::shared_ptr interface) { - audioAppSoundAnalysisMIDI.Setup(sample_rate, interface); - voiceSpaceList = audioAppSoundAnalysisMIDI.getVoiceSpaceNames(); + void setupAudio(float sample_rate) { + audioAppSoundAnalysisMIDI.Setup(sample_rate, interfacePtr); + // Reinitialize XiasriAnalysis filters after maxiSettings is properly configured + mlAnalysis.ReinitFilters(); } __force_inline void loop() { audioAppSoundAnalysisMIDI.loop(); } - inline void analyse(stereosample_t x) { + __force_inline void analyse(stereosample_t x) { union { XiasriAnalysis::parameters_t p; float v[XiasriAnalysis::kN_Params]; @@ -65,16 +69,20 @@ public: machine_list_buffer.writeNonBlocking(param_u.v, XiasriAnalysis::kN_Params); } - size_t getNMIDICtrlOutputs() { - return 8; - } + // size_t getNMIDICtrlOutputs() { + // return 8; + // } - inline void processAnalysisParams(std::shared_ptr interface) { + __force_inline void processAnalysisParams() { // Read SharedBuffer std::vector mlist_params(XiasriAnalysis::kN_Params, 0); machine_list_buffer.readNonBlocking(mlist_params); // Send parameters to RL interface - interface->readAnalysisParameters(mlist_params); + interface.readAnalysisParameters(mlist_params); + // PERIODIC_RUN( + // Serial.printf("%f %f %f\n", mlist_params[0], mlist_params[1], mlist_params[2]); + // , 100); + } }; diff --git a/modes/MEMLNautModeXIASRI.hpp b/modes/MEMLNautModeXIASRI.hpp deleted file mode 100644 index 4701fd2..0000000 --- a/modes/MEMLNautModeXIASRI.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "../src/memllib/interface/MIDIInOut.hpp" -#include "../ChannelStripAudioApp.hpp" -#include "MEMLNautMode.hpp" -#include -#include - -class MEMLNautModeXIASRI { -public: - constexpr static size_t kN_InputParams = XiasriAnalysis::kN_Params; // joystick x, y, rotate - - ChannelStripAudioApp<> audioAppXIASRI; - std::array::nVoiceSpaces> voiceSpaceList; - - String getHelpTitle() { - return "XIASRI Mode"; - } - size_t getNParams() { - return ChannelStripAudioApp<>::kN_Params; - } - - void setVoiceSpace(size_t i) { - audioAppXIASRI.setVoiceSpace(i); - } - - std::span getVoiceSpaceList() { - return voiceSpaceList; - } - - __force_inline stereosample_t process(stereosample_t x) { - return audioAppXIASRI.Process(x); - } - - void setupMIDI(std::shared_ptr midi_interf) { - } - - void addViews() { - - }; - - void Setup(float sample_rate, std::shared_ptr interface) { - audioAppXIASRI.Setup(sample_rate, interface); - voiceSpaceList = audioAppXIASRI.getVoiceSpaceNames(); - } - - __force_inline void loop() { - audioAppXIASRI.loop(); - } - - size_t getNMIDICtrlOutputs() { - return 0; - } - - inline void processAnalysisParams(std::shared_ptr interface) {} - - - -};