i2c refactor and speed up

This commit is contained in:
chriskiefer 2026-03-05 22:25:21 +00:00
parent 3ddbcdfed9
commit 9906cbd154
10 changed files with 67 additions and 33 deletions

View file

@ -164,6 +164,8 @@ void loop() {
digitalWrite(33, LOW);
},
100000)
currentMode->loopCore0();
}
@ -231,5 +233,5 @@ void loop1() {
PERIODIC_RUN_US(
midi_interf->Poll();
, 10000)
, 1000)
}

View file

@ -12,6 +12,7 @@
#include "../../src/memllib/interface/InterfaceBase.hpp"
#include <span>
#include "../../voicespaces/VoiceSpaces.hpp"
@ -59,7 +60,7 @@ inline bool __not_in_flash_func(ratioSeq)(float phasor, float phaseOffset, float
}
template<size_t NPARAMS=70, size_t NSEQUENCES=10>
template<size_t NPARAMS=56, size_t NSEQUENCES=8>
class BreakOrAudioApp : public AudioAppBase<NPARAMS>
{
public:
@ -68,6 +69,8 @@ public:
queue_t bpmQueue;
queue_t sequencerControlQueue;
queue_t i2cOutQueue;
bool sequencerPlaying = false;
@ -95,6 +98,7 @@ public:
// currentVoiceSpace = voiceSpaces[0].mappingFunction;
queue_init(&bpmQueue, sizeof(float), 1);
queue_init(&sequencerControlQueue, sizeof(int), 1);
queue_init(&i2cOutQueue, sizeof(float) * 8, 1);
};
bool __force_inline euclidean(float phase, const size_t n, const size_t k, const size_t offset, const float pulseWidth)
@ -121,14 +125,19 @@ public:
midiIO->flushQueue();
}
if (sequencingSampleCounter==0) {
barPhasor += barPhasorInc;
if (barPhasor >= 1.f) {
barPhasor -= 1.f;
}
int i2cIdx=0;
for(auto &seq: ratioSeqStates) {
//update phasor
seq.phasor += (seq.phasorInc * seq.phasorMul);
if (seq.phasor >= 1.f) {
seq.phasor -= 1.f;
}
bool trig = ratioSeq<3>(seq.phasor, seq.phaseOffset, seq.ratioSum, seq.ratios, seq.pulseWidth);
bool highAmp = ratioSeq<2>(seq.phasor, seq.phaseOffset, seq.ampRatioSum, seq.ampRatios, 0.5f);
float seqPhasor = barPhasor * seq.phasorMul;
seqPhasor = fmodf(seqPhasor + seq.phaseOffset, 1.f); // Wrap phasor to [0,1]
bool trig = ratioSeq<3>(seqPhasor, seq.phaseOffset, seq.ratioSum, seq.ratios, seq.pulseWidth);
bool highAmp = ratioSeq<2>(seqPhasor, seq.phaseOffset, seq.ampRatioSum, seq.ampRatios, 0.5f);
if (trig && !seq.lastTrig) {
if (trig) {
midiIO->queueNoteOn(seq.midiNote, highAmp ? 127 : 64);
@ -137,8 +146,10 @@ public:
}
}
seq.lastTrig = trig;
i2cValues[i2cIdx++] = trig;
}
midiIO->flushQueue();
queue_try_add(&i2cOutQueue, &i2cValues);
}
sequencingSampleCounter ++;
@ -158,7 +169,7 @@ public:
maxiSettings::sampleRate = sample_rate;
sampleRatef = static_cast<float>(sample_rate);
updateBPM(90.f);
const size_t midiNotes[NSEQUENCES] = {36,37,38,39,40, 42,43,45,47,48};
const size_t midiNotes[NSEQUENCES] = {36,37,38,39,40, 42,43,45/*,47,48*/};
size_t midiNote = 0;
for(auto &seq: ratioSeqStates) {
seq.midiNote = midiNotes[midiNote++];
@ -175,6 +186,8 @@ public:
void ProcessParams(const std::array<float, NPARAMS>& params)
{
// if (sequencerPlaying) {
// }
firstParamsReceived = true;
if (queue_try_remove(&bpmQueue, &bpm)) {
bpm = 30.f + (bpm * 200.f); // Scale BPM from [0,1] to [30,230]
@ -198,6 +211,7 @@ public:
midiIO->queueClockStart();
midiIO->flushQueue();
}
Serial.printf("Sequencer %s\n", sequencerPlaying ? "Playing" : "Stopped");
}
// currentVoiceSpace(params);
size_t paramIdx = 0;
@ -210,7 +224,7 @@ public:
v.ratioSum = sum;
// static float muls[7] = {0.25f, 0.33f, 0.5f, 1.f, 1.5f, 2.f, 3.f};
// v.phasorMul = muls[(int)(params[paramIdx++] * 6.999999f)];
static float muls[4] = {0.5f, 1.f, 2.f, 4.f};
static float muls[4] = {1.f, 2.f, 4.f, 8.f};
v.phasorMul = muls[(int)(params[paramIdx++] * 3.999999f)];
v.phaseOffset = ((int)(params[paramIdx++] * timeSigBeats)) * timeSigBeatsInv;
@ -230,10 +244,10 @@ public:
float beatLengthInSeconds = 60.f / bpm;
float barLengthInSeconds = beatLengthInSeconds * timeSigBeats;
float barLengthInSamples = barLengthInSeconds * (sampleRatef/ sequencingSampleDiv);
float barPhasorInc = 1.f/ barLengthInSamples;
for(auto &v: ratioSeqStates) {
v.phasorInc = barPhasorInc;
}
barPhasorInc = 1.f/ barLengthInSamples;
// for(auto &v: ratioSeqStates) {
// v.phasorInc = barPhasorInc;
// }
float midiClockLengthInSeconds = beatLengthInSeconds / 24.f;
float midiClockLengthInSamples = midiClockLengthInSeconds * sampleRatef;
midiClockPhasorInc = 1.f / midiClockLengthInSamples;
@ -249,6 +263,8 @@ public:
protected:
float i2cValues[8] = {0,0,0,0,0,0,0,0};
float sampleRatef;
bool firstParamsReceived = false;
@ -257,7 +273,10 @@ protected:
float timeSigBeatsInv=1.f/timeSigBeats;
float timeSigDivision=4.f;
size_t sequencingSampleDiv = 50;
float barPhasorInc=0.f;
float barPhasor;
size_t sequencingSampleDiv = 400;
size_t sequencingSampleCounter = 0;
std::array<ratioSeqState, NSEQUENCES> ratioSeqStates;

View file

@ -23,5 +23,6 @@ concept MEMLNautMode = requires(T proc) {
{proc.processAnalysisParams()} -> std::same_as<void>;
// {proc.getNMIDICtrlOutputs()} -> std::same_as<size_t>;
{proc.setupInterface()} -> std::same_as<void>;
{proc.loopCore0()} -> std::same_as<void>;
requires std::same_as<decltype(T::kN_InputParams), const size_t>;
};

View file

@ -11,11 +11,14 @@
#include "MEMLNautMode.hpp"
#include <memory>
#include <array>
#include "../src/memllib/interface/USeqI2C.hpp"
class MEMLNautModeBreakOr {
public:
constexpr static size_t kN_InputParams = 4; // joystick x, y, rotate
USeqI2C i2cOut;
inline static BreakOrAudioApp<> audioAppBreakOr;
std::array<String, BreakOrAudioApp<>::nVoiceSpaces> voiceSpaceList;
@ -24,6 +27,8 @@ public:
bool sequencerPlaying = false;
void setupInterface() {
interface.setup(kN_InputParams, BreakOrAudioApp<>::kN_Params);
interface.bindInterface(InterfaceRL::INPUT_MODES::JOYSTICK, true);
@ -36,22 +41,9 @@ public:
queue_try_add(&audioAppBreakOr.sequencerControlQueue, &sequencerPlaying);
}
// //tiggle up
// if (state) {
// //store output
// savedAction = action;
// actionBeingDragged=true;
// msgView->post("Where do you want it?");
// }else{
// //button up
// if (actionBeingDragged) {
// this->storeExperience(1.f, controlInput, savedAction);
// actionBeingDragged=false;
// msgView->post("Here!");
// }
// }
});
i2cOut.begin();
}
String getHelpTitle() {
@ -105,6 +97,17 @@ public:
void analyse(stereosample_t) {}
float i2cValues[8];
void loopCore0() {
PERIODIC_RUN_US(
if (queue_try_remove(&audioAppBreakOr.i2cOutQueue, &i2cValues)) {
// Serial.printf("i2c received: %f %f %f %f %f %f %f %f\n", i2cValues[0], i2cValues[1], i2cValues[2], i2cValues[3], i2cValues[4], i2cValues[5], i2cValues[6], i2cValues[7]);
bool i2cSuccess = i2cOut.sendValues(i2cValues, 8);
}
, 5000)
}
};

View file

@ -105,5 +105,6 @@ public:
void analyse(stereosample_t) {}
void loopCore0() {}
};

View file

@ -115,4 +115,6 @@ public:
void analyse(stereosample_t) {}
void loopCore0() {}
};

View file

@ -85,4 +85,6 @@ public:
}
void loopCore0() {}
};

View file

@ -15,7 +15,7 @@
class MEMLNautModeVerbFX {
public:
constexpr static size_t kN_InputParams = XiasriAnalysis::kN_Params; //ML
constexpr static size_t kN_InputParams = XiasriAnalysis::kN_Params +4; //ML + joystick
InterfaceRL interface;
std::shared_ptr<InterfaceRL> interfacePtr;
XiasriAnalysis mlAnalysis{kSampleRate};
@ -26,7 +26,7 @@ public:
void setupInterface() {
interface.setup(kN_InputParams, VerbFXAudioApp<>::kN_Params);
interface.bindInterface(InterfaceRL::INPUT_MODES::MACHINE_LISTENING);
interface.bindInterface(InterfaceRL::INPUT_MODES::JOYSTICK_AND_MACHINE_LISTENING);
interfacePtr = make_non_owning(interface);
}
@ -80,4 +80,6 @@ public:
}
void loopCore0() {}
};

View file

@ -80,4 +80,6 @@ public:
}
void loopCore0() {}
};

@ -1 +1 @@
Subproject commit 1693e46e0b38c5920ebdf6cdf2a9107503003c8d
Subproject commit 1e420bf8ed869d58df75663d3dbf6870aa543de1