beeps.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "beeps.h"
  2. #include <math.h>
  3. #include <avr/pgmspace.h>
  4. #include <avr/interrupt.h>
  5. #include <avr/io.h>
  6. #define PI 3.14159265
  7. void delay_us(int count) {
  8. while(count--) {
  9. _delay_us(1);
  10. }
  11. }
  12. int voices = 0;
  13. double frequency = 0;
  14. int volume = 0;
  15. int position = 0;
  16. double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  17. int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  18. bool sliding = false;
  19. #define RANGE 1000
  20. volatile int i=0; //elements of the wave
  21. void beeps() {
  22. play_notes();
  23. }
  24. void send_freq(double freq, int vol) {
  25. int duty = (((double)F_CPU) / freq);
  26. ICR3 = duty; // Set max to the period
  27. OCR3A = duty >> (0x10 - vol); // Set compare to half the period
  28. }
  29. void stop_all_notes() {
  30. voices = 0;
  31. TCCR3A = 0;
  32. TCCR3B = 0;
  33. frequency = 0;
  34. volume = 0;
  35. for (int i = 0; i < 8; i++) {
  36. frequencies[i] = 0;
  37. volumes[i] = 0;
  38. }
  39. }
  40. void stop_note(double freq) {
  41. for (int i = 7; i >= 0; i--) {
  42. if (frequencies[i] == freq) {
  43. frequencies[i] = 0;
  44. volumes[i] = 0;
  45. for (int j = i; (j < 7); j++) {
  46. frequencies[j] = frequencies[j+1];
  47. frequencies[j+1] = 0;
  48. volumes[j] = volumes[j+1];
  49. volumes[j+1] = 0;
  50. }
  51. }
  52. }
  53. voices--;
  54. if (voices < 0)
  55. voices = 0;
  56. if (voices == 0) {
  57. TCCR3A = 0;
  58. TCCR3B = 0;
  59. frequency = 0;
  60. volume = 0;
  61. } else {
  62. double freq = frequencies[voices - 1];
  63. int vol = volumes[voices - 1];
  64. if (frequency < freq) {
  65. sliding = true;
  66. for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
  67. send_freq(f, vol);
  68. }
  69. sliding = false;
  70. } else if (frequency > freq) {
  71. sliding = true;
  72. for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
  73. send_freq(f, vol);
  74. }
  75. sliding = false;
  76. }
  77. send_freq(freq, vol);
  78. frequency = freq;
  79. volume = vol;
  80. }
  81. }
  82. void init_notes() {
  83. // TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (1 << WGM10);
  84. // TCCR1B = (1 << COM1B1) | (0 << COM1A0) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
  85. // DDRC |= (1<<6);
  86. // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
  87. // TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
  88. // ICR3 = 0xFFFF;
  89. // OCR3A = (int)((float)wave[i]*ICR3/RANGE); //go to next array element
  90. // cli();
  91. // /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz,
  92. // this gives a timer interrupt at 15625Hz. */
  93. // TIMSK3 = (1 << OCIE3A);
  94. // /* clear/reset timer on match */
  95. // // TCCR3A = 1<<WGM31 | 0<<WGM30; CTC mode, reset on match
  96. // // TCCR3B = 0<<CS32 | 1<<CS31 | 0<<CS30; /* clk, /8 prescaler */
  97. // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
  98. // TCCR3B = (0 << WGM33) | (0 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
  99. // TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
  100. // TCCR1B = (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
  101. // // SPCR = 0x50;
  102. // // SPSR = 0x01;
  103. // DDRC |= (1<<6);
  104. // // ICR3 = 0xFFFF;
  105. // // OCR3A=80;
  106. // PORTC |= (1<<6);
  107. // sei();
  108. }
  109. // #define highByte(c) ((c >> 8) & 0x00FF)
  110. // #define lowByte(c) (c & 0x00FF)
  111. ISR(TIMER3_COMPA_vect) {
  112. if (ICR3 > 0 && !sliding) {
  113. switch (position) {
  114. case 0: {
  115. int duty = (((double)F_CPU) / (frequency));
  116. ICR3 = duty; // Set max to the period
  117. OCR3A = duty >> 1; // Set compare to half the period
  118. break;
  119. }
  120. case 1: {
  121. int duty = (((double)F_CPU) / (frequency*2));
  122. ICR3 = duty; // Set max to the period
  123. OCR3A = duty >> 1; // Set compare to half the period
  124. break;
  125. }
  126. case 2: {
  127. int duty = (((double)F_CPU) / (frequency*3));
  128. ICR3 = duty; // Set max to the period
  129. OCR3A = duty >> 1; // Set compare to half the period
  130. break;
  131. }
  132. }
  133. position = (position + 1) % 3;
  134. }
  135. // /* OCR2A has been cleared, per TCCR2A above */
  136. // // OCR3A = 127;
  137. // // pos1 += incr1;
  138. // // pos2 += incr2;
  139. // // pos3 += incr3;
  140. // // sample = sinewave[highByte(pos1)] + sinewave[highByte(pos2)] + sinewave[highByte(pos3)];
  141. // // OCR3A = sample;
  142. // OCR3A=pgm_read_byte(&sinewave[pos1]);
  143. // pos1++;
  144. // // PORTC &= ~(1<<6);
  145. // /* buffered, 1x gain, active mode */
  146. // // SPDR = highByte(sample) | 0x70;
  147. // // while (!(SPSR & (1<<SPIF)));
  148. // // SPDR = lowByte(sample);
  149. // // while (!(SPSR & (1<<SPIF)));
  150. // // PORTC |= (1<<6);
  151. }
  152. void play_note(double freq, int vol) {
  153. if (freq > 0) {
  154. DDRC |= (1<<6);
  155. TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
  156. TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
  157. if (frequency != 0) {
  158. if (frequency < freq) {
  159. for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
  160. send_freq(f, vol);
  161. }
  162. } else if (frequency > freq) {
  163. for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
  164. send_freq(f, vol);
  165. }
  166. }
  167. }
  168. send_freq(freq, vol);
  169. frequency = freq;
  170. volume = vol;
  171. frequencies[voices] = frequency;
  172. volumes[voices] = volume;
  173. voices++;
  174. }
  175. // ICR3 = 0xFFFF;
  176. // for (int i = 0; i < 10000; i++) {
  177. // OCR3A = round((sin(i*freq)*.5)+.5)*0xFFFF;
  178. // // _delay_us(50);
  179. // }
  180. // TCCR3A = 0;
  181. // TCCR3B = 0;
  182. }
  183. // void note(int x, float length) {
  184. // DDRC |= (1<<6);
  185. // int t = (int)(440*pow(2,-x/12.0)); // starting note
  186. // for (int y = 0; y < length*1000/t; y++) { // note length
  187. // PORTC |= (1<<6);
  188. // delay_us(t);
  189. // PORTC &= ~(1<<6);
  190. // delay_us(t);
  191. // }
  192. // PORTC &= ~(1<<6);
  193. // }
  194. // void true_note(float x, float y, float length) {
  195. // for (uint32_t i = 0; i < length * 50; i++) {
  196. // uint32_t v = (uint32_t) (round(sin(PI*2*i*640000*pow(2, x/12.0))*.5+1 + sin(PI*2*i*640000*pow(2, y/12.0))*.5+1) / 2 * pow(2, 8));
  197. // for (int u = 0; u < 8; u++) {
  198. // if (v & (1 << u) && !(PORTC&(1<<6)))
  199. // PORTC |= (1<<6);
  200. // else if (PORTC&(1<<6))
  201. // PORTC &= ~(1<<6);
  202. // }
  203. // }
  204. // PORTC &= ~(1<<6);
  205. // }