quantum.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. #include "quantum.h"
  2. #include "timer.h"
  3. __attribute__ ((weak))
  4. void matrix_init_kb(void) {}
  5. __attribute__ ((weak))
  6. void matrix_scan_kb(void) {}
  7. __attribute__ ((weak))
  8. bool process_action_kb(keyrecord_t *record) {
  9. return true;
  10. }
  11. __attribute__ ((weak))
  12. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  13. return process_record_user(keycode, record);
  14. }
  15. __attribute__ ((weak))
  16. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  17. return true;
  18. }
  19. __attribute__ ((weak))
  20. void leader_start(void) {}
  21. __attribute__ ((weak))
  22. void leader_end(void) {}
  23. uint8_t starting_note = 0x0C;
  24. int offset = 7;
  25. #ifdef AUDIO_ENABLE
  26. bool music_activated = false;
  27. // music sequencer
  28. static bool music_sequence_recording = false;
  29. static bool music_sequence_playing = false;
  30. static float music_sequence[16] = {0};
  31. static uint8_t music_sequence_count = 0;
  32. static uint8_t music_sequence_position = 0;
  33. static uint16_t music_sequence_timer = 0;
  34. static uint16_t music_sequence_interval = 100;
  35. #endif
  36. #ifdef MIDI_ENABLE
  37. bool midi_activated = false;
  38. #endif
  39. // Leader key stuff
  40. bool leading = false;
  41. uint16_t leader_time = 0;
  42. uint16_t leader_sequence[3] = {0, 0, 0};
  43. uint8_t leader_sequence_size = 0;
  44. // Chording stuff
  45. #define CHORDING_MAX 4
  46. bool chording = false;
  47. uint8_t chord_keys[CHORDING_MAX] = {0};
  48. uint8_t chord_key_count = 0;
  49. uint8_t chord_key_down = 0;
  50. #ifdef UNICODE_ENABLE
  51. static uint8_t input_mode;
  52. #endif
  53. // Shift / paren setup
  54. #ifndef LSPO_KEY
  55. #define LSPO_KEY KC_9
  56. #endif
  57. #ifndef RSPC_KEY
  58. #define RSPC_KEY KC_0
  59. #endif
  60. static bool shift_interrupted[2] = {0, 0};
  61. bool keys_chord(uint8_t keys[]) {
  62. uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
  63. bool pass = true;
  64. uint8_t in = 0;
  65. for (uint8_t i = 0; i < chord_key_count; i++) {
  66. bool found = false;
  67. for (uint8_t j = 0; j < keys_size; j++) {
  68. if (chord_keys[i] == (keys[j] & 0xFF)) {
  69. in++; // detects key in chord
  70. found = true;
  71. break;
  72. }
  73. }
  74. if (found)
  75. continue;
  76. if (chord_keys[i] != 0) {
  77. pass = false; // makes sure rest are blank
  78. }
  79. }
  80. return (pass && (in == keys_size));
  81. }
  82. #ifdef UNICODE_ENABLE
  83. uint16_t hex_to_keycode(uint8_t hex)
  84. {
  85. if (hex == 0x0) {
  86. return KC_0;
  87. } else if (hex < 0xA) {
  88. return KC_1 + (hex - 0x1);
  89. } else {
  90. return KC_A + (hex - 0xA);
  91. }
  92. }
  93. void set_unicode_mode(uint8_t os_target)
  94. {
  95. input_mode = os_target;
  96. }
  97. #endif
  98. bool process_record_quantum(keyrecord_t *record) {
  99. /* This gets the keycode from the key pressed */
  100. keypos_t key = record->event.key;
  101. uint16_t keycode;
  102. #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
  103. uint8_t layer;
  104. if (record->event.pressed) {
  105. layer = layer_switch_get_layer(key);
  106. update_source_layers_cache(key, layer);
  107. } else {
  108. layer = read_source_layers_cache(key);
  109. }
  110. keycode = keymap_key_to_keycode(layer, key);
  111. #else
  112. keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
  113. #endif
  114. if (!process_record_kb(keycode, record))
  115. return false;
  116. // This is how you use actions here
  117. // if (keycode == KC_LEAD) {
  118. // action_t action;
  119. // action.code = ACTION_DEFAULT_LAYER_SET(0);
  120. // process_action(record, action);
  121. // return false;
  122. // }
  123. #ifdef MIDI_ENABLE
  124. if (keycode == MI_ON && record->event.pressed) {
  125. midi_activated = true;
  126. music_scale_user();
  127. return false;
  128. }
  129. if (keycode == MI_OFF && record->event.pressed) {
  130. midi_activated = false;
  131. midi_send_cc(&midi_device, 0, 0x7B, 0);
  132. return false;
  133. }
  134. if (midi_activated) {
  135. if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
  136. if (record->event.pressed) {
  137. starting_note++; // Change key
  138. midi_send_cc(&midi_device, 0, 0x7B, 0);
  139. // midi_send_cc(&midi_device, 1, 0x7B, 0);
  140. // midi_send_cc(&midi_device, 2, 0x7B, 0);
  141. // midi_send_cc(&midi_device, 3, 0x7B, 0);
  142. // midi_send_cc(&midi_device, 4, 0x7B, 0);
  143. }
  144. return false;
  145. }
  146. if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
  147. if (record->event.pressed) {
  148. starting_note--; // Change key
  149. midi_send_cc(&midi_device, 0, 0x7B, 0);
  150. // midi_send_cc(&midi_device, 1, 0x7B, 0);
  151. // midi_send_cc(&midi_device, 2, 0x7B, 0);
  152. // midi_send_cc(&midi_device, 3, 0x7B, 0);
  153. // midi_send_cc(&midi_device, 4, 0x7B, 0);
  154. }
  155. return false;
  156. }
  157. if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
  158. offset++; // Change scale
  159. midi_send_cc(&midi_device, 0, 0x7B, 0);
  160. // midi_send_cc(&midi_device, 1, 0x7B, 0);
  161. // midi_send_cc(&midi_device, 2, 0x7B, 0);
  162. // midi_send_cc(&midi_device, 3, 0x7B, 0);
  163. // midi_send_cc(&midi_device, 4, 0x7B, 0);
  164. return false;
  165. }
  166. if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
  167. offset--; // Change scale
  168. midi_send_cc(&midi_device, 0, 0x7B, 0);
  169. // midi_send_cc(&midi_device, 1, 0x7B, 0);
  170. // midi_send_cc(&midi_device, 2, 0x7B, 0);
  171. // midi_send_cc(&midi_device, 3, 0x7B, 0);
  172. // midi_send_cc(&midi_device, 4, 0x7B, 0);
  173. return false;
  174. }
  175. // basic
  176. // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row);
  177. // advanced
  178. // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row);
  179. // guitar
  180. uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row);
  181. // violin
  182. // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row);
  183. if (record->event.pressed) {
  184. // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
  185. midi_send_noteon(&midi_device, 0, note, 127);
  186. } else {
  187. // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
  188. midi_send_noteoff(&midi_device, 0, note, 127);
  189. }
  190. if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
  191. return false;
  192. }
  193. #endif
  194. #ifdef AUDIO_ENABLE
  195. if (keycode == AU_ON && record->event.pressed) {
  196. audio_on();
  197. return false;
  198. }
  199. if (keycode == AU_OFF && record->event.pressed) {
  200. audio_off();
  201. return false;
  202. }
  203. if (keycode == AU_TOG && record->event.pressed) {
  204. if (is_audio_on())
  205. {
  206. audio_off();
  207. }
  208. else
  209. {
  210. audio_on();
  211. }
  212. return false;
  213. }
  214. if (keycode == MU_ON && record->event.pressed) {
  215. music_on();
  216. return false;
  217. }
  218. if (keycode == MU_OFF && record->event.pressed) {
  219. music_off();
  220. return false;
  221. }
  222. if (keycode == MU_TOG && record->event.pressed) {
  223. if (music_activated)
  224. {
  225. music_off();
  226. }
  227. else
  228. {
  229. music_on();
  230. }
  231. return false;
  232. }
  233. if (keycode == MUV_IN && record->event.pressed) {
  234. voice_iterate();
  235. music_scale_user();
  236. return false;
  237. }
  238. if (keycode == MUV_DE && record->event.pressed) {
  239. voice_deiterate();
  240. music_scale_user();
  241. return false;
  242. }
  243. if (music_activated) {
  244. if (keycode == KC_LCTL && record->event.pressed) { // Start recording
  245. stop_all_notes();
  246. music_sequence_recording = true;
  247. music_sequence_playing = false;
  248. music_sequence_count = 0;
  249. return false;
  250. }
  251. if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
  252. stop_all_notes();
  253. music_sequence_recording = false;
  254. music_sequence_playing = false;
  255. return false;
  256. }
  257. if (keycode == KC_LGUI && record->event.pressed) { // Start playing
  258. stop_all_notes();
  259. music_sequence_recording = false;
  260. music_sequence_playing = true;
  261. music_sequence_position = 0;
  262. music_sequence_timer = 0;
  263. return false;
  264. }
  265. if (keycode == KC_UP) {
  266. if (record->event.pressed)
  267. music_sequence_interval-=10;
  268. return false;
  269. }
  270. if (keycode == KC_DOWN) {
  271. if (record->event.pressed)
  272. music_sequence_interval+=10;
  273. return false;
  274. }
  275. float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row));
  276. if (record->event.pressed) {
  277. play_note(freq, 0xF);
  278. if (music_sequence_recording) {
  279. music_sequence[music_sequence_count] = freq;
  280. music_sequence_count++;
  281. }
  282. } else {
  283. stop_note(freq);
  284. }
  285. if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
  286. return false;
  287. }
  288. #endif
  289. #ifndef DISABLE_LEADER
  290. // Leader key set-up
  291. if (record->event.pressed) {
  292. if (!leading && keycode == KC_LEAD) {
  293. leader_start();
  294. leading = true;
  295. leader_time = timer_read();
  296. leader_sequence_size = 0;
  297. leader_sequence[0] = 0;
  298. leader_sequence[1] = 0;
  299. leader_sequence[2] = 0;
  300. return false;
  301. }
  302. if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
  303. leader_sequence[leader_sequence_size] = keycode;
  304. leader_sequence_size++;
  305. return false;
  306. }
  307. }
  308. #endif
  309. #define DISABLE_CHORDING
  310. #ifndef DISABLE_CHORDING
  311. if (keycode >= 0x5700 && keycode <= 0x57FF) {
  312. if (record->event.pressed) {
  313. if (!chording) {
  314. chording = true;
  315. for (uint8_t i = 0; i < CHORDING_MAX; i++)
  316. chord_keys[i] = 0;
  317. chord_key_count = 0;
  318. chord_key_down = 0;
  319. }
  320. chord_keys[chord_key_count] = (keycode & 0xFF);
  321. chord_key_count++;
  322. chord_key_down++;
  323. return false;
  324. } else {
  325. if (chording) {
  326. chord_key_down--;
  327. if (chord_key_down == 0) {
  328. chording = false;
  329. // Chord Dictionary
  330. if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
  331. register_code(KC_A);
  332. unregister_code(KC_A);
  333. return false;
  334. }
  335. for (uint8_t i = 0; i < chord_key_count; i++) {
  336. register_code(chord_keys[i]);
  337. unregister_code(chord_keys[i]);
  338. return false;
  339. }
  340. }
  341. }
  342. }
  343. }
  344. #endif
  345. #ifdef UNICODE_ENABLE
  346. if (keycode > UNICODE(0) && record->event.pressed) {
  347. uint16_t unicode = keycode & 0x7FFF;
  348. switch(input_mode) {
  349. case UC_OSX:
  350. register_code(KC_LALT);
  351. break;
  352. case UC_LNX:
  353. register_code(KC_LCTL);
  354. register_code(KC_LSFT);
  355. register_code(KC_U);
  356. unregister_code(KC_U);
  357. break;
  358. case UC_WIN:
  359. register_code(KC_LALT);
  360. register_code(KC_PPLS);
  361. unregister_code(KC_PPLS);
  362. break;
  363. }
  364. for(int i = 3; i >= 0; i--) {
  365. uint8_t digit = ((unicode >> (i*4)) & 0xF);
  366. register_code(hex_to_keycode(digit));
  367. unregister_code(hex_to_keycode(digit));
  368. }
  369. switch(input_mode) {
  370. case UC_OSX:
  371. case UC_WIN:
  372. unregister_code(KC_LALT);
  373. break;
  374. case UC_LNX:
  375. unregister_code(KC_LCTL);
  376. unregister_code(KC_LSFT);
  377. break;
  378. }
  379. }
  380. #endif
  381. // Shift / paren setup
  382. switch(keycode) {
  383. case KC_LSPO: {
  384. if (record->event.pressed) {
  385. shift_interrupted[0] = false;
  386. register_mods(MOD_LSFT);
  387. }
  388. else {
  389. if (!shift_interrupted[0]) {
  390. register_code(LSPO_KEY);
  391. unregister_code(LSPO_KEY);
  392. }
  393. unregister_mods(MOD_LSFT);
  394. }
  395. return false;
  396. break;
  397. }
  398. case KC_RSPC: {
  399. if (record->event.pressed) {
  400. shift_interrupted[1] = false;
  401. register_mods(MOD_RSFT);
  402. }
  403. else {
  404. if (!shift_interrupted[1]) {
  405. register_code(RSPC_KEY);
  406. unregister_code(RSPC_KEY);
  407. }
  408. unregister_mods(MOD_RSFT);
  409. }
  410. return false;
  411. break;
  412. }
  413. default: {
  414. shift_interrupted[0] = true;
  415. shift_interrupted[1] = true;
  416. break;
  417. }
  418. }
  419. return process_action_kb(record);
  420. }
  421. const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
  422. 0, 0, 0, 0, 0, 0, 0, 0,
  423. 0, 0, 0, 0, 0, 0, 0, 0,
  424. 0, 0, 0, 0, 0, 0, 0, 0,
  425. 0, 0, 0, 0, 0, 0, 0, 0,
  426. 0, 1, 1, 1, 1, 1, 1, 0,
  427. 1, 1, 1, 1, 0, 0, 0, 0,
  428. 0, 0, 0, 0, 0, 0, 0, 0,
  429. 0, 0, 1, 0, 1, 0, 1, 1,
  430. 1, 1, 1, 1, 1, 1, 1, 1,
  431. 1, 1, 1, 1, 1, 1, 1, 1,
  432. 1, 1, 1, 1, 1, 1, 1, 1,
  433. 1, 1, 1, 0, 0, 0, 1, 1,
  434. 0, 0, 0, 0, 0, 0, 0, 0,
  435. 0, 0, 0, 0, 0, 0, 0, 0,
  436. 0, 0, 0, 0, 0, 0, 0, 0,
  437. 0, 0, 0, 1, 1, 1, 1, 0
  438. };
  439. const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
  440. 0, 0, 0, 0, 0, 0, 0, 0,
  441. KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
  442. 0, 0, 0, 0, 0, 0, 0, 0,
  443. 0, 0, 0, KC_ESC, 0, 0, 0, 0,
  444. KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
  445. KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
  446. KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
  447. KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
  448. KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
  449. KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
  450. KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
  451. KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
  452. KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
  453. KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
  454. KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
  455. KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
  456. };
  457. /* for users whose OSes are set to Colemak */
  458. #if 0
  459. #include "keymap_colemak.h"
  460. const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = {
  461. 0, 0, 0, 0, 0, 0, 0, 0,
  462. 0, 0, 0, 0, 0, 0, 0, 0,
  463. 0, 0, 0, 0, 0, 0, 0, 0,
  464. 0, 0, 0, 0, 0, 0, 0, 0,
  465. 0, 1, 1, 1, 1, 1, 1, 0,
  466. 1, 1, 1, 1, 0, 0, 0, 0,
  467. 0, 0, 0, 0, 0, 0, 0, 0,
  468. 0, 0, 1, 0, 1, 0, 1, 1,
  469. 1, 1, 1, 1, 1, 1, 1, 1,
  470. 1, 1, 1, 1, 1, 1, 1, 1,
  471. 1, 1, 1, 1, 1, 1, 1, 1,
  472. 1, 1, 1, 0, 0, 0, 1, 1,
  473. 0, 0, 0, 0, 0, 0, 0, 0,
  474. 0, 0, 0, 0, 0, 0, 0, 0,
  475. 0, 0, 0, 0, 0, 0, 0, 0,
  476. 0, 0, 0, 1, 1, 1, 1, 0
  477. };
  478. const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
  479. 0, 0, 0, 0, 0, 0, 0, 0,
  480. KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
  481. 0, 0, 0, 0, 0, 0, 0, 0,
  482. 0, 0, 0, KC_ESC, 0, 0, 0, 0,
  483. KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
  484. KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
  485. KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
  486. KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
  487. KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
  488. CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
  489. CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
  490. CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
  491. KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
  492. CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
  493. CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
  494. CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
  495. };
  496. #endif
  497. void send_string(const char *str) {
  498. while (1) {
  499. uint8_t keycode;
  500. uint8_t ascii_code = pgm_read_byte(str);
  501. if (!ascii_code) break;
  502. keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
  503. if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
  504. register_code(KC_LSFT);
  505. register_code(keycode);
  506. unregister_code(keycode);
  507. unregister_code(KC_LSFT);
  508. }
  509. else {
  510. register_code(keycode);
  511. unregister_code(keycode);
  512. }
  513. ++str;
  514. }
  515. }
  516. void matrix_init_quantum() {
  517. matrix_init_kb();
  518. }
  519. void matrix_scan_quantum() {
  520. #ifdef AUDIO_ENABLE
  521. if (music_sequence_playing) {
  522. if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
  523. music_sequence_timer = timer_read();
  524. stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
  525. play_note(music_sequence[music_sequence_position], 0xF);
  526. music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
  527. }
  528. }
  529. #endif
  530. matrix_scan_kb();
  531. }
  532. #ifdef AUDIO_ENABLE
  533. bool is_music_on(void) {
  534. return (music_activated != 0);
  535. }
  536. void music_toggle(void) {
  537. if (!music_activated) {
  538. music_on();
  539. } else {
  540. music_off();
  541. }
  542. }
  543. void music_on(void) {
  544. music_activated = 1;
  545. music_on_user();
  546. }
  547. void music_off(void) {
  548. music_activated = 0;
  549. stop_all_notes();
  550. }
  551. #endif
  552. //------------------------------------------------------------------------------
  553. // Override these functions in your keymap file to play different tunes on
  554. // different events such as startup and bootloader jump
  555. __attribute__ ((weak))
  556. void startup_user() {}
  557. __attribute__ ((weak))
  558. void shutdown_user() {}
  559. __attribute__ ((weak))
  560. void music_on_user() {}
  561. __attribute__ ((weak))
  562. void audio_on_user() {}
  563. __attribute__ ((weak))
  564. void music_scale_user() {}
  565. //------------------------------------------------------------------------------