You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

852 lines
24 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. /* Copyright 2016 Jack Humbert
  2. *
  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 <stdio.h>
  17. #include <string.h>
  18. //#include <math.h>
  19. #include <avr/pgmspace.h>
  20. #include <avr/interrupt.h>
  21. #include <avr/io.h>
  22. #include "print.h"
  23. #include "audio.h"
  24. #include "keymap.h"
  25. #include "eeconfig.h"
  26. #define CPU_PRESCALER 8
  27. // -----------------------------------------------------------------------------
  28. // Timer Abstractions
  29. // -----------------------------------------------------------------------------
  30. // TIMSK3 - Timer/Counter #3 Interrupt Mask Register
  31. // Turn on/off 3A interputs, stopping/enabling the ISR calls
  32. #ifdef C6_AUDIO
  33. #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
  34. #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
  35. #endif
  36. #ifdef B5_AUDIO
  37. #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
  38. #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
  39. #endif
  40. #ifdef B6_AUDIO
  41. #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B)
  42. #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B)
  43. #endif
  44. #ifdef B7_AUDIO
  45. #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C)
  46. #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C)
  47. #endif
  48. // TCCR3A: Timer/Counter #3 Control Register
  49. // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
  50. #ifdef C6_AUDIO
  51. #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
  52. #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
  53. #endif
  54. #ifdef B5_AUDIO
  55. #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
  56. #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
  57. #endif
  58. #ifdef B6_AUDIO
  59. #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1);
  60. #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0));
  61. #endif
  62. #ifdef B7_AUDIO
  63. #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1);
  64. #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0));
  65. #endif
  66. // Fast PWM Mode Controls
  67. #ifdef C6_AUDIO
  68. #define TIMER_3_PERIOD ICR3
  69. #define TIMER_3_DUTY_CYCLE OCR3A
  70. #endif
  71. #ifdef B5_AUDIO
  72. #define TIMER_1_PERIOD ICR1
  73. #define TIMER_1_DUTY_CYCLE OCR1A
  74. #endif
  75. #ifdef B6_AUDIO
  76. #define TIMER_1_PERIOD ICR1
  77. #define TIMER_1_DUTY_CYCLE OCR1B
  78. #endif
  79. #ifdef B7_AUDIO
  80. #define TIMER_1_PERIOD ICR1
  81. #define TIMER_1_DUTY_CYCLE OCR1C
  82. #endif
  83. // -----------------------------------------------------------------------------
  84. int voices = 0;
  85. int voice_place = 0;
  86. float frequency = 0;
  87. float frequency_alt = 0;
  88. int volume = 0;
  89. long position = 0;
  90. float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  91. int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  92. bool sliding = false;
  93. float place = 0;
  94. uint8_t * sample;
  95. uint16_t sample_length = 0;
  96. bool playing_notes = false;
  97. bool playing_note = false;
  98. float note_frequency = 0;
  99. float note_length = 0;
  100. uint8_t note_tempo = TEMPO_DEFAULT;
  101. float note_timbre = TIMBRE_DEFAULT;
  102. uint16_t note_position = 0;
  103. float (* notes_pointer)[][2];
  104. uint16_t notes_count;
  105. bool notes_repeat;
  106. bool note_resting = false;
  107. uint8_t current_note = 0;
  108. uint8_t rest_counter = 0;
  109. #ifdef VIBRATO_ENABLE
  110. float vibrato_counter = 0;
  111. float vibrato_strength = .5;
  112. float vibrato_rate = 0.125;
  113. #endif
  114. float polyphony_rate = 0;
  115. static bool audio_initialized = false;
  116. audio_config_t audio_config;
  117. uint16_t envelope_index = 0;
  118. bool glissando = true;
  119. #ifndef STARTUP_SONG
  120. #define STARTUP_SONG SONG(STARTUP_SOUND)
  121. #endif
  122. float startup_song[][2] = STARTUP_SONG;
  123. void audio_init()
  124. {
  125. if (audio_initialized)
  126. return;
  127. // Check EEPROM
  128. if (!eeconfig_is_enabled())
  129. {
  130. eeconfig_init();
  131. }
  132. audio_config.raw = eeconfig_read_audio();
  133. // Set port PC6 (OC3A and /OC4A) as output
  134. #ifdef C6_AUDIO
  135. DDRC |= _BV(PORTC6);
  136. #else
  137. DDRC |= _BV(PORTC6);
  138. PORTC &= ~_BV(PORTC6);
  139. #endif
  140. #ifdef B5_AUDIO
  141. DDRB |= _BV(PORTB5);
  142. #else
  143. DDRB |= _BV(PORTB5);
  144. PORTB &= ~_BV(PORTB5);
  145. #endif
  146. #ifdef B6_AUDIO
  147. DDRB |= _BV(PORTB6);
  148. #else
  149. DDRB |= _BV(PORTB6);
  150. PORTB &= ~_BV(PORTB6);
  151. #endif
  152. #ifdef B7_AUDIO
  153. DDRB |= _BV(PORTB7);
  154. #else
  155. DDRB |= _BV(PORTB7);
  156. PORTB &= ~_BV(PORTB7);
  157. #endif
  158. #ifdef C6_AUDIO
  159. DISABLE_AUDIO_COUNTER_3_ISR;
  160. #endif
  161. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  162. DISABLE_AUDIO_COUNTER_1_ISR;
  163. #endif
  164. // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
  165. // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
  166. // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
  167. // Clock Select (CS3n) = 0b010 = Clock / 8
  168. #ifdef C6_AUDIO
  169. TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
  170. TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
  171. #endif
  172. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  173. TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
  174. TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
  175. #endif
  176. audio_initialized = true;
  177. if (audio_config.enable) {
  178. PLAY_SONG(startup_song);
  179. }
  180. }
  181. void stop_all_notes()
  182. {
  183. dprintf("audio stop all notes");
  184. if (!audio_initialized) {
  185. audio_init();
  186. }
  187. voices = 0;
  188. #ifdef C6_AUDIO
  189. DISABLE_AUDIO_COUNTER_3_ISR;
  190. DISABLE_AUDIO_COUNTER_3_OUTPUT;
  191. #endif
  192. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  193. DISABLE_AUDIO_COUNTER_1_ISR;
  194. DISABLE_AUDIO_COUNTER_1_OUTPUT;
  195. #endif
  196. playing_notes = false;
  197. playing_note = false;
  198. frequency = 0;
  199. frequency_alt = 0;
  200. volume = 0;
  201. for (uint8_t i = 0; i < 8; i++)
  202. {
  203. frequencies[i] = 0;
  204. volumes[i] = 0;
  205. }
  206. }
  207. void stop_note(float freq)
  208. {
  209. dprintf("audio stop note freq=%d", (int)freq);
  210. if (playing_note) {
  211. if (!audio_initialized) {
  212. audio_init();
  213. }
  214. for (int i = 7; i >= 0; i--) {
  215. if (frequencies[i] == freq) {
  216. frequencies[i] = 0;
  217. volumes[i] = 0;
  218. for (int j = i; (j < 7); j++) {
  219. frequencies[j] = frequencies[j+1];
  220. frequencies[j+1] = 0;
  221. volumes[j] = volumes[j+1];
  222. volumes[j+1] = 0;
  223. }
  224. break;
  225. }
  226. }
  227. voices--;
  228. if (voices < 0)
  229. voices = 0;
  230. if (voice_place >= voices) {
  231. voice_place = 0;
  232. }
  233. if (voices == 0) {
  234. #ifdef C6_AUDIO
  235. DISABLE_AUDIO_COUNTER_3_ISR;
  236. DISABLE_AUDIO_COUNTER_3_OUTPUT;
  237. #endif
  238. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  239. DISABLE_AUDIO_COUNTER_1_ISR;
  240. DISABLE_AUDIO_COUNTER_1_OUTPUT;
  241. #endif
  242. frequency = 0;
  243. frequency_alt = 0;
  244. volume = 0;
  245. playing_note = false;
  246. }
  247. }
  248. }
  249. #ifdef VIBRATO_ENABLE
  250. float mod(float a, int b)
  251. {
  252. float r = fmod(a, b);
  253. return r < 0 ? r + b : r;
  254. }
  255. float vibrato(float average_freq) {
  256. #ifdef VIBRATO_STRENGTH_ENABLE
  257. float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
  258. #else
  259. float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
  260. #endif
  261. vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
  262. return vibrated_freq;
  263. }
  264. #endif
  265. #ifdef C6_AUDIO
  266. ISR(TIMER3_COMPA_vect)
  267. {
  268. float freq;
  269. if (playing_note) {
  270. if (voices > 0) {
  271. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  272. float freq_alt = 0;
  273. if (voices > 1) {
  274. if (polyphony_rate == 0) {
  275. if (glissando) {
  276. if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
  277. frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
  278. } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
  279. frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2);
  280. } else {
  281. frequency_alt = frequencies[voices - 2];
  282. }
  283. } else {
  284. frequency_alt = frequencies[voices - 2];
  285. }
  286. #ifdef VIBRATO_ENABLE
  287. if (vibrato_strength > 0) {
  288. freq_alt = vibrato(frequency_alt);
  289. } else {
  290. freq_alt = frequency_alt;
  291. }
  292. #else
  293. freq_alt = frequency_alt;
  294. #endif
  295. }
  296. if (envelope_index < 65535) {
  297. envelope_index++;
  298. }
  299. freq_alt = voice_envelope(freq_alt);
  300. if (freq_alt < 30.517578125) {
  301. freq_alt = 30.52;
  302. }
  303. TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
  304. TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre);
  305. }
  306. #endif
  307. if (polyphony_rate > 0) {
  308. if (voices > 1) {
  309. voice_place %= voices;
  310. if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
  311. voice_place = (voice_place + 1) % voices;
  312. place = 0.0;
  313. }
  314. }
  315. #ifdef VIBRATO_ENABLE
  316. if (vibrato_strength > 0) {
  317. freq = vibrato(frequencies[voice_place]);
  318. } else {
  319. freq = frequencies[voice_place];
  320. }
  321. #else
  322. freq = frequencies[voice_place];
  323. #endif
  324. } else {
  325. if (glissando) {
  326. if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
  327. frequency = frequency * pow(2, 440/frequency/12/2);
  328. } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
  329. frequency = frequency * pow(2, -440/frequency/12/2);
  330. } else {
  331. frequency = frequencies[voices - 1];
  332. }
  333. } else {
  334. frequency = frequencies[voices - 1];
  335. }
  336. #ifdef VIBRATO_ENABLE
  337. if (vibrato_strength > 0) {
  338. freq = vibrato(frequency);
  339. } else {
  340. freq = frequency;
  341. }
  342. #else
  343. freq = frequency;
  344. #endif
  345. }
  346. if (envelope_index < 65535) {
  347. envelope_index++;
  348. }
  349. freq = voice_envelope(freq);
  350. if (freq < 30.517578125) {
  351. freq = 30.52;
  352. }
  353. TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
  354. TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
  355. }
  356. }
  357. if (playing_notes) {
  358. if (note_frequency > 0) {
  359. #ifdef VIBRATO_ENABLE
  360. if (vibrato_strength > 0) {
  361. freq = vibrato(note_frequency);
  362. } else {
  363. freq = note_frequency;
  364. }
  365. #else
  366. freq = note_frequency;
  367. #endif
  368. if (envelope_index < 65535) {
  369. envelope_index++;
  370. }
  371. freq = voice_envelope(freq);
  372. TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
  373. TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
  374. } else {
  375. TIMER_3_PERIOD = 0;
  376. TIMER_3_DUTY_CYCLE = 0;
  377. }
  378. note_position++;
  379. bool end_of_note = false;
  380. if (TIMER_3_PERIOD > 0) {
  381. if (!note_resting)
  382. end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
  383. else
  384. end_of_note = (note_position >= (note_length));
  385. } else {
  386. end_of_note = (note_position >= (note_length));
  387. }
  388. if (end_of_note) {
  389. current_note++;
  390. if (current_note >= notes_count) {
  391. if (notes_repeat) {
  392. current_note = 0;
  393. } else {
  394. DISABLE_AUDIO_COUNTER_3_ISR;
  395. DISABLE_AUDIO_COUNTER_3_OUTPUT;
  396. playing_notes = false;
  397. return;
  398. }
  399. }
  400. if (!note_resting) {
  401. note_resting = true;
  402. current_note--;
  403. if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
  404. note_frequency = 0;
  405. note_length = 1;
  406. } else {
  407. note_frequency = (*notes_pointer)[current_note][0];
  408. note_length = 1;
  409. }
  410. } else {
  411. note_resting = false;
  412. envelope_index = 0;
  413. note_frequency = (*notes_pointer)[current_note][0];
  414. note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
  415. }
  416. note_position = 0;
  417. }
  418. }
  419. if (!audio_config.enable) {
  420. playing_notes = false;
  421. playing_note = false;
  422. }
  423. }
  424. #endif
  425. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  426. ISR(TIMER1_COMPA_vect)
  427. {
  428. #if (defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)) && !defined(C6_AUDIO)
  429. float freq = 0;
  430. if (playing_note) {
  431. if (voices > 0) {
  432. if (polyphony_rate > 0) {
  433. if (voices > 1) {
  434. voice_place %= voices;
  435. if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
  436. voice_place = (voice_place + 1) % voices;
  437. place = 0.0;
  438. }
  439. }
  440. #ifdef VIBRATO_ENABLE
  441. if (vibrato_strength > 0) {
  442. freq = vibrato(frequencies[voice_place]);
  443. } else {
  444. freq = frequencies[voice_place];
  445. }
  446. #else
  447. freq = frequencies[voice_place];
  448. #endif
  449. } else {
  450. if (glissando) {
  451. if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
  452. frequency = frequency * pow(2, 440/frequency/12/2);
  453. } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
  454. frequency = frequency * pow(2, -440/frequency/12/2);
  455. } else {
  456. frequency = frequencies[voices - 1];
  457. }
  458. } else {
  459. frequency = frequencies[voices - 1];
  460. }
  461. #ifdef VIBRATO_ENABLE
  462. if (vibrato_strength > 0) {
  463. freq = vibrato(frequency);
  464. } else {
  465. freq = frequency;
  466. }
  467. #else
  468. freq = frequency;
  469. #endif
  470. }
  471. if (envelope_index < 65535) {
  472. envelope_index++;
  473. }
  474. freq = voice_envelope(freq);
  475. if (freq < 30.517578125) {
  476. freq = 30.52;
  477. }
  478. TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
  479. TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
  480. }
  481. }
  482. if (playing_notes) {
  483. if (note_frequency > 0) {
  484. #ifdef VIBRATO_ENABLE
  485. if (vibrato_strength > 0) {
  486. freq = vibrato(note_frequency);
  487. } else {
  488. freq = note_frequency;
  489. }
  490. #else
  491. freq = note_frequency;
  492. #endif
  493. if (envelope_index < 65535) {
  494. envelope_index++;
  495. }
  496. freq = voice_envelope(freq);
  497. TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
  498. TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
  499. } else {
  500. TIMER_1_PERIOD = 0;
  501. TIMER_1_DUTY_CYCLE = 0;
  502. }
  503. note_position++;
  504. bool end_of_note = false;
  505. if (TIMER_1_PERIOD > 0) {
  506. if (!note_resting)
  507. end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
  508. else
  509. end_of_note = (note_position >= (note_length));
  510. } else {
  511. end_of_note = (note_position >= (note_length));
  512. }
  513. if (end_of_note) {
  514. current_note++;
  515. if (current_note >= notes_count) {
  516. if (notes_repeat) {
  517. current_note = 0;
  518. } else {
  519. DISABLE_AUDIO_COUNTER_1_ISR;
  520. DISABLE_AUDIO_COUNTER_1_OUTPUT;
  521. playing_notes = false;
  522. return;
  523. }
  524. }
  525. if (!note_resting) {
  526. note_resting = true;
  527. current_note--;
  528. if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
  529. note_frequency = 0;
  530. note_length = 1;
  531. } else {
  532. note_frequency = (*notes_pointer)[current_note][0];
  533. note_length = 1;
  534. }
  535. } else {
  536. note_resting = false;
  537. envelope_index = 0;
  538. note_frequency = (*notes_pointer)[current_note][0];
  539. note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
  540. }
  541. note_position = 0;
  542. }
  543. }
  544. if (!audio_config.enable) {
  545. playing_notes = false;
  546. playing_note = false;
  547. }
  548. #endif
  549. }
  550. #endif
  551. void play_note(float freq, int vol) {
  552. dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
  553. if (!audio_initialized) {
  554. audio_init();
  555. }
  556. if (audio_config.enable && voices < 8) {
  557. #ifdef C6_AUDIO
  558. DISABLE_AUDIO_COUNTER_3_ISR;
  559. #endif
  560. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  561. DISABLE_AUDIO_COUNTER_1_ISR;
  562. #endif
  563. // Cancel notes if notes are playing
  564. if (playing_notes)
  565. stop_all_notes();
  566. playing_note = true;
  567. envelope_index = 0;
  568. if (freq > 0) {
  569. frequencies[voices] = freq;
  570. volumes[voices] = vol;
  571. voices++;
  572. }
  573. #ifdef C6_AUDIO
  574. ENABLE_AUDIO_COUNTER_3_ISR;
  575. ENABLE_AUDIO_COUNTER_3_OUTPUT;
  576. #endif
  577. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  578. #ifdef C6_AUDIO
  579. if (voices > 1) {
  580. ENABLE_AUDIO_COUNTER_1_ISR;
  581. ENABLE_AUDIO_COUNTER_1_OUTPUT;
  582. }
  583. #else
  584. ENABLE_AUDIO_COUNTER_1_ISR;
  585. ENABLE_AUDIO_COUNTER_1_OUTPUT;
  586. #endif
  587. #endif
  588. }
  589. }
  590. void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
  591. {
  592. if (!audio_initialized) {
  593. audio_init();
  594. }
  595. if (audio_config.enable) {
  596. #ifdef C6_AUDIO
  597. DISABLE_AUDIO_COUNTER_3_ISR;
  598. #endif
  599. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  600. DISABLE_AUDIO_COUNTER_1_ISR;
  601. #endif
  602. // Cancel note if a note is playing
  603. if (playing_note)
  604. stop_all_notes();
  605. playing_notes = true;
  606. notes_pointer = np;
  607. notes_count = n_count;
  608. notes_repeat = n_repeat;
  609. place = 0;
  610. current_note = 0;
  611. note_frequency = (*notes_pointer)[current_note][0];
  612. note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
  613. note_position = 0;
  614. #ifdef C6_AUDIO
  615. ENABLE_AUDIO_COUNTER_3_ISR;
  616. ENABLE_AUDIO_COUNTER_3_OUTPUT;
  617. #endif
  618. #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)
  619. #ifndef C6_AUDIO
  620. ENABLE_AUDIO_COUNTER_1_ISR;
  621. ENABLE_AUDIO_COUNTER_1_OUTPUT;
  622. #endif
  623. #endif
  624. }
  625. }
  626. bool is_playing_notes(void) {
  627. return playing_notes;
  628. }
  629. bool is_audio_on(void) {
  630. return (audio_config.enable != 0);
  631. }
  632. void audio_toggle(void) {
  633. audio_config.enable ^= 1;
  634. eeconfig_update_audio(audio_config.raw);
  635. if (audio_config.enable)
  636. audio_on_user();
  637. }
  638. void audio_on(void) {
  639. audio_config.enable = 1;
  640. eeconfig_update_audio(audio_config.raw);
  641. audio_on_user();
  642. }
  643. void audio_off(void) {
  644. audio_config.enable = 0;
  645. eeconfig_update_audio(audio_config.raw);
  646. }
  647. #ifdef VIBRATO_ENABLE
  648. // Vibrato rate functions
  649. void set_vibrato_rate(float rate) {
  650. vibrato_rate = rate;
  651. }
  652. void increase_vibrato_rate(float change) {
  653. vibrato_rate *= change;
  654. }
  655. void decrease_vibrato_rate(float change) {
  656. vibrato_rate /= change;
  657. }
  658. #ifdef VIBRATO_STRENGTH_ENABLE
  659. void set_vibrato_strength(float strength) {
  660. vibrato_strength = strength;
  661. }
  662. void increase_vibrato_strength(float change) {
  663. vibrato_strength *= change;
  664. }
  665. void decrease_vibrato_strength(float change) {
  666. vibrato_strength /= change;
  667. }
  668. #endif /* VIBRATO_STRENGTH_ENABLE */
  669. #endif /* VIBRATO_ENABLE */
  670. // Polyphony functions
  671. void set_polyphony_rate(float rate) {
  672. polyphony_rate = rate;
  673. }
  674. void enable_polyphony() {
  675. polyphony_rate = 5;
  676. }
  677. void disable_polyphony() {
  678. polyphony_rate = 0;
  679. }
  680. void increase_polyphony_rate(float change) {
  681. polyphony_rate *= change;
  682. }
  683. void decrease_polyphony_rate(float change) {
  684. polyphony_rate /= change;
  685. }
  686. // Timbre function
  687. void set_timbre(float timbre) {
  688. note_timbre = timbre;
  689. }
  690. // Tempo functions
  691. void set_tempo(uint8_t tempo) {
  692. note_tempo = tempo;
  693. }
  694. void decrease_tempo(uint8_t tempo_change) {
  695. note_tempo += tempo_change;
  696. }
  697. void increase_tempo(uint8_t tempo_change) {
  698. if (note_tempo - tempo_change < 10) {
  699. note_tempo = 10;
  700. } else {
  701. note_tempo -= tempo_change;
  702. }
  703. }