process_midi.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "process_midi.h"
  2. #include "timer.h"
  3. typedef union {
  4. uint16_t raw;
  5. struct {
  6. uint8_t octave :4;
  7. uint8_t velocity :4;
  8. uint8_t channel :4;
  9. uint8_t modulation_interval :4;
  10. };
  11. } midi_config_t;
  12. midi_config_t midi_config;
  13. #define MIDI_INVALID_NOTE 0xFF
  14. #define MIDI_TONE_COUNT (MIDI_TONE_MAX - MIDI_TONE_MIN + 1)
  15. static uint8_t tone_status[MIDI_TONE_COUNT];
  16. static uint8_t midi_modulation;
  17. static int8_t midi_modulation_step;
  18. static uint16_t midi_modulation_timer;
  19. inline uint8_t compute_velocity(uint8_t setting)
  20. {
  21. return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
  22. }
  23. void midi_init(void)
  24. {
  25. midi_config.octave = MI_OCT_0 - MIDI_OCTAVE_MIN;
  26. midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
  27. midi_config.channel = 0;
  28. midi_config.modulation_interval = 8;
  29. for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
  30. {
  31. tone_status[i] = MIDI_INVALID_NOTE;
  32. }
  33. midi_modulation = 0;
  34. midi_modulation_step = 0;
  35. midi_modulation_timer = 0;
  36. }
  37. void midi_task(void)
  38. {
  39. if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
  40. return;
  41. midi_modulation_timer = timer_read();
  42. if (midi_modulation_step != 0)
  43. {
  44. dprintf("midi modulation %d\n", midi_modulation);
  45. midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
  46. if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
  47. midi_modulation = 0;
  48. midi_modulation_step = 0;
  49. return;
  50. }
  51. midi_modulation += midi_modulation_step;
  52. if (midi_modulation > 127)
  53. midi_modulation = 127;
  54. }
  55. }
  56. bool process_midi(uint16_t keycode, keyrecord_t *record)
  57. {
  58. switch (keycode) {
  59. case MIDI_TONE_MIN ... MIDI_TONE_MAX:
  60. {
  61. uint8_t channel = midi_config.channel;
  62. uint8_t tone = keycode - MIDI_TONE_MIN;
  63. uint8_t velocity = compute_velocity(midi_config.velocity);
  64. if (record->event.pressed) {
  65. uint8_t note = 12 * midi_config.octave + tone;
  66. midi_send_noteon(&midi_device, channel, note, velocity);
  67. dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
  68. tone_status[tone] = note;
  69. }
  70. else {
  71. uint8_t note = tone_status[tone];
  72. if (note != MIDI_INVALID_NOTE)
  73. {
  74. midi_send_noteoff(&midi_device, channel, note, velocity);
  75. dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
  76. }
  77. tone_status[tone] = MIDI_INVALID_NOTE;
  78. }
  79. return false;
  80. }
  81. case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
  82. if (record->event.pressed) {
  83. midi_config.octave = keycode - MIDI_OCTAVE_MIN;
  84. dprintf("midi octave %d\n", midi_config.octave);
  85. }
  86. return false;
  87. case MI_OCTD:
  88. if (record->event.pressed && midi_config.octave > 0) {
  89. midi_config.octave--;
  90. dprintf("midi octave %d\n", midi_config.octave);
  91. }
  92. return false;
  93. case MI_OCTU:
  94. if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
  95. midi_config.octave++;
  96. dprintf("midi octave %d\n", midi_config.octave);
  97. }
  98. return false;
  99. case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
  100. if (record->event.pressed) {
  101. midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
  102. dprintf("midi velocity %d\n", midi_config.velocity);
  103. }
  104. return false;
  105. case MI_VELD:
  106. if (record->event.pressed && midi_config.velocity > 0) {
  107. midi_config.velocity--;
  108. dprintf("midi velocity %d\n", midi_config.velocity);
  109. }
  110. return false;
  111. case MI_VELU:
  112. if (record->event.pressed) {
  113. midi_config.velocity++;
  114. dprintf("midi velocity %d\n", midi_config.velocity);
  115. }
  116. return false;
  117. case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
  118. if (record->event.pressed) {
  119. midi_config.channel = keycode - MIDI_CHANNEL_MIN;
  120. dprintf("midi channel %d\n", midi_config.channel);
  121. }
  122. return false;
  123. case MI_CHD:
  124. if (record->event.pressed) {
  125. midi_config.channel--;
  126. dprintf("midi channel %d\n", midi_config.channel);
  127. }
  128. return false;
  129. case MI_CHU:
  130. if (record->event.pressed) {
  131. midi_config.channel++;
  132. dprintf("midi channel %d\n", midi_config.channel);
  133. }
  134. return false;
  135. case MI_OFF:
  136. if (record->event.pressed) {
  137. midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
  138. dprintf("midi off\n");
  139. }
  140. return false;
  141. case MI_SUS:
  142. midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
  143. dprintf("midi sustain %d\n", record->event.pressed);
  144. return false;
  145. case MI_PORT:
  146. midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
  147. dprintf("midi portamento %d\n", record->event.pressed);
  148. return false;
  149. case MI_SOST:
  150. midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
  151. dprintf("midi sostenuto %d\n", record->event.pressed);
  152. return false;
  153. case MI_SOFT:
  154. midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
  155. dprintf("midi soft %d\n", record->event.pressed);
  156. return false;
  157. case MI_LEG:
  158. midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
  159. dprintf("midi legato %d\n", record->event.pressed);
  160. return false;
  161. case MI_MOD:
  162. midi_modulation_step = record->event.pressed ? 1 : -1;
  163. return false;
  164. case MI_MODSD:
  165. if (record->event.pressed) {
  166. midi_config.modulation_interval++;
  167. // prevent overflow
  168. if (midi_config.modulation_interval == 0)
  169. midi_config.modulation_interval--;
  170. dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
  171. }
  172. return false;
  173. case MI_MODSU:
  174. if (record->event.pressed && midi_config.modulation_interval > 0) {
  175. midi_config.modulation_interval--;
  176. dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
  177. }
  178. return false;
  179. };
  180. return true;
  181. }