#include"MIDI_joystick.h" #include char** combos; //Matriz de combos reconheciveis int* comandos; //String contendo int base; //Valor base para a escala de notas na manete int note_vel; //Valor da dinâmica da mensagem MIDI enviada char** note; //Vetor que guarda as notas enviadas para ser efetuado um NOTEOFF depois #define c_qtd 5 //Variaveis da alavanca direita int R3_cmd[128]; int R3toggle; int ch; //Conexões atuais da controle int axis_x; int axis_y; int rotation; void joystick_callback(t_mosaic_button_event *msg){ //Declaração de variáveis int i, j, k, t, aux, port_id, p_atual, p_anterior; snd_seq_t* handle; handle = msg->handle; port_id = msg->out_id; if(!msg->chain){ for(i = 0; i < 20; i++){ comandos[i] = 0; } } //Interpretação da String de Combo if(msg->combo){ j = 0; while(msg->combo[j] != '\0'){ printf("%d ", msg->combo[j]); j++; } printf("\n"); for(i = 0; i <= c_qtd; i++){ j = 0; k = 1; //Navega pelo combo while(msg->combo[j] != '\0'){ //Verifica o padrão if(msg->combo[j] == combos[i][k]){ //Se padrão completo reconhecido if(k == (combos[i][0])){ comandos[i]++; //Apago o trecho reconhecido para que ele não seja usado de novo for(t = 0; t < k; t++){ msg->combo[j - t] = 'x'; } k = 1; }else{ k++; } } j++; } } j = 0; while(msg->combo[j] != '\0'){ if(!comandos[c_qtd + 2]){ if(msg->combo[j] == 4 && msg->combo[j+1] == 6){ comandos[c_qtd + 1]++; msg->combo[j] = 'x'; msg->combo[j+1] = 'x'; } } if(!comandos[c_qtd + 1]){ if(msg->combo[j] == 6 && msg->combo[j+1] == 4){ comandos[c_qtd + 2]++; msg->combo[j] = 'x'; msg->combo[j+1] = 'x'; } } if(!comandos[c_qtd + 4]){ if(msg->combo[j] == 2 && msg->combo[j+1] == 8){ comandos[c_qtd + 3]++; msg->combo[j] = 'x'; msg->combo[j+1] = 'x'; } } if(!comandos[c_qtd + 3]){ if(msg->combo[j] == 8 && msg->combo[j+1] == 2){ comandos[c_qtd + 4]++; msg->combo[j] = 'x'; msg->combo[j+1] = 'x'; } } j++; } j = 0; while(msg->combo[j] != '\0'){ if(msg->combo[j] == 6) comandos[c_qtd + 5]++; if(msg->combo[j] == 2) comandos[c_qtd + 6]++; if(msg->combo[j] == 4) comandos[c_qtd + 7]++; if(msg->combo[j] == 8) comandos[c_qtd + 8]++; j++; } for(i = 0; i < 20; i++){ printf("%d ", comandos[i]); } printf("\n"); } //Interpretação do evento if(msg->type == JS_EVENT_BUTTON){ //Mudança de oitava while(comandos[c_qtd + 3] > 0){ base += 12; comandos[c_qtd + 3]--; } while(comandos[c_qtd + 4] > 0){ base -= 12; comandos[c_qtd + 4]--; } //Sustenido e Bemol for(i = 0; i < comandos[c_qtd + 8]; i++){ base++; } for(i = 0; i < comandos[c_qtd + 6]; i++){ base--; } if(comandos[0]) ch = 3; if(comandos[c_qtd + 7]) ch = 1; if(comandos[c_qtd + 5]) ch = 2; //Este switch identifica o botão pressionado switch(msg->id){ case 0: //Triângulo if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 9, ch, handle, port_id); send_note(note_vel, base + 9 + 4, ch, handle, port_id); send_note(note_vel, base + 9 + 7, ch, handle, port_id); note[0][0] = base + 9; note[0][1] = 0; note[0][2] = ch; }else{ send_note(note_vel, base + 9, ch, handle, port_id); note[0][0] = base + 9; note[0][1] = -1; note[0][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[0][1] == -1){ send_note(0, note[0][0], note[0][2], handle, port_id); } if(note[0][1] == 0){ send_note(0, note[0][0], note[0][2], handle, port_id); send_note(0, note[0][0] + 4, note[0][2], handle, port_id); send_note(0, note[0][0] + 7, note[0][2], handle, port_id); } } break; case 1: //Bolinha if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 12, ch, handle, port_id); send_note(note_vel, base + 12 + 4, ch, handle, port_id); send_note(note_vel, base + 12 + 7, ch, handle, port_id); note[1][0] = base + 12; note[1][1] = 0; note[1][2] = ch; }else{ send_note(note_vel, base + 12, ch, handle, port_id); note[1][0] = base + 12; note[1][1] = -1; note[1][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[1][1] == -1){ send_note(0, note[1][0], note[1][2], handle, port_id); } if(note[1][1] == 0){ send_note(0, note[1][0], note[1][2], handle, port_id); send_note(0, note[1][0] + 4, note[1][2], handle, port_id); send_note(0, note[1][0] + 7, note[1][2], handle, port_id); } } break; case 2: //Xis if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 11, ch, handle, port_id); send_note(note_vel, base + 11 + 4, ch, handle, port_id); send_note(note_vel, base + 11 + 7, ch, handle, port_id); note[2][0] = base + 11; note[2][1] = 0; note[2][2] = ch; }else{ send_note(note_vel, base + 11, ch, handle, port_id); note[2][0] = base + 11; note[2][1] = -1; note[2][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[2][1] == -1){ send_note(0, note[2][0], note[2][2], handle, port_id); } if(note[2][1] == 0){ send_note(0, note[2][0], note[2][2], handle, port_id); send_note(0, note[2][0] + 4, note[2][2], handle, port_id); send_note(0, note[2][0] + 7, note[2][2], handle, port_id); } } break; case 3: //Quadrado if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 7, ch, handle, port_id); send_note(note_vel, base + 7 + 4, ch, handle, port_id); send_note(note_vel, base + 7 + 7, ch, handle, port_id); note[3][0] = base + 7; note[3][1] = 0; note[3][2] = ch; }else{ send_note(note_vel, base + 7, ch, handle, port_id); note[3][0] = base + 7; note[3][1] = -1; note[3][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[3][1] == -1){ send_note(0, note[3][0], note[3][2], handle, port_id); } if(note[3][1] == 0){ send_note(0, note[3][0], note[3][2], handle, port_id); send_note(0, note[3][0] + 4, note[3][2], handle, port_id); send_note(0, note[3][0] + 7, note[3][2], handle, port_id); } } break; case 4: //L2 if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base, ch, handle, port_id); send_note(note_vel, base + 4, ch, handle, port_id); send_note(note_vel, base + 7, ch, handle, port_id); note[4][0] = base; note[4][1] = 0; note[4][2] = ch; }else{ send_note(note_vel, base, ch, handle, port_id); note[4][0] = base; note[4][1] = -1; note[4][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[4][1] == -1){ send_note(0, note[4][0], note[4][2], handle, port_id); } if(note[4][1] == 0){ send_note(0, note[4][0], note[4][2], handle, port_id); send_note(0, note[4][0] + 4, note[4][2], handle, port_id); send_note(0, note[4][0] + 7, note[4][2], handle, port_id); } } break; case 5: //R2 if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 2, ch, handle, port_id); send_note(note_vel, base + 2 + 4, ch, handle, port_id); send_note(note_vel, base + 2 + 7, ch, handle, port_id); note[5][0] = base + 2; note[5][1] = 0; note[5][2] = ch; }else{ send_note(note_vel, base + 2, ch, handle, port_id); note[5][0] = base + 2; note[5][1] = -1; note[5][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[5][1] == -1){ send_note(0, note[5][0], note[5][2], handle, port_id); } if(note[5][1] == 0){ send_note(0, note[5][0], note[5][2], handle, port_id); send_note(0, note[5][0] + 4, note[5][2], handle, port_id); send_note(0, note[5][0] + 7, note[5][2], handle, port_id); } } break; case 6: //L1 if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 4, ch, handle, port_id); send_note(note_vel, base + 4 + 4, ch, handle, port_id); send_note(note_vel, base + 4 + 7, ch, handle, port_id); note[6][0] = base + 4; note[6][1] = 0; note[6][2] = ch; }else{ send_note(note_vel, base + 4, ch, handle, port_id); note[6][0] = base + 4; note[6][1] = -1; note[6][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[6][1] == -1){ send_note(0, note[6][0], note[6][2], handle, port_id); } if(note[6][1] == 0){ send_note(0, note[6][0], note[6][2], handle, port_id); send_note(0, note[6][0] + 4, note[6][2], handle, port_id); send_note(0, note[6][0] + 7, note[6][2], handle, port_id); } } break; case 7: //R1 if(msg->value){ //Envia uma nota MIDI caso pressionado if(comandos[2]){ send_note(note_vel, base + 5, ch, handle, port_id); send_note(note_vel, base + 5 + 4, ch, handle, port_id); send_note(note_vel, base + 5 + 7, ch, handle, port_id); note[7][0] = base + 5; note[7][1] = 0; note[7][2] = ch; }else{ send_note(note_vel, base + 5, ch, handle, port_id); note[7][0] = base + 5; note[7][1] = -1; note[7][2] = ch; } }else{ //Envia um NOTEOFF para a ultima nota MIDI acionada if(note[7][1] == -1){ send_note(0, note[7][0], note[7][2], handle, port_id); } if(note[7][1] == 0){ send_note(0, note[7][0], note[7][2], handle, port_id); send_note(0, note[7][0] + 4, note[7][2], handle, port_id); send_note(0, note[7][0] + 7, note[7][2], handle, port_id); } } break; case 8: //Select //PANIC BUTTON if(msg->value == 1){ int c; for(c=0; c<128; c++){ send_note(0, c, 0, handle, port_id); } }else{ } break; case 9: //Start if(msg->value == 1){ }else{ } break; case 10: //L3 if(msg->value == 1){ }else{ } break; case 11: //R3 if(msg->value == 1){ //Ativa/desativa a variável R3toggle cadavez que é pressionado if(R3toggle == 0) R3toggle = 1; else R3toggle = 0; }else{ } break; } for(i = 0; i < comandos[c_qtd + 8]; i++){ base--; } for(i = 0; i < comandos[c_qtd + 6]; i++){ base++; } ch = 0; }else if(msg->type == JS_EVENT_AXIS){ aux = -1; if(comandos[c_qtd + 5]){ while(comandos[c_qtd + 5]){ aux = aux + 1; comandos[c_qtd + 5]--; } }else if(comandos[c_qtd + 6] && !comandos[2] && !comandos[3]){ aux = 15; while(comandos[c_qtd + 6]){ aux = aux + 1; comandos[c_qtd + 6]--; } }else if(comandos[c_qtd + 7]){ aux = 31; while(comandos[c_qtd + 7]){ aux = aux + 1; comandos[c_qtd + 7]--; } }else if(comandos[c_qtd + 8] && !comandos[4] && !comandos[5]){ aux = 47; while(comandos[c_qtd + 8]){ aux = aux + 1; comandos[c_qtd + 8]--; } }else if(comandos[2]){ aux = 63; while(comandos[c_qtd + 6]){ aux = aux + 1; comandos[c_qtd + 6]--; } }else if(comandos[3]){ aux = 78; while(comandos[c_qtd + 6]){ aux = aux + 1; comandos[c_qtd + 6]--; } }else if(comandos[4]){ aux = 94; while(comandos[c_qtd + 8]){ aux = aux + 1; comandos[c_qtd + 8]--; } }else if(comandos[5]){ aux = 110; while(comandos[c_qtd + 8]){ aux = aux + 1; comandos[c_qtd + 8]--; } } switch(msg->id){ case 0: //Para eixos horizontais, os valores crescem da esquerda para a direita, com o 0 com centro //L3 Horizontal if(msg->value > 0){ //Direita }else if(msg->value < 0){ //Esquerda }else{ //Neutro } break; case 1: //Para eixos verticais, os valores crescem de cima para baixo, com o 0 como centro //L3 Vertical if(msg->value > 0){ //Baixo }else if(msg->value < 0){ //Cima }else{ //Neutro } break; case 2: //R3 Horizontal if(!R3toggle){ if(aux > -1){ axis_y = aux; printf("Horizontal controlando %d\n", axis_y); } //______________________________________________ //Este eixo envia uma mensagem MIDI de controle aux = msg->value; aux += 32767; aux = (((double)aux / 65534.0) * 127); send_control(axis_y, (int)aux, 0, handle, port_id); //______________________________________________ }else{ //Seleção de controlador para a rotação if(aux > -1){ rotation = aux; printf("Rotação controlando %d\n", rotation); } //___________________________________________ if(msg->axis[3] == 32767){ p_atual = msg->value + 32767; p_atual = (((double)p_atual / 65534.0) * 4); p_anterior = msg->axis[2] + 32767; p_anterior = (((double)p_anterior / 65534.0) * 4); if(p_atual > p_anterior) R3_cmd[rotation]--; if(p_atual < p_anterior) R3_cmd[rotation]++; } if(msg->axis[3] == -32767){ p_atual = msg->value + 32767; p_atual = (((double)p_atual / 65534.0) * 4); p_anterior = msg->axis[2] + 32767; p_anterior = (((double)p_anterior / 65534.0) * 4); if(p_atual > p_anterior) R3_cmd[rotation]++; if(p_atual < p_anterior) R3_cmd[rotation]--; } if(R3_cmd[rotation] > 127) R3_cmd[rotation] = 127; if(R3_cmd[rotation] < 0) R3_cmd[rotation] = 0; send_control(rotation, R3_cmd[rotation], 0, handle, port_id); } if(msg->value > 0){ //Direita }else if(msg->value < 0){ //Esquerda }else{ //Neutro } break; case 3: //R3 Vertical if(!R3toggle){ if(aux > -1){ axis_x = aux; printf("Vertical controlando %d\n", axis_x); } //Este exio envia uma mensagem MIDI de Pitchbend aux = msg->value; aux += 32767; aux = (((double)aux / 65534.0) * 127); send_control(axis_x, (int)aux, 0, handle, port_id); //_______________________________________________ }else{ if(aux > -1){ rotation = aux; printf("Rotação controlando %d\n", rotation); } if(msg->axis[2] == 32767){ p_atual = msg->value + 32767; p_atual = (((double)p_atual / 65534.0) * 4); p_anterior = msg->axis[3] + 32767; p_anterior = (((double)p_anterior / 65534.0) * 4); if(p_atual > p_anterior) R3_cmd[rotation]++; if(p_atual < p_anterior) R3_cmd[rotation]--; } if(msg->axis[2] == -32767){ p_atual = msg->value + 32767; p_atual = (((double)p_atual / 65534.0) * 4); p_anterior = msg->axis[3] + 32767; p_anterior = (((double)p_anterior / 65534.0) * 4); if(p_atual > p_anterior) R3_cmd[rotation]--; if(p_atual < p_anterior) R3_cmd[rotation]++; } if(R3_cmd[rotation] > 127) R3_cmd[rotation] = 127; if(R3_cmd[rotation] < 0) R3_cmd[rotation] = 0; send_control(rotation, R3_cmd[rotation], 0, handle, port_id); } if(msg->value > 0){ //Baixo }else if(msg->value < 0){ //Cima }else{ //Neutro } break; case 4: //D-Pad Horizontal if(msg->value > 0){ //Direita }else if(msg->value < 0){ //Esquerda }else{ //Neutro } break; case 5: //D-pad Vertical if(msg->value > 0){ //Baixo }else if(msg->value < 0){ //Cima }else{ //Neutro } break; } } } int main(){ int i; //Inicialização de valores globais base = 60; note_vel = 80; R3toggle = 0; axis_x = 0; axis_y = 1; ch = 0; rotation = 0; //Inicialização do vetor de notas disparadas //Este vetor é usado para dar NOTEOFF nas notas corretas note = (char**)malloc(8 * sizeof(char*)); for(i = 0; i < 8; i++){ note[i] = (char*)malloc(3 * sizeof(char)); note[i][0] = 0; note[i][1] = -1; note[i][2] = 0; } //Inicialização do vetor de comandos reconhecidos e do vetor de combos reconhecíveis comandos = (int*)malloc(20 * sizeof(int)); combos = (char**)malloc(20 * sizeof(char*)); for(i = 0; i < 20; i++){ combos[i] = (char*)malloc(10 * sizeof(char)); comandos[i] = 0; } for(i = 0; i < 128; i++){ R3_cmd[i] = 0; } //Lista de combos reconhecíveis //41236 combos[0][0] = 5; combos[0][1] = 4; combos[0][2] = 1; combos[0][3] = 2; combos[0][4] = 3; combos[0][5] = 6; //63214 combos[1][0] = 5; combos[1][1] = 6; combos[1][2] = 3; combos[1][3] = 2; combos[1][4] = 1; combos[1][5] = 4; //236 combos[2][0] = 3; combos[2][1] = 2; combos[2][2] = 3; combos[2][3] = 6; //214 combos[3][0] = 3; combos[3][1] = 2; combos[3][2] = 1; combos[3][3] = 4; //896 combos[4][0] = 3; combos[4][1] = 8; combos[4][2] = 9; combos[4][3] = 6; //874 combos[5][0] = 3; combos[5][1] = 8; combos[5][2] = 7; combos[5][3] = 4; //Inicialização da Manete joystick_inicialize("/dev/input/js0", &joystick_callback, NULL); while(1) usleep(10000); return 0; }