logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

audio.c (20590B)


  1. /* Copyright 2016-2020 Jack Humbert
  2. * Copyright 2020 JohSchneider
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "audio.h"
  17. #include "eeconfig.h"
  18. #include "timer.h"
  19. #include "debug.h"
  20. #include "wait.h"
  21. #include "util.h"
  22. #include "gpio.h"
  23. /* audio system:
  24. *
  25. * audio.[ch] takes care of all overall state, tracking the actively playing
  26. * notes/tones; the notes a SONG consists of;
  27. * ...
  28. * = everything audio-related that is platform agnostic
  29. *
  30. * driver_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts,
  31. * specific to each platform and the used subsystem/driver to drive
  32. * the output pins/channels with the calculated frequencies for each
  33. * active tone
  34. * as part of this, the driver has to trigger regular state updates by
  35. * calling 'audio_update_state' through some sort of timer - be it a
  36. * dedicated one or piggybacking on for example the timer used to
  37. * generate a pwm signal/clock.
  38. *
  39. *
  40. * A Note on terminology:
  41. * tone, pitch and frequency are used somewhat interchangeably, in a strict Wikipedia-sense:
  42. * "(Musical) tone, a sound characterized by its duration, pitch (=frequency),
  43. * intensity (=volume), and timbre"
  44. * - intensity/volume is currently not handled at all, although the 'dac_additive' driver could do so
  45. * - timbre is handled globally (TODO: only used with the pwm drivers at the moment)
  46. *
  47. * in musical_note.h a 'note' is the combination of a pitch and a duration
  48. * these are used to create SONG arrays; during playback their frequencies
  49. * are handled as single successive tones, while the durations are
  50. * kept track of in 'audio_update_state'
  51. *
  52. * 'voice' as it is used here, equates to a sort of instrument with its own
  53. * characteristics sound and effects
  54. * the audio system as-is deals only with (possibly multiple) tones of one
  55. * instrument/voice at a time (think: chords). since the number of tones that
  56. * can be reproduced depends on the hardware/driver in use: pwm can only
  57. * reproduce one tone per output/speaker; DACs can reproduce/mix multiple
  58. * when doing additive synthesis.
  59. *
  60. * 'duration' can either be in the beats-per-minute related unit found in
  61. * musical_notes.h, OR in ms; keyboards create SONGs with the former, while
  62. * the internal state of the audio system does its calculations with the later - ms
  63. */
  64. #ifndef AUDIO_DEFAULT_ON
  65. # define AUDIO_DEFAULT_ON true
  66. #endif
  67. #ifndef AUDIO_DEFAULT_CLICKY_ON
  68. # define AUDIO_DEFAULT_CLICKY_ON true
  69. #endif
  70. #ifndef AUDIO_TONE_STACKSIZE
  71. # define AUDIO_TONE_STACKSIZE 8
  72. #endif
  73. uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the hardware is able to reproduce at any single time
  74. musical_tone_t tones[AUDIO_TONE_STACKSIZE]; // stack of currently active tones
  75. bool playing_melody = false; // playing a SONG?
  76. bool playing_note = false; // or (possibly multiple simultaneous) tones
  77. bool state_changed = false; // global flag, which is set if anything changes with the active_tones
  78. // melody/SONG related state variables
  79. float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs
  80. uint16_t notes_count; // length of the notes_pointer array
  81. bool notes_repeat; // PLAY_SONG or PLAY_LOOP?
  82. uint16_t melody_current_note_duration = 0; // duration of the currently playing note from the active melody, in ms
  83. uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute
  84. uint16_t current_note = 0; // index into the array at notes_pointer
  85. bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody
  86. uint16_t last_timestamp = 0;
  87. #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING
  88. # ifndef AUDIO_MAX_SIMULTANEOUS_TONES
  89. # define AUDIO_MAX_SIMULTANEOUS_TONES 3
  90. # endif
  91. uint16_t tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT;
  92. uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access
  93. #endif
  94. // provided and used by voices.c
  95. extern uint8_t note_timbre;
  96. extern bool glissando;
  97. extern bool vibrato;
  98. extern uint16_t voices_timer;
  99. #ifndef STARTUP_SONG
  100. # define STARTUP_SONG SONG(STARTUP_SOUND)
  101. #endif
  102. #ifndef AUDIO_ON_SONG
  103. # define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND)
  104. #endif
  105. #ifndef AUDIO_OFF_SONG
  106. # define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND)
  107. #endif
  108. float startup_song[][2] = STARTUP_SONG;
  109. float audio_on_song[][2] = AUDIO_ON_SONG;
  110. float audio_off_song[][2] = AUDIO_OFF_SONG;
  111. static bool audio_initialized = false;
  112. static bool audio_driver_stopped = true;
  113. audio_config_t audio_config;
  114. #ifndef AUDIO_POWER_CONTROL_PIN_ON_STATE
  115. # define AUDIO_POWER_CONTROL_PIN_ON_STATE 1
  116. #endif
  117. void audio_driver_initialize(void) {
  118. #ifdef AUDIO_POWER_CONTROL_PIN
  119. gpio_set_pin_output_push_pull(AUDIO_POWER_CONTROL_PIN);
  120. gpio_write_pin(AUDIO_POWER_CONTROL_PIN, !AUDIO_POWER_CONTROL_PIN_ON_STATE);
  121. #endif
  122. audio_driver_initialize_impl();
  123. }
  124. void audio_driver_stop(void) {
  125. audio_driver_stop_impl();
  126. #ifdef AUDIO_POWER_CONTROL_PIN
  127. gpio_write_pin(AUDIO_POWER_CONTROL_PIN, !AUDIO_POWER_CONTROL_PIN_ON_STATE);
  128. #endif
  129. }
  130. void audio_driver_start(void) {
  131. #ifdef AUDIO_POWER_CONTROL_PIN
  132. gpio_write_pin(AUDIO_POWER_CONTROL_PIN, AUDIO_POWER_CONTROL_PIN_ON_STATE);
  133. #endif
  134. audio_driver_start_impl();
  135. }
  136. void eeconfig_update_audio_current(void) {
  137. eeconfig_update_audio(&audio_config);
  138. }
  139. void eeconfig_update_audio_default(void) {
  140. audio_config.valid = true;
  141. audio_config.enable = AUDIO_DEFAULT_ON;
  142. audio_config.clicky_enable = AUDIO_DEFAULT_CLICKY_ON;
  143. eeconfig_update_audio(&audio_config);
  144. }
  145. void audio_init(void) {
  146. if (audio_initialized) {
  147. return;
  148. }
  149. eeconfig_read_audio(&audio_config);
  150. if (!audio_config.valid) {
  151. dprintf("audio_init audio_config.valid = 0. Write default values to EEPROM.\n");
  152. eeconfig_update_audio_default();
  153. }
  154. for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) {
  155. tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
  156. }
  157. audio_driver_initialize();
  158. audio_initialized = true;
  159. stop_all_notes();
  160. #ifndef AUDIO_INIT_DELAY
  161. audio_startup();
  162. #endif
  163. }
  164. void audio_startup(void) {
  165. if (audio_config.enable) {
  166. PLAY_SONG(startup_song);
  167. }
  168. last_timestamp = timer_read();
  169. }
  170. void audio_toggle(void) {
  171. if (audio_config.enable) {
  172. stop_all_notes();
  173. }
  174. audio_config.enable ^= 1;
  175. eeconfig_update_audio(&audio_config);
  176. if (audio_config.enable) {
  177. audio_on_user();
  178. } else {
  179. audio_off_user();
  180. }
  181. }
  182. void audio_on(void) {
  183. audio_config.enable = 1;
  184. eeconfig_update_audio(&audio_config);
  185. audio_on_user();
  186. PLAY_SONG(audio_on_song);
  187. }
  188. void audio_off(void) {
  189. PLAY_SONG(audio_off_song);
  190. audio_off_user();
  191. wait_ms(100);
  192. audio_stop_all();
  193. audio_config.enable = 0;
  194. eeconfig_update_audio(&audio_config);
  195. }
  196. bool audio_is_on(void) {
  197. return (audio_config.enable != 0);
  198. }
  199. void audio_stop_all(void) {
  200. if (audio_driver_stopped) {
  201. return;
  202. }
  203. active_tones = 0;
  204. audio_driver_stop();
  205. playing_melody = false;
  206. playing_note = false;
  207. melody_current_note_duration = 0;
  208. for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) {
  209. tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
  210. }
  211. audio_driver_stopped = true;
  212. }
  213. void audio_stop_tone(float pitch) {
  214. if (pitch < 0.0f) {
  215. pitch = -1 * pitch;
  216. }
  217. if (playing_note) {
  218. if (!audio_initialized) {
  219. audio_init();
  220. }
  221. bool found = false;
  222. for (int i = AUDIO_TONE_STACKSIZE - 1; i >= 0; i--) {
  223. found = (tones[i].pitch == pitch);
  224. if (found) {
  225. for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) {
  226. tones[j] = tones[j + 1];
  227. }
  228. tones[AUDIO_TONE_STACKSIZE - 1] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
  229. break;
  230. }
  231. }
  232. if (!found) {
  233. return;
  234. }
  235. state_changed = true;
  236. active_tones--;
  237. if (active_tones < 0) active_tones = 0;
  238. #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING
  239. if (tone_multiplexing_index_shift >= active_tones) {
  240. tone_multiplexing_index_shift = 0;
  241. }
  242. #endif
  243. if (active_tones == 0) {
  244. audio_driver_stop();
  245. audio_driver_stopped = true;
  246. playing_note = false;
  247. }
  248. }
  249. }
  250. void audio_play_note(float pitch, uint16_t duration) {
  251. if (!audio_config.enable) {
  252. return;
  253. }
  254. if (!audio_initialized) {
  255. audio_init();
  256. }
  257. if (pitch < 0.0f) {
  258. pitch = -1 * pitch;
  259. }
  260. // round-robin: shifting out old tones, keeping only unique ones
  261. // if the new frequency is already amongst the active tones, shift it to the top of the stack
  262. bool found = false;
  263. for (int i = active_tones - 1; i >= 0; i--) {
  264. found = (tones[i].pitch == pitch);
  265. if (found) {
  266. for (int j = i; (j < active_tones - 1); j++) {
  267. tones[j] = tones[j + 1];
  268. tones[j + 1] = (musical_tone_t){.time_started = timer_read(), .pitch = pitch, .duration = duration};
  269. }
  270. return; // since this frequency played already, the hardware was already started
  271. }
  272. }
  273. // frequency/tone is actually new, so we put it on the top of the stack
  274. active_tones++;
  275. if (active_tones > AUDIO_TONE_STACKSIZE) {
  276. active_tones = AUDIO_TONE_STACKSIZE;
  277. // shift out the oldest tone to make room
  278. for (int i = 0; i < active_tones - 1; i++) {
  279. tones[i] = tones[i + 1];
  280. }
  281. }
  282. state_changed = true;
  283. playing_note = true;
  284. tones[active_tones - 1] = (musical_tone_t){.time_started = timer_read(), .pitch = pitch, .duration = duration};
  285. // TODO: needs to be handled per note/tone -> use its timestamp instead?
  286. voices_timer = timer_read(); // reset to zero, for the effects added by voices.c
  287. if (audio_driver_stopped) {
  288. audio_driver_start();
  289. audio_driver_stopped = false;
  290. }
  291. }
  292. void audio_play_tone(float pitch) {
  293. audio_play_note(pitch, 0xffff);
  294. }
  295. void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) {
  296. if (!audio_config.enable) {
  297. audio_stop_all();
  298. return;
  299. }
  300. if (n_count == 0) {
  301. return;
  302. }
  303. if (!audio_initialized) {
  304. audio_init();
  305. }
  306. // Cancel note if a note is playing
  307. if (playing_note) audio_stop_all();
  308. playing_melody = true;
  309. note_resting = false;
  310. notes_pointer = np;
  311. notes_count = n_count;
  312. notes_repeat = n_repeat;
  313. current_note = 0; // note in the melody-array/list at note_pointer
  314. // start first note manually, which also starts the audio_driver
  315. // all following/remaining notes are played by 'audio_update_state'
  316. audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms((*notes_pointer)[current_note][1]));
  317. last_timestamp = timer_read();
  318. melody_current_note_duration = audio_duration_to_ms((*notes_pointer)[current_note][1]);
  319. }
  320. float click[2][2];
  321. void audio_play_click(uint16_t delay, float pitch, uint16_t duration) {
  322. uint16_t duration_tone = audio_ms_to_duration(duration);
  323. uint16_t duration_delay = audio_ms_to_duration(delay);
  324. if (delay <= 0.0f) {
  325. click[0][0] = pitch;
  326. click[0][1] = duration_tone;
  327. click[1][0] = 0.0f;
  328. click[1][1] = 0.0f;
  329. audio_play_melody(&click, 1, false);
  330. } else {
  331. // first note is a rest/pause
  332. click[0][0] = 0.0f;
  333. click[0][1] = duration_delay;
  334. // second note is the actual click
  335. click[1][0] = pitch;
  336. click[1][1] = duration_tone;
  337. audio_play_melody(&click, 2, false);
  338. }
  339. }
  340. bool audio_is_playing_note(void) {
  341. return playing_note;
  342. }
  343. bool audio_is_playing_melody(void) {
  344. return playing_melody;
  345. }
  346. uint8_t audio_get_number_of_active_tones(void) {
  347. return active_tones;
  348. }
  349. float audio_get_frequency(uint8_t tone_index) {
  350. if (tone_index >= active_tones) {
  351. return 0.0f;
  352. }
  353. return tones[active_tones - tone_index - 1].pitch;
  354. }
  355. float audio_get_processed_frequency(uint8_t tone_index) {
  356. if (tone_index >= active_tones) {
  357. return 0.0f;
  358. }
  359. int8_t index = active_tones - tone_index - 1;
  360. // new tones are stacked on top (= appended at the end), so the most recent/current is MAX-1
  361. #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING
  362. index = index - tone_multiplexing_index_shift;
  363. if (index < 0) // wrap around
  364. index += active_tones;
  365. #endif
  366. if (tones[index].pitch <= 0.0f) {
  367. return 0.0f;
  368. }
  369. return voice_envelope(tones[index].pitch);
  370. }
  371. bool audio_update_state(void) {
  372. if (!playing_note && !playing_melody) {
  373. return false;
  374. }
  375. bool goto_next_note = false;
  376. uint16_t current_time = timer_read();
  377. if (playing_melody) {
  378. goto_next_note = timer_elapsed(last_timestamp) >= melody_current_note_duration;
  379. if (goto_next_note) {
  380. uint16_t delta = timer_elapsed(last_timestamp) - melody_current_note_duration;
  381. last_timestamp = current_time;
  382. uint16_t previous_note = current_note;
  383. current_note++;
  384. voices_timer = timer_read(); // reset to zero, for the effects added by voices.c
  385. if (current_note >= notes_count) {
  386. if (notes_repeat) {
  387. current_note = 0;
  388. } else {
  389. audio_stop_all();
  390. return false;
  391. }
  392. }
  393. if (!note_resting && (*notes_pointer)[previous_note][0] == (*notes_pointer)[current_note][0]) {
  394. note_resting = true;
  395. // special handling for successive notes of the same frequency:
  396. // insert a short pause to separate them audibly
  397. audio_play_note(0.0f, audio_duration_to_ms(2));
  398. current_note = previous_note;
  399. melody_current_note_duration = audio_duration_to_ms(2);
  400. } else {
  401. note_resting = false;
  402. // TODO: handle glissando here (or remember previous and current tone)
  403. /* there would need to be a freq(here we are) -> freq(next note)
  404. * and do slide/glissando in between problem here is to know which
  405. * frequency on the stack relates to what other? e.g. a melody starts
  406. * tones in a sequence, and stops expiring one, so the most recently
  407. * stopped is the starting point for a glissando to the most recently started?
  408. * how to detect and preserve this relation?
  409. * and what about user input, chords, ...?
  410. */
  411. // '- delta': Skip forward in the next note's length if we've over shot
  412. // the last, so the overall length of the song is the same
  413. uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]);
  414. // Skip forward past any completely missed notes
  415. while (delta > duration && current_note < notes_count - 1) {
  416. delta -= duration;
  417. current_note++;
  418. duration = audio_duration_to_ms((*notes_pointer)[current_note][1]);
  419. }
  420. if (delta < duration) {
  421. duration -= delta;
  422. } else {
  423. // Only way to get here is if it is the last note and
  424. // we have completely missed it. Play it for 1ms...
  425. duration = 1;
  426. }
  427. audio_play_note((*notes_pointer)[current_note][0], duration);
  428. melody_current_note_duration = duration;
  429. }
  430. }
  431. }
  432. if (playing_note) {
  433. #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING
  434. tone_multiplexing_index_shift = (int)(current_time / tone_multiplexing_rate) % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones);
  435. goto_next_note = true;
  436. #endif
  437. if (vibrato || glissando) {
  438. // force update on each cycle, since vibrato shifts the frequency slightly
  439. goto_next_note = true;
  440. }
  441. // housekeeping: stop notes that have no playtime left
  442. for (int i = 0; i < active_tones; i++) {
  443. if ((tones[i].duration != 0xffff) // indefinitely playing notes, started by 'audio_play_tone'
  444. && (tones[i].duration != 0) // 'uninitialized'
  445. ) {
  446. if (timer_elapsed(tones[i].time_started) >= tones[i].duration) {
  447. audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true'
  448. }
  449. }
  450. }
  451. }
  452. // state-changes have a higher priority, always triggering the hardware to update
  453. if (state_changed) {
  454. state_changed = false;
  455. return true;
  456. }
  457. return goto_next_note;
  458. }
  459. // Tone-multiplexing functions
  460. #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING
  461. void audio_set_tone_multiplexing_rate(uint16_t rate) {
  462. tone_multiplexing_rate = rate;
  463. }
  464. void audio_enable_tone_multiplexing(void) {
  465. tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT;
  466. }
  467. void audio_disable_tone_multiplexing(void) {
  468. tone_multiplexing_rate = 0;
  469. }
  470. void audio_increase_tone_multiplexing_rate(uint16_t change) {
  471. if ((0xffff - change) > tone_multiplexing_rate) {
  472. tone_multiplexing_rate += change;
  473. }
  474. }
  475. void audio_decrease_tone_multiplexing_rate(uint16_t change) {
  476. if (change <= tone_multiplexing_rate) {
  477. tone_multiplexing_rate -= change;
  478. }
  479. }
  480. #endif
  481. // Tempo functions
  482. void audio_set_tempo(uint8_t tempo) {
  483. if (tempo < 10) note_tempo = 10;
  484. // else if (tempo > 250)
  485. // note_tempo = 250;
  486. else
  487. note_tempo = tempo;
  488. }
  489. void audio_increase_tempo(uint8_t tempo_change) {
  490. if (tempo_change > 255 - note_tempo)
  491. note_tempo = 255;
  492. else
  493. note_tempo += tempo_change;
  494. }
  495. void audio_decrease_tempo(uint8_t tempo_change) {
  496. if (tempo_change >= note_tempo - 10)
  497. note_tempo = 10;
  498. else
  499. note_tempo -= tempo_change;
  500. }
  501. /**
  502. * Converts from units of 1/64ths of a beat to milliseconds.
  503. *
  504. * Round-off error is at most 1 millisecond.
  505. *
  506. * Conversion will never overflow for duration_bpm <= 699, provided that
  507. * note_tempo is at least 10. This is quite a long duration, over ten beats.
  508. *
  509. * Beware that for duration_bpm > 699, the result may overflow uint16_t range
  510. * when duration_bpm is large compared to note_tempo:
  511. *
  512. * duration_bpm * 60 * 1000 / (64 * note_tempo) > UINT16_MAX
  513. *
  514. * duration_bpm > (2 * 65535 / 1875) * note_tempo
  515. * = 69.904 * note_tempo.
  516. */
  517. uint16_t audio_duration_to_ms(uint16_t duration_bpm) {
  518. return ((uint32_t)duration_bpm * 1875) / ((uint_fast16_t)note_tempo * 2);
  519. }
  520. /**
  521. * Converts from units of milliseconds to 1/64ths of a beat.
  522. *
  523. * Round-off error is at most 1/64th of a beat.
  524. *
  525. * This conversion never overflows: since duration_ms <= UINT16_MAX = 65535
  526. * and note_tempo <= 255, the result is always in uint16_t range:
  527. *
  528. * duration_ms * 64 * note_tempo / 60 / 1000
  529. * <= 65535 * 2 * 255 / 1875
  530. * = 17825.52
  531. * <= UINT16_MAX.
  532. */
  533. uint16_t audio_ms_to_duration(uint16_t duration_ms) {
  534. return ((uint32_t)duration_ms * 2 * note_tempo) / 1875;
  535. }
  536. __attribute__((weak)) void audio_on_user(void) {}
  537. __attribute__((weak)) void audio_off_user(void) {}