55 *
66 * Responds to Serial (DIN) MIDI In and USB MIDI
77 *
8- * @todbot 3 Jan 2021
8+ * @todbot 3 Jan 2021
99 **/
1010
1111// set DEBUG_MIDI 1 to show CCs received in Serial Monitor
12- #define DEBUG_MIDI 0
12+ #define DEBUG_MIDI 1
1313
1414#include < Adafruit_TinyUSB.h>
1515#include < MIDI.h>
16+ #include < TouchyTouch.h>
1617
1718#include " MozziConfigValues.h" // for named option values
1819#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
2223#define MOZZI_I2S_PIN_BCK 20
2324#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1 ) // HAS TO BE NEXT TO pBCLK, i.e. default is 21
2425#define MOZZI_I2S_PIN_DATA 22
25- #define OSCIL_DITHER_PHASE 1
26+ #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE // we're using regular analogRead()
27+ // #define OSCIL_DITHER_PHASE 1
2628// Mozzi's controller update rate, seems to have issues at 1024
2729// If slower than 512 can't get all MIDI from Live
28- #define MOZZI_CONTROL_RATE 512
29- // #define MOZZI_CONTROL_RATE 128 // mozzi rate for updateControl()
30+ #define MOZZI_CONTROL_RATE 512 // mozzi rate for updateControl()
31+ // #define MOZZI_CONTROL_RATE 128 // mozzi rate for updateControl()
3032
3133#include < Mozzi.h>
32-
3334#include < Oscil.h>
3435#include < tables/triangle_analogue512_int8.h>
3536#include < tables/square_analogue512_int8.h>
@@ -59,11 +60,17 @@ Adafruit_USBD_MIDI usb_midi; // USB MIDI object
5960MIDI_CREATE_INSTANCE (Adafruit_USBD_MIDI, usb_midi, MIDIusb); // USB MIDI
6061// MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDIuart); // Serial MIDI
6162
63+ const int touch_pins[] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 };
64+ const int touch_count = sizeof (touch_pins) / sizeof (int );
65+ const int touch_threshold_adjust = 100 ;
66+
67+ TouchyTouch touches[touch_count];
68+ bool touched[touch_count];
6269
6370// SETTINGS
6471// int portamento_time = 50; // milliseconds
6572// int env_release_time = 1000; // milliseconds
66- byte sound_mode = 0 ; // patch number / program change
73+ byte patch_num = 0 ; // patch number / program change
6774bool retrig_lfo = true ;
6875
6976enum KnownCCs {
@@ -94,7 +101,6 @@ typedef struct {
94101 float filtermod_freq;
95102 float attack_time;
96103 float release_time;
97-
98104} Patch;
99105
100106
@@ -115,8 +121,11 @@ ADSR <CONTROL_RATE, MOZZI_AUDIO_RATE> envelope;
115121Portamento <MOZZI_CONTROL_RATE> portamento;
116122LowPassFilter lpf;
117123
118- //
119- void setup () {
124+ int notes_on = 0 ;
125+ uint32_t last_debug_millis;
126+
127+ // core0 is UI
128+ void setup () {
120129 pinMode (LED_BUILTIN, OUTPUT);
121130
122131 // Serial1.setRX(uart_rx_pin);
@@ -128,21 +137,47 @@ void setup() {
128137 // MIDIuart.begin(MIDI_CHANNEL_OMNI); // don't forget OMNI
129138 // MIDIuart.turnThruOff(); // turn off echo
130139
131- startMozzi (MOZZI_CONTROL_RATE);
140+ // TOUCH
141+ for (int i = 0 ; i < touch_count; i++) {
142+ touches[i].begin (touch_pins[i]);
143+ touches[i].threshold += touch_threshold_adjust; // make a bit more noise-proof
144+ touched[i] = false ;
145+ }
146+ }
132147
133- handleProgramChange (0 ); // set our initial patch
148+ // core0 is UI
149+ void loop () {
150+ handleMIDI ();
151+
152+ updateInputs ();
153+
154+ if ( millis () - last_debug_millis > 100 ) {
155+ last_debug_millis = millis ();
156+ for (int i = 0 ; i < touch_count; i++) {
157+ char t = touches[i].touched () ? ' |' : ' ' ; // indicates a touched value
158+ int touchval = touches[i].raw_value / 100 ; // make a more printalbe value
159+ Serial.printf (" %c%2d%c" , t, touchval, t);
160+ }
161+ Serial.println ();
162+ }
134163
135- }
164+ }
136165
137- //
138- void loop () {
166+ // core1 is audio
167+ void setup1 () {
168+ startMozzi (MOZZI_CONTROL_RATE);
169+ handleProgramChange (patch_num); // set our initial patch
170+ }
171+
172+ // core1 is audio
173+ void loop1 () {
139174 audioHook ();
140175}
141176
142- int notes_on = 0 ;
143-
144177//
145178void handleNoteOn (byte channel, byte note, byte velocity) {
179+ (void ) channel;
180+ (void ) velocity;
146181 #if DEBUG_MIDI
147182 Serial.println (" midi_test handleNoteOn!" );
148183 #endif
@@ -154,6 +189,9 @@ void handleNoteOn(byte channel, byte note, byte velocity) {
154189
155190//
156191void handleNoteOff (byte channel, byte note, byte velocity) {
192+ (void ) channel;
193+ (void ) note;
194+ (void ) velocity;
157195 digitalWrite (LED_BUILTIN,LOW);
158196 notes_on--;
159197 if ( ! notes_on ) {
@@ -163,6 +201,7 @@ void handleNoteOff(byte channel, byte note, byte velocity) {
163201
164202//
165203void handleControlChange (byte channel, byte cc_num, byte cc_val) {
204+ (void ) channel;
166205 #if DEBUG_MIDI
167206 Serial.printf (" CC %d %d\n " , cc_num, cc_val);
168207 #endif
@@ -183,14 +222,14 @@ void handleControlChange(byte channel, byte cc_num, byte cc_val) {
183222//
184223void handleProgramChange (byte m) {
185224 Serial.print (" program change:" ); Serial.println ((byte)m);
186- sound_mode = m;
187- if ( sound_mode == 0 ) {
225+ patch_num = m;
226+ if ( patch_num == 0 ) {
188227 aOsc1.setTable (SAW_ANALOGUE512_DATA);
189228 aOsc2.setTable (SAW_ANALOGUE512_DATA);
190229
191230 mod_vals[Modulation] = 0 ; // FIXME: modulation unused currently
192231 mod_vals[Resonance] = 93 ;
193- mod_vals[FilterCutoff] = 60 ;
232+ mod_vals[FilterCutoff] = 50 ;
194233 mod_vals[PortamentoTime] = 50 ; // actually in milliseconds
195234 mod_vals[EnvReleaseTime] = 100 ; // in 10x milliseconds (100 = 1000 msecs)
196235
@@ -201,7 +240,7 @@ void handleProgramChange(byte m) {
201240 envelope.setTimes (50 , 200 , 20000 , mod_vals[EnvReleaseTime]*10 );
202241 portamento.setTime ( mod_vals[PortamentoTime] );
203242 }
204- else if ( sound_mode == 1 ) {
243+ else if ( patch_num == 1 ) {
205244 aOsc1.setTable (SQUARE_ANALOGUE512_DATA);
206245 aOsc2.setTable (SQUARE_ANALOGUE512_DATA);
207246
@@ -215,7 +254,7 @@ void handleProgramChange(byte m) {
215254 envelope.setTimes (50 , 100 , 20000 , (uint16_t )mod_vals[EnvReleaseTime]*10 );
216255 portamento.setTime ( mod_vals[PortamentoTime] );
217256 }
218- else if ( sound_mode == 2 ) {
257+ else if ( patch_num == 2 ) {
219258 aOsc1.setTable (TRIANGLE_ANALOGUE512_DATA);
220259 aOsc2.setTable (TRIANGLE_ANALOGUE512_DATA);
221260 mod_vals[FilterCutoff] = 65 ;
@@ -247,31 +286,41 @@ void handleMIDI() {
247286 }
248287}
249288
250- // mozzi function, called at CONTROL_RATE times per second
289+ void updateInputs () {
290+ static int touchi = 0 ;
291+
292+ // button.update();
293+ // knobA_update();
294+ // knobB_update();
295+
296+ // only check one touch button per loop since touchytouch spinloops
297+ touches[touchi].update ();
298+ if ( touches[touchi].pressed () ) {
299+ handleNoteOn ( 0 , 36 + touchi, 127 );
300+ }
301+ if ( touches[touchi].released () ) {
302+ handleNoteOff ( 0 , 36 + touchi, 0 );
303+ }
304+ touchi = (touchi+1 ) % touch_count;
305+
306+ }
307+
308+ // Mozzi function, called at CONTROL_RATE times per second on core1
251309void updateControl () {
252- handleMIDI ();
253-
254- // map the lpf modulation into the filter range (0-255), corresponds with 0-8191Hz, kFilterMod runs -128-127
255- // uint8_t cutoff_freq = cutoff + (mod_amount * (kFilterMod.next()/2));
256- // uint16_t fm = ((kFilterMod.next() * mod_vals[Modulation]) / 128) + 127 ;
257- // uint8_t cutoff_freq = constrain(mod_vals[FilterCutoff] + fm, 0,255 );
258-
259- // lpf.setCutoffFreqAndResonance(cutoff_freq, mod_vals[Resonance]*2);
260310
261311 lpf.setCutoffFreqAndResonance (mod_vals[FilterCutoff], mod_vals[Resonance]*2 ); // don't *2 filter since we want 0-4096Hz
262312
263313 envelope.update ();
264314
265315 Q16n16 pf = portamento.next (); // Q16n16 is a fixed-point fraction in 32-bits (16bits . 16bits)
266316 aOsc1.setFreq_Q16n16 (pf);
267- // aOsc2.setFreq_Q16n16(pf * 1.02); // FIXME: adjustable detune plz
268- aOsc2.setFreq_Q16n16 (pf * (1 + rand (10 )/1000.0 )); // FIXME: adjustable detune plz
269-
317+ aOsc2.setFreq_Q16n16 (pf * 1.001 ); // FIXME: adjustable detune plz
270318}
271319
272- // mozzi function, called at AUDIO_RATE times per second
320+ // Mozzi function, called at AUDIO_RATE times per second on core1
273321AudioOutput updateAudio () {
274- long asig = lpf.next ( aOsc1.next () + aOsc2.next () );
322+ int32_t asig = aOsc1.next () + aOsc2.next ();
323+ asig = lpf.next ( asig );
275324 asig = envelope.next () * asig;
276325 return StereoOutput::fromAlmostNBit (18 , asig, asig); // 16 = 8 signal bits + 8 envelope bits
277326}
0 commit comments