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.

177 satır
3.8KB

  1. #include "Audio.h"
  2. #include "arm_math.h"
  3. #include "utility/dspinst.h"
  4. /******************************************************************/
  5. // A u d i o E f f e c t C h o r u s
  6. // Written by Pete (El Supremo) Jan 2014
  7. // circular addressing indices for left and right channels
  8. short AudioEffectChorus::l_circ_idx;
  9. short AudioEffectChorus::r_circ_idx;
  10. short * AudioEffectChorus::l_delayline = NULL;
  11. short * AudioEffectChorus::r_delayline = NULL;
  12. int AudioEffectChorus::delay_length;
  13. // An initial value of zero indicates passthru
  14. int AudioEffectChorus::num_chorus = 0;
  15. // All three must be valid.
  16. boolean AudioEffectChorus::begin(short *delayline,int d_length,int n_chorus)
  17. {
  18. Serial.print("AudioEffectChorus.begin(Chorus delay line length = ");
  19. Serial.print(d_length);
  20. Serial.print(", n_chorus = ");
  21. Serial.print(n_chorus);
  22. Serial.println(")");
  23. l_delayline = NULL;
  24. r_delayline = NULL;
  25. delay_length = 0;
  26. l_circ_idx = 0;
  27. r_circ_idx = 0;
  28. if(delayline == NULL) {
  29. return(false);
  30. }
  31. if(d_length < 10) {
  32. return(false);
  33. }
  34. if(n_chorus < 1) {
  35. return(false);
  36. }
  37. l_delayline = delayline;
  38. r_delayline = delayline + d_length/2;
  39. delay_length = d_length/2;
  40. num_chorus = n_chorus;
  41. return(true);
  42. }
  43. // This has the same effect as begin(NULL,0);
  44. void AudioEffectChorus::stop(void)
  45. {
  46. }
  47. void AudioEffectChorus::modify(int n_chorus)
  48. {
  49. num_chorus = n_chorus;
  50. }
  51. int iabs(int x)
  52. {
  53. if(x < 0)return(-x);
  54. return(x);
  55. }
  56. //static int d_count = 0;
  57. int last_idx = 0;
  58. void AudioEffectChorus::update(void)
  59. {
  60. audio_block_t *block;
  61. short *bp;
  62. int sum;
  63. int c_idx;
  64. if(l_delayline == NULL)return;
  65. if(r_delayline == NULL)return;
  66. // do passthru
  67. // It stores the unmodified data in the delay line so that
  68. // it isn't as likely to click
  69. if(num_chorus < 1) {
  70. // Just passthrough
  71. block = receiveWritable(0);
  72. if(block) {
  73. bp = block->data;
  74. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  75. l_circ_idx++;
  76. if(l_circ_idx >= delay_length) {
  77. l_circ_idx = 0;
  78. }
  79. l_delayline[l_circ_idx] = *bp++;
  80. }
  81. transmit(block,0);
  82. release(block);
  83. }
  84. block = receiveWritable(1);
  85. if(block) {
  86. bp = block->data;
  87. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  88. r_circ_idx++;
  89. if(r_circ_idx >= delay_length) {
  90. r_circ_idx = 0;
  91. }
  92. r_delayline[r_circ_idx] = *bp++;
  93. }
  94. transmit(block,1);
  95. release(block);
  96. }
  97. return;
  98. }
  99. // L E F T C H A N N E L
  100. block = receiveWritable(0);
  101. if(block) {
  102. bp = block->data;
  103. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  104. l_circ_idx++;
  105. if(l_circ_idx >= delay_length) {
  106. l_circ_idx = 0;
  107. }
  108. l_delayline[l_circ_idx] = *bp;
  109. sum = 0;
  110. c_idx = l_circ_idx;
  111. for(int k = 0; k < num_chorus; k++) {
  112. sum += l_delayline[c_idx];
  113. if(num_chorus > 1)c_idx -= delay_length/(num_chorus - 1) - 1;
  114. if(c_idx < 0) {
  115. c_idx += delay_length;
  116. }
  117. }
  118. *bp++ = sum/num_chorus;
  119. }
  120. // send the effect output to the left channel
  121. transmit(block,0);
  122. release(block);
  123. }
  124. // R I G H T C H A N N E L
  125. block = receiveWritable(1);
  126. if(block) {
  127. bp = block->data;
  128. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  129. r_circ_idx++;
  130. if(r_circ_idx >= delay_length) {
  131. r_circ_idx = 0;
  132. }
  133. r_delayline[r_circ_idx] = *bp;
  134. sum = 0;
  135. c_idx = r_circ_idx;
  136. for(int k = 0; k < num_chorus; k++) {
  137. sum += r_delayline[c_idx];
  138. if(num_chorus > 1)c_idx -= delay_length/(num_chorus - 1) - 1;
  139. if(c_idx < 0) {
  140. c_idx += delay_length;
  141. }
  142. }
  143. *bp++ = sum/num_chorus;
  144. }
  145. // send the effect output to the left channel
  146. transmit(block,1);
  147. release(block);
  148. }
  149. }