forked from bagofarms/midi-channel-mapper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharduino_midi_oled.ino
166 lines (137 loc) · 4.25 KB
/
arduino_midi_oled.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <MIDI.h>
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_SSD1306.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
// OLED Display
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
#define SIZE5_2DIGIT_XOFFSET 68
#define SIZE5_2DIGIT_YOFFSET 24
#define OLED_HEADER " MIDItron"
// Potentiometer inputs
#define MAX_POT_VALUE 1024
#define CHAN_IN_POT 2
#define CHAN_OUT_POT 3
#define DEBUG true
MIDI_CREATE_DEFAULT_INSTANCE();
// When output pot is set to 17, make it dynamic
byte dyn_channel = 1; // Programmatically selected
byte man_channel = 1; // Manually selected
byte in_channel = 1; // Input channel
byte prog_pass_channel = 14; // Channel to pass through program change events
void setup() {
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
MIDI.setHandleProgramChange(handleProgramChange);
MIDI.setHandlePitchBend(handlePitchBend);
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.turnThruOff();
// OLED Display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display(); // You must do this after every draw action
delay(500);
displayChannels();
}
void loop() {
// Write values to screen
//writeOLED(chanIn, chanOut);
MIDI.read();
}
void handleProgramChange(byte channel, byte number) {
// If we're on the input channel
if(channel == in_channel) {
// Split off the first byte to find output channel to change to
dyn_channel = number;
dyn_channel += 1; // Adding 1 because the midi library is 1-indexed
// Remove the first byte to send out
// byte new_num = number & 0x0F;
displayChannels();
} else if(channel == prog_pass_channel) {
MIDI.sendProgramChange(number, prog_pass_channel);
}
}
void handleAftertouch(byte command, byte data1) {
// Don't do anything here because aftertouch sends data too fast
// and it will bog down the serial reads.
Serial.write(command);
Serial.write(data1);
}
void handleNoteOn(byte channel, byte note, byte velocity) {
if(channel == in_channel) {
if(DEBUG){ displayNoteOLED(channel, note, velocity); }
MIDI.sendNoteOn(note, velocity, getOutChannel());
} else if(channel == prog_pass_channel) {
MIDI.sendNoteOn(note, velocity, prog_pass_channel);
}
}
void handleNoteOff(byte channel, byte note, byte velocity) {
if(channel == in_channel) {
if(DEBUG){ displayNoteOLED(channel, note, velocity); }
MIDI.sendNoteOff(note, velocity, getOutChannel());
} else if(channel == prog_pass_channel) {
MIDI.sendNoteOff(note, velocity, prog_pass_channel);
}
}
void handlePitchBend(byte channel, int bend) {
if(channel == in_channel) {
if(DEBUG){ displayPitchBend(channel, bend); }
MIDI.sendPitchBend(bend, getOutChannel());
} else if(channel == prog_pass_channel) {
MIDI.sendPitchBend(bend, prog_pass_channel);
}
}
byte getOutChannel() {
// TODO: Switch between the dynamic and manual override channel
return dyn_channel;
}
// Display
void displayChannels(){
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(OLED_HEADER);
display.setTextSize(5);
display.setCursor(0,SIZE5_2DIGIT_YOFFSET);
oledPrintWithLeadingZero(in_channel);
display.setCursor(SIZE5_2DIGIT_XOFFSET,SIZE5_2DIGIT_YOFFSET);
oledPrintWithLeadingZero(dyn_channel);
display.display();
}
void displayNoteOLED(byte channel, byte note, byte velocity) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(channel);
display.print(" -> ");
display.print(dyn_channel);
display.setCursor(0,16);
display.println(note);
display.println(velocity);
display.display();
}
void displayPitchBend(byte channel, int bend) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Pitch Bend");
display.println(bend);
display.display();
}
void oledPrintWithLeadingZero(byte val) {
int leftDigit = val/10;
if( leftDigit == 0 ) {
display.print(0);
} else {
display.print(val / 10);
}
display.print(val % 10);
}