beeps.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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 loop() {
  153. }
  154. // ISR(TIMER1_COMPA_vect)
  155. // {
  156. // // if (i<(sizeof(wave)/sizeof(int))) //don't exceed ends of vector... sizeof(wave)
  157. // if (i<pow(2, 10)) //don't exceed ends of vector... sizeof(wave)
  158. // {
  159. // OCR3A = (int)((float)wave[i]*ICR3/RANGE); //go to next array element
  160. // // int x = 1;
  161. // // int y = 5;
  162. // // OCR3A = (int) (round(sin(i*440*pow(2, x/12.0))*.5+.5 + sin(i*440*pow(2, y/12.0))*.5+.5) / 2 * ICR3);
  163. // i++; //increment
  164. // }
  165. // else i=0; //reset
  166. // }
  167. void play_note(double freq, int vol) {
  168. if (freq > 0) {
  169. DDRC |= (1<<6);
  170. TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
  171. TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
  172. if (frequency != 0) {
  173. if (frequency < freq) {
  174. for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
  175. send_freq(f, vol);
  176. }
  177. } else if (frequency > freq) {
  178. for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
  179. send_freq(f, vol);
  180. }
  181. }
  182. }
  183. send_freq(freq, vol);
  184. frequency = freq;
  185. volume = vol;
  186. frequencies[voices] = frequency;
  187. volumes[voices] = volume;
  188. voices++;
  189. }
  190. // ICR3 = 0xFFFF;
  191. // for (int i = 0; i < 10000; i++) {
  192. // OCR3A = round((sin(i*freq)*.5)+.5)*0xFFFF;
  193. // // _delay_us(50);
  194. // }
  195. // TCCR3A = 0;
  196. // TCCR3B = 0;
  197. }
  198. void note(int x, float length) {
  199. DDRC |= (1<<6);
  200. int t = (int)(440*pow(2,-x/12.0)); // starting note
  201. for (int y = 0; y < length*1000/t; y++) { // note length
  202. PORTC |= (1<<6);
  203. delay_us(t);
  204. PORTC &= ~(1<<6);
  205. delay_us(t);
  206. }
  207. PORTC &= ~(1<<6);
  208. }
  209. void true_note(float x, float y, float length) {
  210. for (uint32_t i = 0; i < length * 50; i++) {
  211. 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));
  212. for (int u = 0; u < 8; u++) {
  213. if (v & (1 << u) && !(PORTC&(1<<6)))
  214. PORTC |= (1<<6);
  215. else if (PORTC&(1<<6))
  216. PORTC &= ~(1<<6);
  217. }
  218. }
  219. PORTC &= ~(1<<6);
  220. }