Skip to content

Commit 4865a59

Browse files
committed
add MIDI CC variables and input handler
1 parent 5cb7f82 commit 4865a59

6 files changed

Lines changed: 197 additions & 23 deletions

File tree

lib/globals.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,23 @@ LEDText *ledtext;
149149
#define MIDIOUTS 6
150150
MidiOut *midiout[6];
151151
bool midi_input_activated = false;
152+
153+
// setup some constants for CCs
154+
const uint8_t cc_knobx = 0;
155+
const uint8_t cc_knoby= 1;
156+
const uint8_t cc_knobz = 2;
157+
const uint8_t cc_tempo = 3;
158+
const uint8_t cc_pitch = 4;
159+
const uint8_t cc_volume = 5;
160+
const uint8_t cc_randsequence = 6;
161+
const uint8_t cc_djfilter = 7;
162+
const uint8_t cc_bassvolume = 8;
163+
const uint8_t cc_sampleselect = 9;
164+
const uint8_t cc_randtunnel = 10;
165+
const uint8_t cc_quantize = 11;
166+
const uint8_t cc_randjump = 12;
167+
const uint8_t cc_randfx = 13;
168+
const uint8_t cc_randfxbank = 14;
152169
#endif
153170

154171
bool toggle_chain_play = false;

lib/midi_comm.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ typedef void (*midi_comm_callback)(uint8_t, uint8_t, uint8_t, uint8_t);
107107

108108
void midi_comm_task(midi_comm_callback callback, callback_int_int midi_note_on,
109109
callback_int midi_note_off, callback_void midi_start,
110-
callback_void midi_continue, callback_void midi_stop,
111-
callback_void midi_timing) {
110+
callback_void midi_continue, callback_void midi_stop,
111+
callback_void midi_timing, callback_uint8_uint8_uint8 midi_control_change) {
112112
uint8_t midi_buffer[3];
113113
midi_buffer[0] = 0;
114114
midi_buffer[1] = 0;
@@ -150,6 +150,12 @@ void midi_comm_task(midi_comm_callback callback, callback_int_int midi_note_on,
150150
midi_stop();
151151
}
152152
return;
153+
} else if (midi_buffer[0] == 0xB0 && bytes_read > 1) {
154+
uint8_t channel = midi_buffer[0] & 0xf;
155+
// CONTROL CHANGE
156+
midi_control_change (channel, midi_buffer[1], midi_buffer[2]);
157+
return;
158+
153159
} else if (midi_buffer[0] == 0x80 && bytes_read > 1) {
154160
// note off received
155161
usb_midi_present = true;

lib/midicallback.h

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,151 @@ void midi_stop() {
7373
do_stop_playback = true;
7474
}
7575

76+
void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) {
77+
// printf("chan/cc/value: %d/%d/%d\n", channel, control, value);
78+
uint8_t new_adcvalue = (value * 2) ;
79+
switch (control) {
80+
case cc_volume: // volume
81+
uint8_t new_vol = new_adcvalue; // is it 256 total?
82+
if (new_vol != sf->vol) {
83+
sf->vol = new_vol;
84+
// printf("sf-vol: %d\n", sf->vol);
85+
}
86+
break;
87+
case cc_bassvolume: // volume
88+
#ifdef INCLUDE_SINEBASS
89+
WaveBass_set_volume(wavebass, new_adcvalue);
90+
#endif
91+
break;
92+
case cc_tempo: // tempo
93+
uint8_t new_bpm = new_adcvalue ; // what is range?
94+
if (new_bpm != sf->bpm_tempo) {
95+
sf->bpm_tempo = new_bpm;
96+
// printf("sf-vol: %d\n", sf->vol);
97+
}
98+
break;
99+
case cc_pitch: // pitch
100+
// if (adc < 2048 - 200) {
101+
// sf->pitch_val_index = adc * PITCH_VAL_MID / (2048 - 200);
102+
// } else if (adc > 2048 + 200) {
103+
// adc -= 2048 + 200;
104+
// sf->pitch_val_index =
105+
// adc * (PITCH_VAL_MAX - PITCH_VAL_MID) / (2048 - 200) +
106+
// PITCH_VAL_MID;
107+
// } else {
108+
// sf->pitch_val_index = PITCH_VAL_MID;
109+
// }
110+
111+
if (new_adcvalue < 127 - 10) {
112+
sf->pitch_val_index = new_adcvalue * PITCH_VAL_MID / (127 - 10);
113+
} else if (new_adcvalue > 127 + 10) {
114+
new_adcvalue -= 127 + 10;
115+
sf->pitch_val_index =
116+
new_adcvalue * (PITCH_VAL_MAX - PITCH_VAL_MID) / (127 - 10) + PITCH_VAL_MID;
117+
} else {
118+
sf->pitch_val_index = PITCH_VAL_MID;
119+
}
120+
break;
121+
case cc_sampleselect: // sample
122+
uint8_t new_sample = new_adcvalue ; // what is range?
123+
uint8_t sample_selection_index = 0;
124+
sample_selection_index = new_sample * (sample_selection_num - 1) / 255;
125+
uint8_t f_sel_bank_next = sample_selection[sample_selection_index].bank;
126+
uint8_t f_sel_sample_next = sample_selection[sample_selection_index].sample;
127+
if (f_sel_bank_next != sel_bank_cur ||
128+
f_sel_sample_next != sel_sample_cur) {
129+
sel_bank_next = f_sel_bank_next;
130+
sel_sample_next = f_sel_sample_next;
131+
printf("[zeptocore] %d bank %d, sample %d\n",
132+
sample_selection_index, sel_bank_next, sel_sample_next);
133+
fil_current_change = true;
134+
}
135+
break;
136+
case cc_quantize: // Qunatize
137+
const uint8_t quantizations[10] = {1, 6, 12, 24, 48,
138+
64, 96, 144, 192, 192};
139+
printf("quantization: %d\n", quantizations[new_adcvalue * 9 / 255 ]);
140+
Sequencer_quantize(
141+
sf->sequencers[mode_buttons16][sf->sequence_sel[mode_buttons16]],
142+
quantizations[new_adcvalue * 9 / 255]);
143+
break;
144+
case cc_randtunnel: // Random Tunnel
145+
probability_of_random_tunnel = new_adcvalue * 1000 / 256;
146+
// if (probability_of_random_tunnel < 100) {
147+
if ((new_adcvalue) < 20) {
148+
probability_of_random_tunnel = 0;
149+
}
150+
break;
151+
case cc_djfilter: // DJ Filter
152+
for (uint8_t channel = 0; channel < 2; channel++) {
153+
int filter_spacing = 16;
154+
for (uint8_t channel = 0; channel < 2; channel++) {
155+
if (new_adcvalue < 128 - filter_spacing) {
156+
global_filter_index =
157+
new_adcvalue * (resonantfilter_fc_max) / (128 - filter_spacing);
158+
global_filter_lphp = 0;
159+
ResonantFilter_setFilterType(resFilter[channel],
160+
global_filter_lphp);
161+
ResonantFilter_setFc(resFilter[channel], global_filter_index);
162+
} else if (value >= 64 + filter_spacing) {
163+
global_filter_index = (new_adcvalue - (128 + filter_spacing)) *
164+
(resonantfilter_fc_max) /
165+
(128 - filter_spacing);
166+
global_filter_lphp = 1;
167+
ResonantFilter_setFilterType(resFilter[channel],
168+
global_filter_lphp);
169+
ResonantFilter_setFc(resFilter[channel], global_filter_index);
170+
} else {
171+
global_filter_index = resonantfilter_fc_max;
172+
global_filter_lphp = 0;
173+
ResonantFilter_setFilterType(resFilter[channel],
174+
global_filter_lphp);
175+
ResonantFilter_setFc(resFilter[channel], resonantfilter_fc_max);
176+
}
177+
}
178+
}
179+
break;
180+
case cc_randfxbank: // Grimoire
181+
// change the grimoire rune
182+
grimoire_rune = new_adcvalue * 7 / 255;
183+
break;
184+
case cc_randfx: // Grimoire Probability = "Break"
185+
break_knob_set_point = new_adcvalue * 1024 / 255;
186+
break;
187+
case cc_randsequence: // Random sequencer
188+
if (new_adcvalue > 255) new_adcvalue = 255;
189+
if (new_adcvalue < 32) {
190+
// normal
191+
do_retrig_at_end_of_phrase = false;
192+
random_sequence_length = 0;
193+
} else if (new_adcvalue < 255 - 32) {
194+
do_retrig_at_end_of_phrase = false;
195+
uint8_t sequence_lengths[11] = {
196+
1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64,
197+
};
198+
random_sequence_length =
199+
sequence_lengths[((int16_t)(new_adcvalue - 32) * 11 / (255 - 32)) % 11];
200+
} else {
201+
// new random sequence
202+
regenerate_random_sequence_arr();
203+
random_sequence_length = 8;
204+
do_retrig_at_end_of_phrase = true;
205+
}
206+
break;
207+
case cc_randjump: // Random Jump - "Amen"
208+
if (new_adcvalue < 128) {
209+
sf->stay_in_sync = true;
210+
probability_of_random_jump = new_adcvalue * 100 / 128;
211+
} else if (new_adcvalue >= 128) {
212+
sf->stay_in_sync = false;
213+
probability_of_random_jump = (255 - new_adcvalue) * 100 / 128;
214+
}
215+
break;
216+
default:
217+
return;
218+
}
219+
220+
}
76221
// Comparator function for qsort
77222
int compare_ints(const void *a, const void *b) {
78223
return (*(int *)a - *(int *)b);

lib/onewiremidi.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ typedef struct Onewiremidi {
5555
callback_void midi_continue;
5656
callback_void midi_stop;
5757
callback_void midi_timing;
58+
callback_uint8_uint8_uint8 midi_control_change;
5859
} Onewiremidi;
5960

6061
Onewiremidi *Onewiremidi_new(PIO pio, unsigned char sm, const uint pin,
@@ -63,7 +64,9 @@ Onewiremidi *Onewiremidi_new(PIO pio, unsigned char sm, const uint pin,
6364
callback_void midi_start,
6465
callback_void midi_continue,
6566
callback_void midi_stop,
66-
callback_void midi_timing) {
67+
callback_void midi_timing,
68+
callback_uint8_uint8_uint8 midi_control_change
69+
) {
6770
Onewiremidi *self = (Onewiremidi *)malloc(sizeof(Onewiremidi));
6871
self->pio = pio;
6972
self->sm = sm;

lib/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ uint16_t bit_set(uint16_t value, uint8_t bit, bool on) {
2424
typedef void (*callback_int_int)(int, int);
2525
typedef void (*callback_int)(int);
2626
typedef void (*callback_int32)(int32_t);
27+
typedef void (*callback_uint8_uint8_uint8)(uint8_t, uint8_t, uint8_t);
2728
typedef void (*callback_uint8_uint8)(uint8_t, uint8_t);
2829
typedef void (*callback_uint8)(uint8_t);
2930
typedef void (*callback_uint16)(uint16_t);

0 commit comments

Comments
 (0)