Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

196 lines
4.9KB

  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2014, Pete (El Supremo)
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. * THE SOFTWARE.
  21. */
  22. #include "effect_chorus.h"
  23. /******************************************************************/
  24. // A u d i o E f f e c t C h o r u s
  25. // Written by Pete (El Supremo) Jan 2014
  26. // circular addressing indices for left and right channels
  27. short AudioEffectChorus::l_circ_idx;
  28. short AudioEffectChorus::r_circ_idx;
  29. short * AudioEffectChorus::l_delayline = NULL;
  30. short * AudioEffectChorus::r_delayline = NULL;
  31. int AudioEffectChorus::delay_length;
  32. // An initial value of zero indicates passthru
  33. int AudioEffectChorus::num_chorus = 0;
  34. // All three must be valid.
  35. boolean AudioEffectChorus::begin(short *delayline,int d_length,int n_chorus)
  36. {
  37. Serial.print("AudioEffectChorus.begin(Chorus delay line length = ");
  38. Serial.print(d_length);
  39. Serial.print(", n_chorus = ");
  40. Serial.print(n_chorus);
  41. Serial.println(")");
  42. l_delayline = NULL;
  43. r_delayline = NULL;
  44. delay_length = 0;
  45. l_circ_idx = 0;
  46. r_circ_idx = 0;
  47. if(delayline == NULL) {
  48. return(false);
  49. }
  50. if(d_length < 10) {
  51. return(false);
  52. }
  53. if(n_chorus < 1) {
  54. return(false);
  55. }
  56. l_delayline = delayline;
  57. r_delayline = delayline + d_length/2;
  58. delay_length = d_length/2;
  59. num_chorus = n_chorus;
  60. return(true);
  61. }
  62. // This has the same effect as begin(NULL,0);
  63. void AudioEffectChorus::stop(void)
  64. {
  65. }
  66. void AudioEffectChorus::modify(int n_chorus)
  67. {
  68. num_chorus = n_chorus;
  69. }
  70. int iabs(int x)
  71. {
  72. if(x < 0)return(-x);
  73. return(x);
  74. }
  75. //static int d_count = 0;
  76. int last_idx = 0;
  77. void AudioEffectChorus::update(void)
  78. {
  79. audio_block_t *block;
  80. short *bp;
  81. int sum;
  82. int c_idx;
  83. if(l_delayline == NULL)return;
  84. if(r_delayline == NULL)return;
  85. // do passthru
  86. // It stores the unmodified data in the delay line so that
  87. // it isn't as likely to click
  88. if(num_chorus < 1) {
  89. // Just passthrough
  90. block = receiveWritable(0);
  91. if(block) {
  92. bp = block->data;
  93. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  94. l_circ_idx++;
  95. if(l_circ_idx >= delay_length) {
  96. l_circ_idx = 0;
  97. }
  98. l_delayline[l_circ_idx] = *bp++;
  99. }
  100. transmit(block,0);
  101. release(block);
  102. }
  103. block = receiveWritable(1);
  104. if(block) {
  105. bp = block->data;
  106. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  107. r_circ_idx++;
  108. if(r_circ_idx >= delay_length) {
  109. r_circ_idx = 0;
  110. }
  111. r_delayline[r_circ_idx] = *bp++;
  112. }
  113. transmit(block,1);
  114. release(block);
  115. }
  116. return;
  117. }
  118. // L E F T C H A N N E L
  119. block = receiveWritable(0);
  120. if(block) {
  121. bp = block->data;
  122. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  123. l_circ_idx++;
  124. if(l_circ_idx >= delay_length) {
  125. l_circ_idx = 0;
  126. }
  127. l_delayline[l_circ_idx] = *bp;
  128. sum = 0;
  129. c_idx = l_circ_idx;
  130. for(int k = 0; k < num_chorus; k++) {
  131. sum += l_delayline[c_idx];
  132. if(num_chorus > 1)c_idx -= delay_length/(num_chorus - 1) - 1;
  133. if(c_idx < 0) {
  134. c_idx += delay_length;
  135. }
  136. }
  137. *bp++ = sum/num_chorus;
  138. }
  139. // send the effect output to the left channel
  140. transmit(block,0);
  141. release(block);
  142. }
  143. // R I G H T C H A N N E L
  144. block = receiveWritable(1);
  145. if(block) {
  146. bp = block->data;
  147. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  148. r_circ_idx++;
  149. if(r_circ_idx >= delay_length) {
  150. r_circ_idx = 0;
  151. }
  152. r_delayline[r_circ_idx] = *bp;
  153. sum = 0;
  154. c_idx = r_circ_idx;
  155. for(int k = 0; k < num_chorus; k++) {
  156. sum += r_delayline[c_idx];
  157. if(num_chorus > 1)c_idx -= delay_length/(num_chorus - 1) - 1;
  158. if(c_idx < 0) {
  159. c_idx += delay_length;
  160. }
  161. }
  162. *bp++ = sum/num_chorus;
  163. }
  164. // send the effect output to the left channel
  165. transmit(block,1);
  166. release(block);
  167. }
  168. }