Skip to content

Commit 3a7da3b

Browse files
committed
add touch keys to monosynth1
1 parent ad13e1b commit 3a7da3b

File tree

1 file changed

+85
-36
lines changed

1 file changed

+85
-36
lines changed

arduino/monosynth1/monosynth1.ino

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
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
@@ -22,14 +23,14 @@
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
5960
MIDI_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
6774
bool retrig_lfo = true;
6875

6976
enum 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;
115121
Portamento <MOZZI_CONTROL_RATE> portamento;
116122
LowPassFilter 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
//
145178
void 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
//
156191
void 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
//
165203
void 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
//
184223
void 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
251309
void 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
273321
AudioOutput 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

Comments
 (0)