MIDI Note Input
This commit is contained in:
parent
9308af9b84
commit
f697d71aac
3 changed files with 70 additions and 12 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
// #include "src/memllib/interface/InterfaceBase.hpp"
|
// #include "src/memllib/interface/InterfaceBase.hpp"
|
||||||
|
#include "src/memllib/interface/MIDIInOut.hpp"
|
||||||
#include "display.hpp"
|
#include "display.hpp"
|
||||||
#include "src/memllib/audio/AudioAppBase.hpp"
|
#include "src/memllib/audio/AudioAppBase.hpp"
|
||||||
#include "src/memllib/audio/AudioDriver.hpp"
|
#include "src/memllib/audio/AudioDriver.hpp"
|
||||||
|
|
@ -32,6 +33,9 @@ uint32_t get_rosc_entropy_seed(int bits) {
|
||||||
// Global objects
|
// Global objects
|
||||||
std::shared_ptr<InterfaceRL> APP_SRAM RLInterface;
|
std::shared_ptr<InterfaceRL> APP_SRAM RLInterface;
|
||||||
|
|
||||||
|
std::shared_ptr<MIDIInOut> APP_SRAM midi_interf;
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<PAFSynthAudioApp> __scratch_y("audio") audio_app;
|
std::shared_ptr<PAFSynthAudioApp> __scratch_y("audio") audio_app;
|
||||||
|
|
||||||
// Inter-core communication
|
// Inter-core communication
|
||||||
|
|
@ -41,6 +45,7 @@ volatile bool APP_SRAM serial_ready = false;
|
||||||
volatile bool APP_SRAM interface_ready = false;
|
volatile bool APP_SRAM interface_ready = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// We're only bound to the joystick inputs (x, y, rotate)
|
// We're only bound to the joystick inputs (x, y, rotate)
|
||||||
constexpr size_t kN_InputParams = 3;
|
constexpr size_t kN_InputParams = 3;
|
||||||
|
|
||||||
|
|
@ -87,6 +92,22 @@ void setup()
|
||||||
RLInterface->bind_RL_interface(scr);
|
RLInterface->bind_RL_interface(scr);
|
||||||
Serial.println("Bound RL interface to MEMLNaut.");
|
Serial.println("Bound RL interface to MEMLNaut.");
|
||||||
|
|
||||||
|
midi_interf = std::make_shared<MIDIInOut>();
|
||||||
|
midi_interf->Setup(0);
|
||||||
|
midi_interf->SetMIDISendChannel(1);
|
||||||
|
Serial.println("MIDI setup complete.");
|
||||||
|
if (midi_interf) {
|
||||||
|
midi_interf->SetNoteCallback([RLInterface] (bool noteon, uint8_t note_number, uint8_t vel_value) {
|
||||||
|
if (noteon) {
|
||||||
|
uint8_t midimsg[2] = {note_number, vel_value };
|
||||||
|
queue_try_add(&audio_app->qMIDINoteOn, &midimsg);
|
||||||
|
}
|
||||||
|
Serial.printf("MIDI Note %d: %d\n", note_number, vel_value);
|
||||||
|
});
|
||||||
|
Serial.println("MIDI note callback set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WRITE_VOLATILE(core_0_ready, true);
|
WRITE_VOLATILE(core_0_ready, true);
|
||||||
while (!READ_VOLATILE(core_1_ready)) {
|
while (!READ_VOLATILE(core_1_ready)) {
|
||||||
|
|
@ -115,6 +136,7 @@ void loop()
|
||||||
// Un-blink LED
|
// Un-blink LED
|
||||||
digitalWrite(33, LOW);
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ stereosample_t PAFSynthAudioApp::Process(const stereosample_t x)
|
||||||
|
|
||||||
// const float trig = pulse.square(1);
|
// const float trig = pulse.square(1);
|
||||||
|
|
||||||
paf0.play(x1, 1, arpFreq, arpFreq + (paf0_cf * arpFreq), paf0_bw * arpFreq, paf0_vib, paf0_vfr, paf0_shift, 0);
|
paf0.play(x1, 1, baseFreq, baseFreq + (paf0_cf * baseFreq), paf0_bw * baseFreq, paf0_vib, paf0_vfr, paf0_shift, 0);
|
||||||
float y = x1[0];
|
float y = x1[0];
|
||||||
|
|
||||||
const float freq1 = arpFreq * detune;
|
const float freq1 = baseFreq * detune;
|
||||||
|
|
||||||
paf1.play(x1, 1, freq1, freq1 + (paf1_cf * freq1), paf1_bw * freq1, paf1_vib, paf1_vfr, paf1_shift, 1);
|
paf1.play(x1, 1, freq1, freq1 + (paf1_cf * freq1), paf1_bw * freq1, paf1_vib, paf1_vfr, paf1_shift, 1);
|
||||||
y += x1[0];
|
y += x1[0];
|
||||||
|
|
@ -36,18 +36,20 @@ stereosample_t PAFSynthAudioApp::Process(const stereosample_t x)
|
||||||
paf2.play(x1, 1, freq2, freq2 + (paf2_cf * freq2), paf2_bw * freq2, paf2_vib, paf2_vfr, paf2_shift, 1);
|
paf2.play(x1, 1, freq2, freq2 + (paf2_cf * freq2), paf2_bw * freq2, paf2_vib, paf2_vfr, paf2_shift, 1);
|
||||||
y += x1[0];
|
y += x1[0];
|
||||||
|
|
||||||
const float ph = phasorOsc.phasor(1);
|
// const float ph = phasorOsc.phasor(1);
|
||||||
const bool euclidNewNote = euclidean(ph, 12, euclidN, 0, 0.1f);
|
// const bool euclidNewNote = euclidean(ph, 12, euclidN, 0, 0.1f);
|
||||||
// y = y * 0.3f;
|
// y = y * 0.3f;
|
||||||
// const float envamp = env.play(counter==0);
|
// const float envamp = env.play(counter==0);
|
||||||
// const float envamp = line.play(counter==0);
|
// const float envamp = line.play(counter==0);
|
||||||
if(zxdetect.onZX(euclidNewNote)) {
|
if(newNote) {
|
||||||
envamp=0.2f;
|
// if(zxdetect.onZX(euclidNewNote)) {
|
||||||
freqIndex++;
|
newNote = false;
|
||||||
if(freqIndex >= 4) {
|
envamp=0.8f;
|
||||||
freqIndex = 0;
|
// freqIndex++;
|
||||||
}
|
// if(freqIndex >= 4) {
|
||||||
arpFreq = frequencies[freqIndex];
|
// freqIndex = 0;
|
||||||
|
// }
|
||||||
|
// arpFreq = frequencies[freqIndex];
|
||||||
}else{
|
}else{
|
||||||
constexpr float envdec = 0.2f/9000.f;
|
constexpr float envdec = 0.2f/9000.f;
|
||||||
envamp -= envdec;
|
envamp -= envdec;
|
||||||
|
|
@ -71,6 +73,8 @@ stereosample_t PAFSynthAudioApp::Process(const stereosample_t x)
|
||||||
// Serial.println(envamp);
|
// Serial.println(envamp);
|
||||||
// })
|
// })
|
||||||
|
|
||||||
|
y *= noteVel;
|
||||||
|
|
||||||
float d1 = (dl1.play(y, 3500, 0.8f) * dl1mix);
|
float d1 = (dl1.play(y, 3500, 0.8f) * dl1mix);
|
||||||
// float d2 = (dl2.play(y, 15000, 0.8f) * dl2mix);
|
// float d2 = (dl2.play(y, 15000, 0.8f) * dl2mix);
|
||||||
y = y + d1;// + d2;
|
y = y + d1;// + d2;
|
||||||
|
|
@ -83,6 +87,8 @@ void PAFSynthAudioApp::Setup(float sample_rate, std::shared_ptr<InterfaceBase> i
|
||||||
{
|
{
|
||||||
AudioAppBase::Setup(sample_rate, interface);
|
AudioAppBase::Setup(sample_rate, interface);
|
||||||
maxiSettings::sampleRate = sample_rate;
|
maxiSettings::sampleRate = sample_rate;
|
||||||
|
|
||||||
|
|
||||||
paf0.init();
|
paf0.init();
|
||||||
paf0.setsr(maxiSettings::getSampleRate(), 1);
|
paf0.setsr(maxiSettings::getSampleRate(), 1);
|
||||||
// paf0.freq(100, 0);
|
// paf0.freq(100, 0);
|
||||||
|
|
@ -118,10 +124,32 @@ void PAFSynthAudioApp::Setup(float sample_rate, std::shared_ptr<InterfaceBase> i
|
||||||
// line.prepare(1.f,0.f,100.f,false);
|
// line.prepare(1.f,0.f,100.f,false);
|
||||||
// line.triggerEnable(true);
|
// line.triggerEnable(true);
|
||||||
envamp=1.f;
|
envamp=1.f;
|
||||||
|
|
||||||
|
queue_init(&qMIDINoteOn, sizeof(uint8_t)*2, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float mtof(uint8_t note) {
|
||||||
|
// Convert MIDI note to frequency
|
||||||
|
return 440.0f * powf(2.0f, (note - 69) / 12.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PAFSynthAudioApp::loop(){
|
||||||
|
AudioAppBase::loop();
|
||||||
|
uint8_t midimsg[2];
|
||||||
|
if (firstParamsReceived && queue_try_remove(&qMIDINoteOn, &midimsg)) {
|
||||||
|
// Serial.printf("PAFSynthAudioApp::ProcessParams - Received MIDI Note On: %d, Velocity: %d\n", midimsg[0], midimsg[1]);
|
||||||
|
baseFreq = mtof(midimsg[0]);
|
||||||
|
noteVel = midimsg[1] / 127.0f; // Normalize velocity to [0, 1]
|
||||||
|
noteVel = noteVel * noteVel; // Square the velocity for more pronounced effect
|
||||||
|
newNote = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PAFSynthAudioApp::ProcessParams(const std::vector<float>& params)
|
void PAFSynthAudioApp::ProcessParams(const std::vector<float>& params)
|
||||||
{
|
{
|
||||||
|
firstParamsReceived = true;
|
||||||
// // Map parameters to the synth
|
// // Map parameters to the synth
|
||||||
// synth_.mapParameters(params);
|
// synth_.mapParameters(params);
|
||||||
// //Serial.print("Params processed.");
|
// //Serial.print("Params processed.");
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ public:
|
||||||
|
|
||||||
void ProcessParams(const std::vector<float>& params) override;
|
void ProcessParams(const std::vector<float>& params) override;
|
||||||
|
|
||||||
|
queue_t qMIDINoteOn, qMIDINoteOff;
|
||||||
|
|
||||||
|
void loop() override;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
maxiPAFOperator paf0;
|
maxiPAFOperator paf0;
|
||||||
|
|
@ -79,7 +82,7 @@ protected:
|
||||||
float arpFreq=50;
|
float arpFreq=50;
|
||||||
|
|
||||||
maxiLine line;
|
maxiLine line;
|
||||||
float envamp;
|
float envamp=0.f;
|
||||||
|
|
||||||
float detune = 1.0;
|
float detune = 1.0;
|
||||||
|
|
||||||
|
|
@ -88,6 +91,11 @@ protected:
|
||||||
|
|
||||||
size_t euclidN=4;
|
size_t euclidN=4;
|
||||||
|
|
||||||
|
float baseFreq = 50.0f; // Base frequency for the synth
|
||||||
|
bool newNote=false;
|
||||||
|
float noteVel = 0.f;
|
||||||
|
bool firstParamsReceived = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __PAF_SYNTH_AUDIO_APP_HPP__
|
#endif // __PAF_SYNTH_AUDIO_APP_HPP__
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue