Added CV and Gate outputs via 2x i2c MCP4725 modules
This commit is contained in:
183
PageSequencer.ino
Normal file
183
PageSequencer.ino
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
[step edit]
|
||||
knobs: octave, note, global tunning, sequence length
|
||||
|
||||
buttons: prev step, next step, rest, glide/tie, accent, play/stop
|
||||
*/
|
||||
void sendPreviewNote(uint8_t step)
|
||||
{
|
||||
unsigned long milliTime, preMilliTime;
|
||||
uint8_t note;
|
||||
|
||||
// enable or disable harmonizer
|
||||
if ( _harmonize == 1 ) {
|
||||
note = harmonizer(_sequencer[_selected_track].data.step[step].note);
|
||||
} else {
|
||||
note = _sequencer[_selected_track].data.step[step].note;
|
||||
}
|
||||
ATOMIC(sendMidiMessage(NOTE_ON, note, _sequencer[_selected_track].data.step[step].accent ? ACCENT_VELOCITY : NOTE_VELOCITY, _sequencer[_selected_track].channel))
|
||||
|
||||
// avoid delay() call because of uClock timmer1 usage
|
||||
//delay(200);
|
||||
preMilliTime = millis();
|
||||
while ( true ) {
|
||||
milliTime = millis();
|
||||
if (abs(milliTime - preMilliTime) >= 200) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ATOMIC(sendMidiMessage(NOTE_OFF, note, 0, _sequencer[_selected_track].channel))
|
||||
}
|
||||
|
||||
void processSequencerPots()
|
||||
{
|
||||
static int8_t octave, note, step_note;
|
||||
static int16_t value;
|
||||
uint8_t relative_step = uint8_t(_step_edit + _sequencer[_selected_track].data.step_init_point) % _sequencer[_selected_track].data.step_length;
|
||||
|
||||
// GENERIC_POT_1: Note Octave Selector
|
||||
octave = getPotChanges(GENERIC_POT_1, 0, 10);
|
||||
if ( octave != -1 ) {
|
||||
_last_octave = octave;
|
||||
}
|
||||
|
||||
// GENERIC_POT_2: Note Selector (generic C to B, no octave)
|
||||
note = getPotChanges(GENERIC_POT_2, 0, 11);
|
||||
if ( note != -1 ) {
|
||||
_last_note = note;
|
||||
}
|
||||
|
||||
// changes on octave or note pot?
|
||||
if ( octave != -1 || note != -1 ) {
|
||||
//ATOMIC(_sequencer[_selected_track].data.step[relative_step].note = (_last_octave * 8) + _last_note);
|
||||
note = (_last_octave * 8) + _last_note;
|
||||
ATOMIC(_sequencer[_selected_track].data.step[relative_step].note = note);
|
||||
if ( _playing == false && _sequencer[_selected_track].data.step[relative_step].rest == 0 ) {
|
||||
sendPreviewNote(relative_step);
|
||||
}
|
||||
}
|
||||
|
||||
// GENERIC_POT_3: global tunning (afects booth tracks) or track tunning
|
||||
value = getPotChanges(GENERIC_POT_3, 0, 24);
|
||||
if ( value != -1 ) {
|
||||
//clearStackNote();
|
||||
// -12 (0) +12
|
||||
ATOMIC(_transpose = value-12);
|
||||
}
|
||||
|
||||
// GENERIC_POT_4: sequencer step length
|
||||
value = getPotChanges(GENERIC_POT_4, 1, STEP_MAX_SIZE);
|
||||
if ( value != -1 ) {
|
||||
//clearStackNote(_selected_track);
|
||||
ATOMIC(_sequencer[_selected_track].data.step_length = value);
|
||||
if ( relative_step >= _sequencer[_selected_track].data.step_length ) {
|
||||
_step_edit = _sequencer[_selected_track].data.step_length-1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void processSequencerButtons()
|
||||
{
|
||||
uint8_t relative_step = uint8_t(_step_edit + _sequencer[_selected_track].data.step_init_point) % _sequencer[_selected_track].data.step_length;
|
||||
|
||||
// previous step edit
|
||||
if ( released(GENERIC_BUTTON_1) ) {
|
||||
if ( _step_edit != 0 ) {
|
||||
// add a lock here for octave and note to not mess with edit mode when moving steps around
|
||||
lockPotsState(true);
|
||||
--_step_edit;
|
||||
}
|
||||
if ( _playing == false && _sequencer[_selected_track].data.step[relative_step].rest == 0 ) {
|
||||
sendPreviewNote(relative_step-1);
|
||||
}
|
||||
}
|
||||
|
||||
// next step edit
|
||||
if ( released(GENERIC_BUTTON_2) ) {
|
||||
if ( _step_edit < _sequencer[_selected_track].data.step_length-1 ) {
|
||||
// add a lock here for octave and note to not mess with edit mode when moving steps around
|
||||
lockPotsState(true);
|
||||
++_step_edit;
|
||||
}
|
||||
if ( _playing == false && _sequencer[_selected_track].data.step[relative_step].rest == 0 ) {
|
||||
sendPreviewNote(relative_step+1);
|
||||
}
|
||||
}
|
||||
|
||||
// step rest
|
||||
if ( pressed(GENERIC_BUTTON_3) ) {
|
||||
ATOMIC(_sequencer[_selected_track].data.step[relative_step].rest = !_sequencer[_selected_track].data.step[relative_step].rest);
|
||||
if ( _playing == false && _sequencer[_selected_track].data.step[relative_step].rest == 0 ) {
|
||||
sendPreviewNote(relative_step);
|
||||
}
|
||||
}
|
||||
|
||||
// step glide/tie
|
||||
if ( pressed(GENERIC_BUTTON_4) ) {
|
||||
// if last step is on or it has a tie, we manage tie data
|
||||
if ((_sequencer[_selected_track].data.step[relative_step-1].rest == 0 || _sequencer[_selected_track].data.step[relative_step-1].tie) && _sequencer[_selected_track].data.step[relative_step].rest && relative_step != 0) {
|
||||
ATOMIC(_sequencer[_selected_track].data.step[relative_step].tie = !_sequencer[_selected_track].data.step[relative_step].tie);
|
||||
// otherwise glide step
|
||||
} else {
|
||||
ATOMIC(_sequencer[_selected_track].data.step[relative_step].glide = !_sequencer[_selected_track].data.step[relative_step].glide);
|
||||
}
|
||||
}
|
||||
|
||||
// step accent
|
||||
if ( pressed(GENERIC_BUTTON_5) ) {
|
||||
ATOMIC(_sequencer[_selected_track].data.step[relative_step].accent = !_sequencer[_selected_track].data.step[relative_step].accent);
|
||||
if ( _playing == false && _sequencer[_selected_track].data.step[relative_step].rest == 0 ) {
|
||||
sendPreviewNote(relative_step);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processSequencerLeds()
|
||||
{
|
||||
uint8_t relative_step = uint8_t(_step_edit + _sequencer[_selected_track].data.step_init_point) % _sequencer[_selected_track].data.step_length;
|
||||
|
||||
// Editing First Step?
|
||||
if ( _step_edit == 0 ) {
|
||||
digitalWrite(GENERIC_LED_1 , HIGH);
|
||||
} else {
|
||||
digitalWrite(GENERIC_LED_1 , LOW);
|
||||
}
|
||||
|
||||
// Editing Last Step?
|
||||
if ( _step_edit == _sequencer[_selected_track].data.step_length-1 ) {
|
||||
digitalWrite(GENERIC_LED_2 , HIGH);
|
||||
} else {
|
||||
digitalWrite(GENERIC_LED_2 , LOW);
|
||||
}
|
||||
|
||||
// Rest
|
||||
if ( _sequencer[_selected_track].data.step[relative_step].rest == 1 ) {
|
||||
digitalWrite(GENERIC_LED_3 , HIGH);
|
||||
} else {
|
||||
digitalWrite(GENERIC_LED_3 , LOW);
|
||||
}
|
||||
|
||||
// Glide/Tie
|
||||
uint8_t tie_glide_staus = 0;
|
||||
// if last step is on or it has a tie, check for tie event
|
||||
if ((_sequencer[_selected_track].data.step[relative_step-1].rest == 0 || _sequencer[_selected_track].data.step[relative_step-1].tie) && _sequencer[_selected_track].data.step[relative_step].rest && relative_step != 0) {
|
||||
tie_glide_staus = _sequencer[_selected_track].data.step[relative_step].tie;
|
||||
} else {
|
||||
tie_glide_staus = _sequencer[_selected_track].data.step[relative_step].glide;
|
||||
}
|
||||
|
||||
if ( tie_glide_staus ) {
|
||||
digitalWrite(GENERIC_LED_4 , HIGH);
|
||||
} else {
|
||||
digitalWrite(GENERIC_LED_4 , LOW);
|
||||
}
|
||||
|
||||
// Accent
|
||||
if ( _sequencer[_selected_track].data.step[relative_step].accent == 1 ) {
|
||||
digitalWrite(GENERIC_LED_5 , HIGH);
|
||||
} else {
|
||||
digitalWrite(GENERIC_LED_5 , LOW);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user