Initial commit for midi. Midi out is working, Midi In is still a work in progress.
This commit is contained in:
65
clock.h
65
clock.h
@ -12,28 +12,49 @@
|
|||||||
#ifndef CLOCK_H
|
#ifndef CLOCK_H
|
||||||
#define CLOCK_H
|
#define CLOCK_H
|
||||||
|
|
||||||
|
#include <NeoHWSerial.h>
|
||||||
#include <uClock.h>
|
#include <uClock.h>
|
||||||
|
|
||||||
#include "peripherials.h"
|
#include "peripherials.h"
|
||||||
|
|
||||||
|
// MIDI clock, start, stop, and continue byte definitions - based on MIDI 1.0 Standards.
|
||||||
|
#define MIDI_CLOCK 0xF8
|
||||||
|
#define MIDI_START 0xFA
|
||||||
|
#define MIDI_STOP 0xFC
|
||||||
|
#define MIDI_CONTINUE 0xFB
|
||||||
|
|
||||||
const int DEFAULT_TEMPO = 120;
|
const int DEFAULT_TEMPO = 120;
|
||||||
|
static bool MIDI_ENABLED = false;
|
||||||
|
|
||||||
enum Source {
|
enum Source {
|
||||||
SOURCE_INTERNAL,
|
SOURCE_INTERNAL,
|
||||||
SOURCE_EXTERNAL_PPQN_24,
|
SOURCE_EXTERNAL_PPQN_24,
|
||||||
SOURCE_EXTERNAL_PPQN_4,
|
SOURCE_EXTERNAL_PPQN_4,
|
||||||
// SOURCE_MIDI,
|
SOURCE_EXTERNAL_MIDI,
|
||||||
SOURCE_LAST,
|
SOURCE_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Clock {
|
class Clock {
|
||||||
public:
|
public:
|
||||||
void Init() {
|
void Init() {
|
||||||
|
NeoSerial.begin(31250);
|
||||||
|
NeoSerial.attachInterrupt(onSerialEvent);
|
||||||
|
|
||||||
|
// Static pin definition for pulse out.
|
||||||
|
pinMode(PULSE_OUT_PIN, OUTPUT);
|
||||||
|
|
||||||
// Initialize the clock library
|
// Initialize the clock library
|
||||||
uClock.init();
|
uClock.init();
|
||||||
uClock.setClockMode(uClock.INTERNAL_CLOCK);
|
uClock.setClockMode(uClock.INTERNAL_CLOCK);
|
||||||
uClock.setOutputPPQN(uClock.PPQN_96);
|
uClock.setOutputPPQN(uClock.PPQN_96);
|
||||||
uClock.setTempo(DEFAULT_TEMPO);
|
uClock.setTempo(DEFAULT_TEMPO);
|
||||||
|
|
||||||
|
// MIDI events.
|
||||||
|
uClock.setOnClockStart(sendMIDIStart);
|
||||||
|
uClock.setOnClockStop(sendMIDIStop);
|
||||||
|
uClock.setOnSync24(sendMidiClock);
|
||||||
|
uClock.setOnSync48(sendPulseOut);
|
||||||
|
|
||||||
uClock.start();
|
uClock.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +71,7 @@ class Clock {
|
|||||||
// Set the source of the clock mode.
|
// Set the source of the clock mode.
|
||||||
void SetSource(Source source) {
|
void SetSource(Source source) {
|
||||||
uClock.stop();
|
uClock.stop();
|
||||||
|
MIDI_ENABLED = false;
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case SOURCE_INTERNAL:
|
case SOURCE_INTERNAL:
|
||||||
uClock.setClockMode(uClock.INTERNAL_CLOCK);
|
uClock.setClockMode(uClock.INTERNAL_CLOCK);
|
||||||
@ -62,6 +84,11 @@ class Clock {
|
|||||||
uClock.setClockMode(uClock.EXTERNAL_CLOCK);
|
uClock.setClockMode(uClock.EXTERNAL_CLOCK);
|
||||||
uClock.setInputPPQN(uClock.PPQN_4);
|
uClock.setInputPPQN(uClock.PPQN_4);
|
||||||
break;
|
break;
|
||||||
|
case SOURCE_EXTERNAL_MIDI:
|
||||||
|
uClock.setClockMode(uClock.EXTERNAL_CLOCK);
|
||||||
|
uClock.setInputPPQN(uClock.PPQN_24);
|
||||||
|
MIDI_ENABLED = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
uClock.start();
|
uClock.start();
|
||||||
}
|
}
|
||||||
@ -97,6 +124,42 @@ class Clock {
|
|||||||
bool IsPaused() {
|
bool IsPaused() {
|
||||||
return uClock.clock_state == uClock.PAUSED;
|
return uClock.clock_state == uClock.PAUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void onSerialEvent(uint8_t msg, uint8_t status) {
|
||||||
|
// if (!MIDI_ENABLED) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
switch (msg) {
|
||||||
|
case MIDI_CLOCK:
|
||||||
|
uClock.clockMe();
|
||||||
|
break;
|
||||||
|
case MIDI_STOP:
|
||||||
|
uClock.stop();
|
||||||
|
break;
|
||||||
|
case MIDI_START:
|
||||||
|
case MIDI_CONTINUE:
|
||||||
|
uClock.start();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendMIDIStart() {
|
||||||
|
NeoSerial.write(MIDI_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendMIDIStop() {
|
||||||
|
NeoSerial.write(MIDI_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendMidiClock(uint32_t tick) {
|
||||||
|
NeoSerial.write(MIDI_CLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendPulseOut(uint32_t tick) {
|
||||||
|
digitalWrite(PULSE_OUT_PIN, !digitalRead(PULSE_OUT_PIN));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -39,7 +39,7 @@ AppState app;
|
|||||||
|
|
||||||
// The number of clock mod options, hepls validate choices and pulses arrays are the same size.
|
// The number of clock mod options, hepls validate choices and pulses arrays are the same size.
|
||||||
const int MOD_CHOICE_SIZE = 21;
|
const int MOD_CHOICE_SIZE = 21;
|
||||||
// negative=multiply, positive=divide
|
// Negative for multiply, positive for divide.
|
||||||
const int clock_mod[MOD_CHOICE_SIZE] = {-24, -12, -8, -6, -4, -3, -2, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 24, 32, 64, 128};
|
const int clock_mod[MOD_CHOICE_SIZE] = {-24, -12, -8, -6, -4, -3, -2, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 24, 32, 64, 128};
|
||||||
|
|
||||||
// This represents the number of clock pulses for a 96 PPQN clock source that match the above div/mult mods.
|
// This represents the number of clock pulses for a 96 PPQN clock source that match the above div/mult mods.
|
||||||
@ -317,9 +317,14 @@ void DisplayMainPage() {
|
|||||||
textWidth = gravity.display.getUTF8Width("4 PPQN");
|
textWidth = gravity.display.getUTF8Width("4 PPQN");
|
||||||
gravity.display.drawStr(32 - (textWidth / 2), subTextY, "4 PPQN");
|
gravity.display.drawStr(32 - (textWidth / 2), subTextY, "4 PPQN");
|
||||||
break;
|
break;
|
||||||
// case SOURCE_EXTERNAL_MIDI:
|
case SOURCE_EXTERNAL_MIDI:
|
||||||
// gravity.display.print(F("EXT MIDI"));
|
gravity.display.setFont(LARGE_FONT);
|
||||||
// break;
|
textWidth = gravity.display.getUTF8Width("EXT");
|
||||||
|
gravity.display.drawStr(32 - (textWidth / 2), textY, "EXT");
|
||||||
|
gravity.display.setFont(TEXT_FONT);
|
||||||
|
textWidth = gravity.display.getUTF8Width("MIDI");
|
||||||
|
gravity.display.drawStr(32 - (textWidth / 2), subTextY, "MIDI");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +371,7 @@ void DisplayChannelPage() {
|
|||||||
gravity.display.drawStr(32 - (textWidth / 2), subTextY, "Divide");
|
gravity.display.drawStr(32 - (textWidth / 2), subTextY, "Divide");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sprintf(mod_str, "X%d", abs(clock_mod[ch.clock_mod_index]));
|
sprintf(mod_str, "x%d", abs(clock_mod[ch.clock_mod_index]));
|
||||||
textWidth = gravity.display.getUTF8Width(mod_str);
|
textWidth = gravity.display.getUTF8Width(mod_str);
|
||||||
gravity.display.drawStr(32 - (textWidth / 2), textY, mod_str);
|
gravity.display.drawStr(32 - (textWidth / 2), textY, mod_str);
|
||||||
gravity.display.setFont(TEXT_FONT);
|
gravity.display.setFont(TEXT_FONT);
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
#define EXT_PIN 2
|
#define EXT_PIN 2
|
||||||
#define CV1_PIN A7
|
#define CV1_PIN A7
|
||||||
#define CV2_PIN A6
|
#define CV2_PIN A6
|
||||||
|
#define PULSE_OUT_PIN 3
|
||||||
|
|
||||||
// Button pins
|
// Button pins
|
||||||
#define SHIFT_BTN_PIN 12
|
#define SHIFT_BTN_PIN 12
|
||||||
|
|||||||
Reference in New Issue
Block a user