#include #include #include #include #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; } // Send a MIDI Key Event void VailAdapter::midiKey(uint8_t key, bool down) { midiEventPacket_t event = {uint8_t(down?9:8), uint8_t(down?0x90:0x80), key, 0x7f}; 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); 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; if (this->keyer) { this->keyer->SetDitDuration(this->ditDuration); } break; case 2: // set tx note this->txNote = event.byte3; break; } break; case 0xC0: // Program Change if (this->keyer) { this->keyer->Release(); } this->keyer = GetKeyerByNumber(event.byte2, this); this->keyer->SetDitDuration(this->ditDuration); break; case 0x80: // Note off this->buzzer->NoTone(1); break; case 0x90: // Note on this->buzzer->Note(1, event.byte2); break; } } void VailAdapter::Tick(unsigned millis) { if (this->keyer) { this->keyer->Tick(millis); } }