Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added FEATURE_MIDI for teensy boards #132

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions k3ng_keyer/k3ng_keyer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2328,6 +2328,10 @@ void setup()
initialize_sd_card();
initialize_debug_startup();

#if defined(FEATURE_MIDI)
midi_setup();
#endif

}

// --------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -5897,6 +5901,7 @@ void ptt_key(){
#ifdef FEATURE_SEQUENCER
sequencer_ptt_inactive_time = 0;
#endif

}
#else
if (configuration.current_ptt_line) {
Expand Down Expand Up @@ -5925,6 +5930,10 @@ void ptt_key(){
}
#endif //FEATURE_SO2R_BASE

#ifdef FEATURE_MIDI
midi_key_ptt(1);
#endif

ptt_line_activated = 1;

#ifdef FEATURE_SO2R_BASE
Expand Down Expand Up @@ -6063,6 +6072,11 @@ void ptt_unkey(){
#endif
#endif //FEATURE_SO2R_BASE
}

#ifdef FEATURE_MIDI
midi_key_ptt(0);
#endif

ptt_line_activated = 0;
#ifdef FEATURE_SEQUENCER
sequencer_ptt_inactive_time = millis();
Expand Down Expand Up @@ -7214,6 +7228,10 @@ void speed_set(int wpm_set){
update_led_ring();
#endif //FEATURE_LED_RING

#ifdef FEATURE_MIDI
midi_send_wpm_response();
#endif

#ifdef FEATURE_DISPLAY
lcd_center_print_timed_wpm();
#endif
Expand Down Expand Up @@ -22266,6 +22284,127 @@ void so2r_command() {

//-------------------------------------------------------------------------------------------------------

#ifdef FEATURE_MIDI

void midi_setup() {
// set callback for commands
usbMIDI.setHandleControlChange(myControlChange);
}

void midi_key_tx(int state) {
if (state) {
usbMIDI.sendNoteOn(OPTION_MIDI_BASE_NOTE+1, 99, OPTION_MIDI_KEYER_CHANNEL);
} else {
usbMIDI.sendNoteOff(OPTION_MIDI_BASE_NOTE+1, 0, OPTION_MIDI_KEYER_CHANNEL);
}
}

void midi_key_ptt(int state) {
if (state) {
usbMIDI.sendNoteOn(OPTION_MIDI_BASE_NOTE+0, 99, OPTION_MIDI_KEYER_CHANNEL);
} else {
usbMIDI.sendNoteOff(OPTION_MIDI_BASE_NOTE+0, 0, OPTION_MIDI_KEYER_CHANNEL);
}
}

// MIDI callback
void myControlChange(byte channel, byte control, byte value) {
// debug
//usbMIDI.sendNoteOn(OPTION_MIDI_BASE_NOTE+1, 99, OPTION_MIDI_KEYER_CHANNEL);
//delay(100);
//usbMIDI.sendNoteOff(OPTION_MIDI_BASE_NOTE+1, 0, OPTION_MIDI_KEYER_CHANNEL);
// end debug

int ok = 1;

if (channel != OPTION_MIDI_INPUT_CHANNEL) {
// error, unexpected channel
sendMidiResponseOk(0);
return;
}

switch (control) {
case OPTION_MIDI_IS_KEYER_CONTROL:
// no switching in this Sketch
sendMidiResponseOk(0);
// if (value > 0) {
// setupIambic(1);
// } else {
// setupIambic(0);
// }
break;
case OPTION_MIDI_IAMBIC_CONTROL:
if (value > 0) {
setupIambicMode(1);
} else {
setupIambicMode(0);
}
break;
case OPTION_MIDI_WPM_CONTROL:
speed_set(value);
#ifdef FEATURE_WINKEY_EMULATION
winkey_port_write(((value - pot_wpm_low_value)|128),0);
#endif
break;
case OPTION_MIDI_REVERSE_CONTROL:
if (value > 0) {
configuration.paddle_mode = PADDLE_REVERSE;
} else {
configuration.paddle_mode = PADDLE_NORMAL;
}
break;
case OPTION_MIDI_GET_KEYER_STATE_CONTROL:
sendKeyerStateResponse();
break;
default:
// unknown command
sendMidiResponseOk(0);
}
if (ok == 1) {
sendMidiResponseOk(1);
} else {
sendMidiResponseOk(0);
}
}

void setupIambicMode(int modeB) {
if (modeB == 1) {
configuration.keyer_mode = IAMBIC_B;
} else {
configuration.keyer_mode = IAMBIC_A;
}
config_dirty = 1;
}

void sendMidiResponseOk(int ok) {
if (ok == 1) {
// ok
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_OK, 99, OPTION_MIDI_RESPONSE_CHANNEL);
} else {
// error
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_FAIL, 0, OPTION_MIDI_RESPONSE_CHANNEL);
}
}

void sendKeyerStateResponse() {
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_IS_KEYER, 2, OPTION_MIDI_RESPONSE_CHANNEL);
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_WPM, configuration.wpm, OPTION_MIDI_RESPONSE_CHANNEL);
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_REVERSE, ( configuration.paddle_mode == PADDLE_REVERSE ? 1 : 0 ), OPTION_MIDI_RESPONSE_CHANNEL);
if (configuration.keyer_mode == IAMBIC_B) {
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_IAMBIC, 1, OPTION_MIDI_RESPONSE_CHANNEL);
} else if (configuration.keyer_mode == IAMBIC_A) {
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_IAMBIC, 0, OPTION_MIDI_RESPONSE_CHANNEL);
}
}

void midi_send_wpm_response() {
usbMIDI.sendControlChange(OPTION_MIDI_RESPONSE_WPM, configuration.wpm, OPTION_MIDI_RESPONSE_CHANNEL);
}


#endif // FEATURE_MIDI
//-------------------------------------------------------------------------------------------------------


// DL2DBG contributed code (adapted into code by Goody K3NG)
// Based on https://forum.arduino.cc/index.php?topic=446209.15
Expand Down
31 changes: 31 additions & 0 deletions k3ng_keyer/keyer_features_and_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
// #define FEATURE_INTERNET_LINK // Details: https://github.com/k3ng/k3ng_cw_keyer/wiki/390-Feature:-Ethernet,-Web-Server,-and-Internet-Linking

// #define FEATURE_COMMAND_LINE_INTERFACE_ON_SECONDARY_PORT // Activate the Command Line interface on the secondary serial port
// #define FEATURE_MIDI // sends MIDI notes on supported hardware (teensy 3.x). Can be used e.g. with quisk SDR software

#define OPTION_PRIMARY_SERIAL_PORT_DEFAULT_WINKEY_EMULATION // Use when activating both FEATURE_WINKEY_EMULATION and FEATURE_COMMAND_LINE_INTERFACE
// simultaneously. This will make Winkey emulation be the default at boot up;
// hold command button down at boot up to activate CLI mode
Expand Down Expand Up @@ -134,3 +136,32 @@
// #define OPTION_BEACON_MODE_PTT_TAIL_TIME // adds the ptt tail time to each playing of memory 1 in beacon mode

// #define OPTION_WINKEY_PROSIGN_COMPATIBILITY // Additional character mappings to support K1EL Winkey emulation prosigns

// MIDI definitions
#define OPTION_MIDI_BASE_NOTE 0 // the base midi note
#define OPTION_MIDI_KEYER_CHANNEL 1 // the MIDI channel number to send messages
// commands and queries from the computer
#define OPTION_MIDI_INPUT_CHANNEL 2 // the MIDI channel to receive commands as notes
#define OPTION_MIDI_WPM_CONTROL 0 // for WPM command, value is wpm value
#define OPTION_MIDI_IS_KEYER_CONTROL 1 // set behavior as keyer or dumb interface: value > 0 -> Iambic Keyer, = 0 -> Interface
#define OPTION_MIDI_REVERSE_CONTROL 2 // value > 0 -> Paddle Reverse
#define OPTION_MIDI_IAMBIC_CONTROL 3 // value > 0 -> Iambic B, = 0 -> Iambic A

//
// query for keyer state
// Resonses:
// response_is_keyer: value = 1 - yes, value 0 - no, value = 2 - Winkeyer (not in this Sketch)
// when keyer then more responses:
// response_wpm: value = wpm
// response_reverse: Paddle reverse: value > 0 - yes, value 0 - no
// response_iambic: Iambic Mode: value > 0 -> Iambic B, = 0 -> Iambic A
#define OPTION_MIDI_GET_KEYER_STATE_CONTROL 4

// responses to the computer
#define OPTION_MIDI_RESPONSE_CHANNEL 3 // the channel to send response messages
#define OPTION_MIDI_RESPONSE_FAIL 0
#define OPTION_MIDI_RESPONSE_OK 1
#define OPTION_MIDI_RESPONSE_IS_KEYER 2 // value = 1 - yes, value 0 - no, value = 2 - Winkeyer (not in this Sketch)
#define OPTION_MIDI_RESPONSE_WPM 3 // value = wpm
#define OPTION_MIDI_RESPONSE_REVERSE 4 // Paddle reverse: value > 0 - yes, value 0 - no
#define OPTION_MIDI_RESPONSE_IAMBIC 5 // Iambic Mode: value > 0 -> Iambic B, = 0 -> Iambic A
1 change: 0 additions & 1 deletion k3ng_keyer/keyer_pin_settings.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,3 @@ FEATURE_SIDETONE_SWITCH
#error "Multiple pin_settings.h files included somehow..."

#endif //keyer_pin_settings_h