From 3e89a6861aeffb8793768e2fd1b9adc69491b25b Mon Sep 17 00:00:00 2001 From: marchingband Date: Fri, 12 Nov 2021 17:17:53 -0800 Subject: [PATCH] add dual midi --- .gitignore | 3 +- src/file_system.c | 9 +- src/midi.cpp | 21 +++++ src/midi.h | 1 + src/midi_in.c | 228 +++++++++++++++++++++++++++++++++++++--------- src/wav_player.c | 3 +- src/wvr_0.3.h | 2 +- 7 files changed, 218 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index 85470cf..2929565 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode .DS_Store compile_all_boards.sh -compile_mkr_boards.sh \ No newline at end of file +compile_mkr_boards.sh +release_process.txt \ No newline at end of file diff --git a/src/file_system.c b/src/file_system.c index febb623..e97dae9 100644 --- a/src/file_system.c +++ b/src/file_system.c @@ -504,7 +504,14 @@ struct wav_lu_t get_file_t_from_lookup_table(uint8_t voice, uint8_t note, uint8_ } for(int i=1; i<=rack.num_layers; i++){ if(velocity <= rack.break_points[i]){ - return(rack.layers[i-1]); + // add the mode enums from the parent note + struct wav_lu_t wav = rack.layers[i-1]; + wav.play_back_mode = wav_lut[voice][note].play_back_mode; + wav.retrigger_mode = wav_lut[voice][note].retrigger_mode; + wav.note_off_meaning = wav_lut[voice][note].note_off_meaning; + wav.response_curve = wav_lut[voice][note].response_curve; + // return(rack.layers[i-1]); + return wav; } } // its above the top threshold diff --git a/src/midi.cpp b/src/midi.cpp index 9b652fc..09728c6 100644 --- a/src/midi.cpp +++ b/src/midi.cpp @@ -6,12 +6,15 @@ #include "midi.h" midiXparser midiParser; +midiXparser usbMidiParser; uint8_t *msg; +uint8_t *usb_msg; void midi_parser_init(void) { midiParser.setMidiMsgFilter( midiXparser::channelVoiceMsgTypeMsk ); + usbMidiParser.setMidiMsgFilter( midiXparser::channelVoiceMsgTypeMsk ); } extern "C" uint8_t* midi_parse(uint8_t in) @@ -30,4 +33,22 @@ extern "C" uint8_t* midi_parse(uint8_t in) } } return NULL; +} + +extern "C" uint8_t* usb_midi_parse(uint8_t in) +{ + if ( usbMidiParser.parse( in ) ) // Do we received a channel voice msg ? + { + if ( + usbMidiParser.isMidiStatus(midiXparser::noteOnStatus) || + usbMidiParser.isMidiStatus(midiXparser::noteOffStatus) || + usbMidiParser.isMidiStatus(midiXparser::programChangeStatus) || + usbMidiParser.isMidiStatus(midiXparser::controlChangeStatus) + ) + { + usb_msg = usbMidiParser.getMidiMsg(); + return usb_msg; + } + } + return NULL; } \ No newline at end of file diff --git a/src/midi.h b/src/midi.h index 227ccdc..697e9cf 100644 --- a/src/midi.h +++ b/src/midi.h @@ -9,6 +9,7 @@ extern "C" { #endif uint8_t* midi_parse(uint8_t in); + uint8_t* usb_midi_parse(uint8_t in); uint8_t* midi_hook_default(uint8_t *in); #ifdef __cplusplus diff --git a/src/midi_in.c b/src/midi_in.c index 5f8a725..b00f73a 100644 --- a/src/midi_in.c +++ b/src/midi_in.c @@ -12,6 +12,7 @@ #include "midi.h" #define MIDI_UART_NUM UART_NUM_2 +#define USB_MIDI_UART_NUM UART_NUM_1 #define BUF_SIZE (1024) #define RD_BUF_SIZE (BUF_SIZE) @@ -22,43 +23,42 @@ static const char *TAG = "midi"; // from server.cpp void sendWSMsg(char* msg); -// from midiXparser.cpp -// uint8_t *midi_parse(uint8_t in); -// uint8_t *midi_hook(uint8_t *in); esp_err_t ret; QueueHandle_t wav_player_queue; QueueHandle_t uart_queue; // uart Events queue +QueueHandle_t uart_queue_usb; // usb uart Events queue struct wav_player_event_t wav_player_event; -int bytes_read; -uint8_t *raw_msg; uint8_t *msg; +uint8_t *usb_msg; uint8_t*(*midi_hook)(uint8_t *in); -void init_gpio(bool useUsbMidi) +void init_gpio() { gpio_config_t io_conf; io_conf.mode = GPIO_MODE_INPUT; io_conf.pull_up_en = GPIO_PULLUP_ENABLE; io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; - if(useUsbMidi) - { - io_conf.pin_bit_mask = (1 << GPIO_NUM_21); // USB MIDI - } - else - { - io_conf.pin_bit_mask = (1 << GPIO_NUM_23); // WVR MIDI IN - } -// io_conf.pin_bit_mask = (1 << GPIO_NUM_23); // WVR MIDI IN -// io_conf.pin_bit_mask = (1 << GPIO_NUM_21); // USB MIDI + io_conf.pin_bit_mask = (1 << GPIO_NUM_23); // WVR MIDI IN io_conf.intr_type = GPIO_INTR_DISABLE; gpio_config(&io_conf); } -void init_uart(bool useUsbMidi) +void init_gpio_usb() +{ + gpio_config_t io_conf; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pull_up_en = GPIO_PULLUP_ENABLE; + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pin_bit_mask = (1 << GPIO_NUM_21); // USB MIDI + io_conf.intr_type = GPIO_INTR_DISABLE; + gpio_config(&io_conf); +} + +void init_uart() { uart_config_t uart_config = { .baud_rate = 31250, @@ -68,19 +68,26 @@ void init_uart(bool useUsbMidi) .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; ESP_ERROR_CHECK(uart_param_config(MIDI_UART_NUM, &uart_config)); - if(useUsbMidi) - { - ESP_ERROR_CHECK(uart_set_pin(MIDI_UART_NUM, UART_PIN_NO_CHANGE, USB_MIDI_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); - } - else - { - ESP_ERROR_CHECK(uart_set_pin(MIDI_UART_NUM, UART_PIN_NO_CHANGE, MIDI_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); - } - // ESP_ERROR_CHECK(uart_set_pin(MIDI_UART_NUM, UART_PIN_NO_CHANGE, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_set_pin(MIDI_UART_NUM, UART_PIN_NO_CHANGE, MIDI_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); ESP_ERROR_CHECK(uart_driver_install(MIDI_UART_NUM,1024, 0, 1024, &uart_queue, 0)); ESP_ERROR_CHECK(uart_set_rx_timeout(MIDI_UART_NUM, 1)); } +void init_uart_usb() +{ + uart_config_t uart_config = { + .baud_rate = 31250, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE + }; + ESP_ERROR_CHECK(uart_param_config(USB_MIDI_UART_NUM, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(USB_MIDI_UART_NUM, UART_PIN_NO_CHANGE, USB_MIDI_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_driver_install(USB_MIDI_UART_NUM,1024, 0, 1024, &uart_queue_usb, 0)); + ESP_ERROR_CHECK(uart_set_rx_timeout(USB_MIDI_UART_NUM, 1)); +} + #define MIDI_BUFFER_SIZE 256 uint8_t channel_lut[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @@ -97,20 +104,8 @@ uint8_t *get_channel_lut(void) static void read_uart_task() { uart_event_t event; + int bytes_read; uint8_t* tmp = (uint8_t*)malloc(MIDI_BUFFER_SIZE); - - // uart_config_t uart_config = { - // .baud_rate = 31250, - // .data_bits = UART_DATA_8_BITS, - // .parity = UART_PARITY_DISABLE, - // .stop_bits = UART_STOP_BITS_1, - // .flow_ctrl = UART_HW_FLOWCTRL_DISABLE - // }; - // ESP_ERROR_CHECK(uart_param_config(MIDI_UART_NUM, &uart_config)); - // ESP_ERROR_CHECK(uart_set_pin(MIDI_UART_NUM, UART_PIN_NO_CHANGE, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); - // ESP_ERROR_CHECK(uart_driver_install(MIDI_UART_NUM,1024, 0, 1024, &uart_queue, 0)); - // ESP_ERROR_CHECK(uart_set_rx_timeout(MIDI_UART_NUM, 1)); - if(tmp == NULL) { log_e("failed to malloc tmp"); @@ -124,10 +119,6 @@ static void read_uart_task() if(event.type==UART_DATA) { bytes_read = uart_read_bytes(MIDI_UART_NUM, tmp, event.size, portMAX_DELAY); - // for(int i=0;i> 4) & 0b00001111; + switch (code) + { + case MIDI_NOTE_ON: + case MIDI_NOTE_OFF: + { + struct wav_player_event_t wav_player_event; + wav_player_event.code = (usb_msg[0] >> 4) & 0b00001111; + wav_player_event.voice = channel_lut[channel]; + wav_player_event.note = usb_msg[1] & 0b01111111; + wav_player_event.velocity = usb_msg[2] & 0b01111111; + wav_player_event.channel = channel; + xQueueSendToBack(wav_player_queue,(void *) &wav_player_event, portMAX_DELAY); + // log_i("%d: note:%d velocity:%d channel:%d voice:%d code:%d", + // i, + // wav_player_event.note, + // wav_player_event.velocity, + // wav_player_event.channel, + // wav_player_event.voice, + // wav_player_event.code + // ); + } + break; + case MIDI_PROGRAM_CHANGE: + { + uint8_t voice = usb_msg[1] & 0b01111111; + // log_e("prog chng %d on channel %d",voice, channel); + // if the program change is out of range set it to the highest voice + voice = voice < NUM_VOICES ? voice : NUM_VOICES - 1; + channel_lut[channel] = voice; + break; + } + case MIDI_CC: + { + uint8_t CC = usb_msg[1] & 0b01111111; + uint8_t val = usb_msg[2] & 0b01111111; + // log_i("MIDI_CC:#%d val:%d on channel %d", CC, val, channel); + switch (CC) + { + case MIDI_CC_PAN: + // log_e("Pan %d",val); + if(val == 64) + { + channel_pan[channel].left_vol = 127; + channel_pan[channel].right_vol = 127; + } + else if(val == 0) + { + channel_pan[channel].right_vol = 0; + channel_pan[channel].left_vol = 127; + } + else if(val == 127) + { + channel_pan[channel].right_vol = 127; + channel_pan[channel].left_vol = 0; + } + else if(val > 64) + { + channel_pan[channel].right_vol = 127; + channel_pan[channel].left_vol = 127 - ((val - 64) * 2); + } + else if(val < 64) + { + channel_pan[channel].right_vol = 127 - ((64 - val) * 2); + channel_pan[channel].left_vol = 127; + } + break; + case MIDI_CC_EQ_BASS: + eq_low = ((val * 2.0) / 127) - 1; + break; + case MIDI_CC_EQ_TREBLE: + eq_high = ((val * 2.0) / 127); + break; + default: + break; + } + } + default: + break; + } + } + } + } + else if(event.type==UART_FIFO_OVF) + { + log_e("UART_USB_FIFO_OVF"); + } + else if(event.type==UART_BUFFER_FULL) + { + log_e("UART_USB_BUFFER_FULL"); + } + else if(event.type==UART_BREAK) + { + log_e("UART_USB_BREAK"); + } + else if(event.type==UART_PARITY_ERR) + { + log_e("UART_USB_PARITY_ERR"); + } + else if(event.type==UART_FRAME_ERR) + { + log_e("UART_USB_FRAME_ERR"); + } + else + { + log_e("other uart usb event %d", event.type); + } + } + } +} + void midi_init(bool useUsbMidi) { - init_gpio(useUsbMidi); - init_uart(useUsbMidi); + init_gpio(); + init_uart(); midi_hook = midi_hook_default; xTaskCreatePinnedToCore(read_uart_task, "read_uart_task", 4096, NULL, 3, NULL, 0); + if(useUsbMidi) + { + init_gpio_usb(); + init_uart_usb(); + xTaskCreatePinnedToCore(read_usb_uart_task, "read_usb_uart_task", 4096, NULL, 3, NULL, 0); + } // xTaskCreatePinnedToCore(read_uart_task, "read_uart_task", 4096, NULL, 3, NULL, 1); } diff --git a/src/wav_player.c b/src/wav_player.c index 20ff88a..0f4e781 100644 --- a/src/wav_player.c +++ b/src/wav_player.c @@ -214,7 +214,7 @@ void stop_wav(uint8_t voice, uint8_t note) { struct wav_player_event_t wav_player_event; wav_player_event.code = MIDI_NOTE_OFF; - wav_player_event.voice = 0; + wav_player_event.voice = voice; wav_player_event.velocity = 0; wav_player_event.note = note; xQueueSendToBack(wav_player_queue, &wav_player_event, portMAX_DELAY); @@ -304,6 +304,7 @@ void wav_player_task(void* pvParameters) ) { // it is a retrigger, do the right thing + switch(bufs[b].wav_data.retrigger_mode){ case RESTART: bufs[b].fade = 1; diff --git a/src/wvr_0.3.h b/src/wvr_0.3.h index 9921729..92992af 100644 --- a/src/wvr_0.3.h +++ b/src/wvr_0.3.h @@ -3,7 +3,7 @@ // #include "WVR.h" -#define VERSION_CODE "1.0.5" +#define VERSION_CODE "1.0.6" void wvr_init(bool useFTDI, bool useUsbMidi, bool checkRecoveryModePin);