From 09ff0cb7558a8e0b12611f4a3e18d8efff9acb37 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Mon, 9 Aug 2021 11:45:53 +0200 Subject: [PATCH] First test for sequencer-sync towards the audio interrupt. --- MicroDexed.ino | 30 +++++++++++++++++ sequencer.cpp | 81 +++++++++++++++++++++++---------------------- sequencer.h | 48 +++++++++++++-------------- sequencer_timer.cpp | 39 ++++++++++++++++++++++ sequencer_timer.h | 27 +++++++++++++++ 5 files changed, 162 insertions(+), 63 deletions(-) create mode 100644 sequencer_timer.cpp create mode 100644 sequencer_timer.h diff --git a/MicroDexed.ino b/MicroDexed.ino index 1867a8d..5ec6155 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -36,6 +36,7 @@ #include "effect_modulated_delay.h" #include "effect_stereo_mono.h" #include "effect_mono_stereo.h" +#include "sequencer_timer.h" #ifdef USE_PLATEREVERB #include "effect_platervbstereo.h" #else @@ -251,6 +252,9 @@ AudioConnection patchCord22(drum_mixer_l, 0, master_mixer_l, 2); #endif #endif +AudioSequencerTimer sequencer_timer; +AudioConnection patchCord25(reverb_mixer_r, sequencer_timer); + // // Dynamic patching of MicroDexed objects // @@ -400,6 +404,29 @@ extern LCDMenuLib2 LCDML; extern void getNoteName(char* noteName, uint8_t noteNumber); +void testfunc(void) +{ + static int8_t takt; + + switch (takt % 4) + { + case 0: + Serial.println("EINS!"); + break; + case 1: + Serial.println("ZWEI!"); + break; + case 2: + Serial.println("DREI!"); + break; + case 3: + Serial.println("VIER!"); + takt = -1; + break; + } + takt++; +} + /*********************************************************************** SETUP ***********************************************************************/ @@ -665,6 +692,9 @@ void setup() audio_thru_mixer_l.gain(3, 0.0); #endif + sequencer_timer.set_bpm(60); + sequencer_timer.step_function(&testfunc); + #ifdef DEBUG Serial.println(F("")); #endif diff --git a/sequencer.cpp b/sequencer.cpp index 792656b..d46526e 100644 --- a/sequencer.cpp +++ b/sequencer.cpp @@ -12,19 +12,22 @@ extern void handleNoteOff(byte , byte , byte ); extern void UI_func_sequencer(uint8_t); extern const char* seq_find_shortname(uint8_t); + + + void sequencer(void) { - + if (seq_note_in > 0 && seq_note_in < 62 && seq_recording == false ) { - // handleNoteOff(configuration.dexed[0].midi_channel, seq_data[3][seq_step] + seq_transpose , 0); - // handleNoteOff(configuration.dexed[0].midi_channel, seq_data[3][seq_step - 1] + seq_transpose , 0); + // handleNoteOff(configuration.dexed[0].midi_channel, seq_data[3][seq_step] + seq_transpose , 0); + // handleNoteOff(configuration.dexed[0].midi_channel, seq_data[3][seq_step - 1] + seq_transpose , 0); -//if (seq_note_in>65)seq_note_in=seq_note_in-12; + //if (seq_note_in>65)seq_note_in=seq_note_in-12; - // seq_transpose = seq_note_in % 12 ; + // seq_transpose = seq_note_in % 12 ; //seq_transpose=seq_transpose-12; - // seq_note_in = 0; + // seq_note_in = 0; } if (seq_millis_timer > seq_timer_previous + seq_tempo_ms) @@ -34,17 +37,17 @@ void sequencer(void) if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_sequencer)) { - //write to sequencer if in sequencer menu + //write to sequencer if in sequencer menu if (seq_note_in > 0 && seq_recording == true) { - // if ( seq_content_type[ seq_patternchain[seq_chain_active_step][active_track] ] == 1) handleNoteOff(configuration.dexed[0].midi_channel, seq_data[active_track][seq_step] + seq_transpose , 0); + // if ( seq_content_type[ seq_patternchain[seq_chain_active_step][active_track] ] == 1) handleNoteOff(configuration.dexed[0].midi_channel, seq_data[active_track][seq_step] + seq_transpose , 0); seq_data[seq_active_track][seq_step] = seq_note_in; seq_vel[seq_active_track][seq_step] = seq_note_in_velocity; seq_note_in = 0; - seq_note_in_velocity=0; + seq_note_in_velocity = 0; } - lcd.setCursor(seq_step, 1); + lcd.setCursor(seq_step, 1); lcd.print("X"); if (seq_step == 0) { lcd.setCursor(15, 1); @@ -54,53 +57,53 @@ void sequencer(void) { lcd.setCursor(seq_step - 1, 1); lcd.print(seq_find_shortname(seq_step - 1)[0]); - } + } } for (uint8_t d = 0; d < 4; d++) { - if ( seq_track_type[d] == 0){// drum track - if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 && seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0) - { - handleNoteOn(DRUM_MIDI_CHANNEL, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] , seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]); + if ( seq_track_type[d] == 0) { // drum track + if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 && seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0) + { + handleNoteOn(DRUM_MIDI_CHANNEL, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] , seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]); + } } + else { + if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 && seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0) // instrument track + { + handleNoteOn(configuration.dexed[0].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose , seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]); + seq_prev_note[d] = seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose; + } + } + seq_noteoffsent[d] = false; } - else { - if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 && seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0) // instrument track - { - handleNoteOn(configuration.dexed[0].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose , seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]); - seq_prev_note[d]=seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose; - } - } - seq_noteoffsent[d] = false; - } - + seq_step++; if (seq_step > 15) { seq_step = 0; - if (seq_chain_lenght>0){ - seq_chain_active_step++; - if (seq_chain_active_step>seq_chain_lenght) - { - seq_chain_active_step=0; - } - } + if (seq_chain_lenght > 0) { + seq_chain_active_step++; + if (seq_chain_active_step > seq_chain_lenght) + { + seq_chain_active_step = 0; + } } + } } if (seq_millis_timer > seq_timer_previous + 80 ) { - for (uint8_t d = 0; d < 4; d++) + for (uint8_t d = 0; d < 4; d++) { - if( seq_noteoffsent[d] == false) { + if ( seq_noteoffsent[d] == false) { if ( seq_prev_note[d] > 0) //test instrument sequencer Instance=0 { handleNoteOff(configuration.dexed[0].midi_channel, seq_prev_note[d] , 0); - } - } - seq_noteoffsent[d] = true; - } - + } + } + seq_noteoffsent[d] = true; + } + } } diff --git a/sequencer.h b/sequencer.h index acd4fe4..a2d90ec 100644 --- a/sequencer.h +++ b/sequencer.h @@ -2,7 +2,7 @@ uint8_t seq_active_track = 0; uint8_t seq_menu; bool seq_button_r = false; -bool seq_noteoffsent[4] = {false,false,false,false}; +bool seq_noteoffsent[4] = {false, false, false, false}; elapsedMillis seq_millis_timer; uint8_t seq_step = 0; uint32_t seq_timer_previous = 0; @@ -11,39 +11,39 @@ bool seq_recording = false; uint8_t seq_note_in; uint8_t seq_note_in_velocity; int seq_transpose; -int seq_tempo_ms=147; -int seq_bpm=102; +int seq_tempo_ms = 147; +int seq_bpm = 102; uint8_t seq_temp_select_menu; uint8_t seq_temp_active_menu = 99; uint8_t seq_chain_active_chainstep; uint8_t seq_chain_lenght = 3; // 0=16 steps, 1=32 Steps, 2=46 Steps, 3=64 Steps uint8_t seq_chain_active_step = 0; uint8_t seq_prev_note[4]; // note_offs for every (instr.) track -uint8_t seq_data[10][16] = {72 ,0 ,0 ,0 ,72 ,0 ,0 ,0 ,72 ,0 ,0 ,0 ,72 ,0 ,0 ,0 , - 78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 ,78 , - 72 ,0 ,0 ,0 ,72 ,0 ,0 ,0 ,72 ,0 ,0 ,75 ,72 ,0 ,0 ,0 , - 60 ,61 ,62 ,63 ,64 ,65 ,66 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 55 ,0 ,0 ,0 ,0 ,0 ,52 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 57 ,0 ,0 ,0 ,0 ,0 ,53 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 74 ,0 ,0 ,72 ,0 ,0 ,74 ,0 ,0 ,0 ,76 ,0 ,0 ,0 ,0 ,0 , - 74 ,0 ,0 ,72 ,0 ,0 ,71 ,0 ,0 ,0 ,67 ,0 ,0 ,0 ,0 ,0 , - 69 ,0 ,0 ,76 ,0 ,0 ,69 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 +uint8_t seq_data[10][16] = {72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , + 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , + 72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , 72 , 0 , 0 , 75 , 72 , 0 , 0 , 0 , + 60 , 61 , 62 , 63 , 64 , 65 , 66 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 55 , 0 , 0 , 0 , 0 , 0 , 52 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 57 , 0 , 0 , 0 , 0 , 0 , 53 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 74 , 0 , 0 , 72 , 0 , 0 , 74 , 0 , 0 , 0 , 76 , 0 , 0 , 0 , 0 , 0 , + 74 , 0 , 0 , 72 , 0 , 0 , 71 , 0 , 0 , 0 , 67 , 0 , 0 , 0 , 0 , 0 , + 69 , 0 , 0 , 76 , 0 , 0 , 69 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; -uint8_t seq_vel[10][16] = {120 ,0 ,0 ,0 ,120 ,0 ,0 ,0 ,120 ,0 ,0 ,0 ,120 ,0 ,0 ,0 , - 125 ,101 ,125 ,125 ,126 ,98 ,126 ,99 ,126 ,97 ,126 ,100 ,126 ,99 ,125 ,100 , - 120 ,0 ,0 ,0 ,120 ,0 ,0 ,0 ,120 ,0 ,120 ,120 ,120 ,120 ,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 125 ,0 ,0 ,0 ,0 ,0 ,126 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 78 ,120 ,0 ,0 ,0 ,0 ,84 ,120 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 98 ,120 ,0 ,88 ,120 ,0 ,127 ,120 ,0 ,0 ,125 ,120 ,0 ,0 , - 0 ,0 ,124 ,120 ,0 ,115 ,0 ,0 ,126 ,120 ,0 ,120 ,127 ,120 ,0 ,0 , - 0 ,0 ,123 ,120 ,0 ,110 ,120 ,0 ,90 ,120 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 +uint8_t seq_vel[10][16] = {120 , 0 , 0 , 0 , 120 , 0 , 0 , 0 , 120 , 0 , 0 , 0 , 120 , 0 , 0 , 0 , + 125 , 101 , 125 , 125 , 126 , 98 , 126 , 99 , 126 , 97 , 126 , 100 , 126 , 99 , 125 , 100 , + 120 , 0 , 0 , 0 , 120 , 0 , 0 , 0 , 120 , 0 , 120 , 120 , 120 , 120 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 125 , 0 , 0 , 0 , 0 , 0 , 126 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 78 , 120 , 0 , 0 , 0 , 0 , 84 , 120 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 98 , 120 , 0 , 88 , 120 , 0 , 127 , 120 , 0 , 0 , 125 , 120 , 0 , 0 , + 0 , 0 , 124 , 120 , 0 , 115 , 0 , 0 , 126 , 120 , 0 , 120 , 127 , 120 , 0 , 0 , + 0 , 0 , 123 , 120 , 0 , 110 , 120 , 0 , 90 , 120 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; -uint8_t seq_patternchain[4][4] = { 0 ,1 ,6 ,9 ,0 ,1 ,5 ,8 ,0 ,1 ,6 ,9 ,2 ,1 ,5 ,7 +uint8_t seq_patternchain[4][4] = { 0 , 1 , 6 , 9 , 0 , 1 , 5 , 8 , 0 , 1 , 6 , 9 , 2 , 1 , 5 , 7 }; uint8_t seq_content_type[10] = { 0, 0, 0, 0 , 1, 1, 1 , 1 , 1 , 1 }; // 0 = track is Drumtrack, 1= Instrumenttrack uint8_t seq_track_type[4] = { 0, 0, 1, 1 }; // 0 = track is Drumtrack, 1= Instrumenttrack diff --git a/sequencer_timer.cpp b/sequencer_timer.cpp new file mode 100644 index 0000000..ffcbfaf --- /dev/null +++ b/sequencer_timer.cpp @@ -0,0 +1,39 @@ +#include +#include "config.h" +#include "sequencer_timer.h" + +void AudioSequencerTimer::update(void) +{ + audio_block_t *in; + + in = receiveReadOnly(0); + if (in) + release(in); + + tick++; + + if (tick >= float(beat)*float(bpm) + 0.5) + { + if (sequencer_step_function != NULL) + (*sequencer_step_function)(); + tick = 0; + } +} + +uint32_t AudioSequencerTimer::get_tick(void) +{ + return (tick); +} + +void AudioSequencerTimer::set_bpm(uint8_t b) +{ + bpm = b; +} + +void AudioSequencerTimer::step_function(void(*func)()) +{ + if (func != NULL) + sequencer_step_function = func; + else + sequencer_step_function = NULL; +} diff --git a/sequencer_timer.h b/sequencer_timer.h new file mode 100644 index 0000000..24bce3b --- /dev/null +++ b/sequencer_timer.h @@ -0,0 +1,27 @@ +#ifndef _SEQUENCER_TIMER_H_ +#define _SEQUENCER_TIMER_H_ + +class AudioSequencerTimer : public AudioStream +{ + public: + AudioSequencerTimer(void): + AudioStream(1, inputQueueArray) + { + tick = 0; + bpm = 60; + sequencer_step_function = NULL; + } + + virtual uint32_t get_tick(void); + virtual void set_bpm(uint8_t b); + virtual void step_function(void(*func)()); + virtual void update(void); + + private: + audio_block_t *inputQueueArray[1]; + uint8_t bpm; + void (*sequencer_step_function)(); + volatile uint32_t tick; + const float beat = AUDIO_SAMPLE_RATE_EXACT / float(AUDIO_BLOCK_SAMPLES) / 60.0; +}; +#endif