Skip to content

Commit

Permalink
Merge pull request #29 from marchingband/dual-usb
Browse files Browse the repository at this point in the history
add dual midi
  • Loading branch information
marchingband authored Nov 13, 2021
2 parents d8453e9 + 3e89a68 commit 65128a4
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 49 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.vscode
.DS_Store
compile_all_boards.sh
compile_mkr_boards.sh
compile_mkr_boards.sh
release_process.txt
9 changes: 8 additions & 1 deletion src/file_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions src/midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
1 change: 1 addition & 0 deletions src/midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
228 changes: 183 additions & 45 deletions src/midi_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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,
Expand All @@ -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};
Expand All @@ -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");
Expand All @@ -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<bytes_read;i++)
// {
// log_i("%d: %d",i,tmp[i]);
// }
for(int i=0;i<bytes_read;i++)
{
// returns uint8_t* or NULL
Expand Down Expand Up @@ -251,12 +242,159 @@ static void read_uart_task()
}
}

static void read_usb_uart_task()
{
uart_event_t event;
int bytes_read;
uint8_t* tmp = (uint8_t*)malloc(MIDI_BUFFER_SIZE);
if(tmp == NULL)
{
log_e("failed to malloc tmp");
}

log_i("midi usb task running on core %u",xPortGetCoreID());

for(;;) {
if(xQueueReceive(uart_queue_usb, (void *)&event, (portTickType)portMAX_DELAY)) {
bzero(tmp, MIDI_BUFFER_SIZE);
if(event.type==UART_DATA)
{
bytes_read = uart_read_bytes(USB_MIDI_UART_NUM, tmp, event.size, portMAX_DELAY);
for(int i=0;i<bytes_read;i++)
{
// returns uint8_t* or NULL
usb_msg = usb_midi_parse(tmp[i]);
if(usb_msg)
{
// send it through the midi filter hook
usb_msg = midi_hook(usb_msg);
}
if(usb_msg)
{
uint8_t channel = usb_msg[0] & 0b00001111;
uint8_t code = (usb_msg[0] >> 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);
}

Expand Down
3 changes: 2 additions & 1 deletion src/wav_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/wvr_0.3.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 65128a4

Please sign in to comment.