From 94c877082c284f25fed89ea0073c39f3476d2de5 Mon Sep 17 00:00:00 2001 From: chriskiefer Date: Wed, 15 Oct 2025 10:14:21 +0100 Subject: [PATCH] audio headroom calc --- MEMLNaut-PAF-CARL.ino | 75 ++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/MEMLNaut-PAF-CARL.ino b/MEMLNaut-PAF-CARL.ino index ccb305d..82b1203 100644 --- a/MEMLNaut-PAF-CARL.ino +++ b/MEMLNaut-PAF-CARL.ino @@ -1,6 +1,6 @@ -// #include "src/memllib/interface/InterfaceBase.hpp" + +#include "src/memllib/utils/perf.hpp" #include "src/memllib/interface/MIDIInOut.hpp" -// #include "src/memllib/hardware/memlnaut/display.hpp" #include "src/memllib/audio/AudioAppBase.hpp" #include "src/memllib/audio/AudioDriver.hpp" #include "src/memllib/hardware/memlnaut/MEMLNaut.hpp" @@ -9,6 +9,7 @@ #include "PAFSynthAudioApp.hpp" #include "src/memllib/examples/InterfaceRL.hpp" + #define INTERFACE_TYPE InterfaceRL #define APP_SRAM __not_in_flash("app") @@ -35,8 +36,8 @@ std::shared_ptr APP_SRAM interface; std::shared_ptr APP_SRAM midi_interf; // Statically allocated, properly aligned storage in AUDIO_MEM for objects -alignas(PAFSynthAudioApp) char AUDIO_MEM audio_app_mem[sizeof(PAFSynthAudioApp)]; -std::shared_ptr __scratch_y("audio") audio_app; +alignas(PAFSynthAudioApp<>) char AUDIO_MEM audio_app_mem[sizeof(PAFSynthAudioApp<>)]; +std::shared_ptr > __scratch_y("audio") audio_app; // Inter-core communication volatile bool APP_SRAM core_0_ready = false; @@ -80,21 +81,9 @@ void setup() MEMLNaut::Initialize(); pinMode(33, OUTPUT); - // auto temp_interface = std::make_shared(); - // temp_interface->setup(kN_InputParams, PAFSynthAudioApp::kN_Params); - // MEMORY_BARRIER(); - // RLInterface = temp_interface; - // MEMORY_BARRIER(); - - // // Setup interface with memory barrier protection - // WRITE_VOLATILE(interface_ready, true); - // // Bind interface after ensuring it's fully initialized - // RLInterface->bind_RL_interface(); - // // Serial.println("Bound RL interface to MEMLNaut."); - { auto temp_interface = std::make_shared(); - temp_interface->setup(kN_InputParams, PAFSynthAudioApp::kN_Params); + temp_interface->setup(kN_InputParams, PAFSynthAudioApp<>::kN_Params); MEMORY_BARRIER(); interface = temp_interface; MEMORY_BARRIER(); @@ -119,6 +108,8 @@ void setup() Serial.printf("MIDI Note %d: %d\n", note_number, vel_value); }); Serial.println("MIDI note callback set."); + + interface->bindMIDI(midi_interf); } @@ -144,45 +135,55 @@ void setup() MEMLNaut::Instance()->addSystemInfoView(); Serial.println("Finished initialising core 0."); + } +PERF_DECLARE(MLSTATS); + void loop() { + PERIODIC_RUN_US( + PERF_BEGIN(MLSTATS); + MEMLNaut::Instance()->loop(); + PERF_END(MLSTATS); + , 5000) - MEMLNaut::Instance()->loop(); static int AUDIO_MEM blip_counter = 0; if (blip_counter++ > 100) { blip_counter = 0; Serial.println("."); // Blink LED digitalWrite(33, HIGH); + constexpr float audioHeadroomMul = 1.0/(1000000 * 48.0/kSampleRate); + Serial.printf("ml: %d, aud: %d, q: %f\n",PERF_GET_MEAN(MLSTATS), AUDIOLOOP_MEAN, AUDIOLOOP_MEAN * audioHeadroomMul); } else { // Un-blink LED digitalWrite(33, LOW); } midi_interf->Poll(); - delay(10); // Add a small delay to avoid flooding the serial output + // delay(10); // Add a small delay to avoid flooding the serial output } -// void AUDIO_FUNC(audio_block_callback)(float in[][kBufferSize], float out[][kBufferSize], size_t n_channels, size_t n_frames) -// { -// // digitalWrite(Pins::LED, HIGH); -// for (size_t i = 0; i < n_frames; ++i) { +void AUDIO_FUNC(audio_block_callback)(float in[][kBufferSize], float out[][kBufferSize], size_t n_channels, size_t n_frames) +{ + for (size_t i = 0; i < n_frames; ++i) { -// float y = in[0][i]; + stereosample_t x { + in[0][i], + in[1][i] + }, y; -// // Audio processing -// if (audio_app) { -// y = audio_app->ProcessLean(); -// } + // Audio processing + if (audio_app) { + y = audio_app->Process(x); + } -// out[0][i] = y; -// out[1][i] = y; -// } -// // digitalWrite(Pins::LED, LOW); -// } + out[0][i] = y.L; + out[1][i] = y.R; + } +} void setup1() @@ -200,19 +201,19 @@ void setup1() // Create audio app with memory barrier protection { - PAFSynthAudioApp* audio_raw = new (audio_app_mem) PAFSynthAudioApp(); + 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); + auto audio_deleter = [](PAFSynthAudioApp<>* p) { if (p) p->~PAFSynthAudioApp<>(); }; + std::shared_ptr> temp_audio_app(audio_raw, audio_deleter); MEMORY_BARRIER(); audio_app = temp_audio_app; MEMORY_BARRIER(); } - // AudioDriver::SetBlockCallback(audio_block_callback); + AudioDriver::SetBlockCallback(audio_block_callback); // Start audio driver AudioDriver::Setup(); // AudioDriver::SetBlockCallback(audio_block_callback);