vail-adapter/adapter.cpp

132 lines
3.4 KiB
C++
Raw Normal View History

2022-05-22 21:55:22 -06:00
#include <Arduino.h>
#include <Keyboard.h>
#include <MIDIUSB.h>
#include <cstddef>
#include "keyers.h"
#include "adapter.h"
#include "polybuzzer.h"
#define MILLISECOND 1
#define SECOND (1000 * MILLISECOND)
VailAdapter::VailAdapter(unsigned int PiezoPin) {
this->buzzer = new PolyBuzzer(PiezoPin);
}
bool VailAdapter::KeyboardMode() {
return this->keyboardMode;
2022-05-22 21:55:22 -06:00
}
// Send a MIDI Key Event
void VailAdapter::midiKey(uint8_t key, bool down) {
2022-05-28 15:18:28 -06:00
midiEventPacket_t event = {uint8_t(down?9:8), uint8_t(down?0x90:0x80), key, 0x7f};
2022-05-22 21:55:22 -06:00
MidiUSB.sendMIDI(event);
MidiUSB.flush();
}
// Send a keyboard key event
void VailAdapter::keyboardKey(uint8_t key, bool down) {
if (down) {
Keyboard.press(key);
} else {
Keyboard.release(key);
}
}
// Begin transmitting
void VailAdapter::BeginTx() {
this->buzzer->Note(0, this->txNote);
2022-05-22 21:55:22 -06:00
if (this->keyboardMode) {
this->keyboardKey(KEY_LEFT_CTRL, true);
} else {
this->midiKey(0, true);
}
}
// Stop transmitting
void VailAdapter::EndTx() {
this->buzzer->NoTone(0);
if (this->keyboardMode) {
this->keyboardKey(KEY_LEFT_CTRL, false);
} else {
this->midiKey(0, false);
}
}
// Handle a paddle being pressed.
//
// The caller needs to debounce keys and deal with keys wired in parallel.
void VailAdapter::HandlePaddle(Paddle paddle, bool pressed) {
switch (paddle) {
case PADDLE_STRAIGHT:
if (pressed) {
this->BeginTx();
} else {
this->EndTx();
}
return;
case PADDLE_DIT:
if (this->keyer) {
this->keyer->Key(paddle, pressed);
} else if (this->keyboardMode) {
this->keyboardKey(KEY_LEFT_CTRL, pressed);
} else {
this->midiKey(1, pressed);
}
break;
case PADDLE_DAH:
if (this->keyer) {
this->keyer->Key(paddle, pressed);
} else if (this->keyboardMode) {
this->keyboardKey(KEY_RIGHT_CTRL, pressed);
} else {
this->midiKey(2, pressed);
}
break;
}
}
// Handle a MIDI event.
//
// We act as a MIDI
void VailAdapter::HandleMIDI(midiEventPacket_t event) {
uint16_t msg = (event.byte1 << 8) | (event.byte2 << 0);
switch (event.byte1) {
case 0xB0: // Controller Change
switch (event.byte2) {
case 0: // turn keyboard mode on/off
this->keyboardMode = (event.byte3 > 0x3f);
MidiUSB.sendMIDI(event); // Send it back to acknowledge
break;
case 1: // set dit duration (0-254) *2ms
this->ditDuration = event.byte3 * 2 * MILLISECOND;
2022-05-28 15:38:10 -06:00
if (this->keyer) {
this->keyer->SetDitDuration(this->ditDuration);
}
2022-05-22 21:55:22 -06:00
break;
case 2: // set tx note
this->txNote = event.byte3;
break;
2022-05-22 21:55:22 -06:00
}
break;
case 0xC0: // Program Change
2022-05-28 15:18:28 -06:00
if (this->keyer) {
this->keyer->Release();
}
2022-05-22 21:55:22 -06:00
this->keyer = GetKeyerByNumber(event.byte2, this);
2022-06-26 10:55:28 -06:00
this->keyer->SetDitDuration(this->ditDuration);
2022-05-22 21:55:22 -06:00
break;
case 0x80: // Note off
this->buzzer->NoTone(1);
break;
case 0x90: // Note on
this->buzzer->Note(1, event.byte2);
break;
}
}
2022-05-28 15:18:28 -06:00
void VailAdapter::Tick(unsigned millis) {
if (this->keyer) {
this->keyer->Tick(millis);
}
}