Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

320 lines
8.5KB

  1. /*
  2. Change the chorus code to produce a flange effect
  3. PROC/MEM 25/4
  4. 140204
  5. d
  6. - fixed the problem with user-supplied delay line
  7. 140203
  8. c
  9. 140203
  10. b
  11. - when switching to/from passthru, keep the delay line filled
  12. BUT to be effective must also fix up begin and add another
  13. function to allow changing to/from passthru without
  14. reinitialing everything.
  15. I have mixed up the names "chorus" and flange". The sketches named
  16. chorus have, up to version 'm', actually implemented a flanger.
  17. From version 'o' onwards the sketches named chorus will implement
  18. a real chorus effect and flange will do a flanging effect.
  19. 140202
  20. a
  21. Modify filter_test_f to try out a chorus effect
  22. m + n only changed the effect parameters
  23. -
  24. 140201
  25. l - found the problem at last using my_flange_cd_usd_c
  26. YES! Way back when I found I hadn't been using d_depth. Now I
  27. have just discovered that I haven't been using delay_offset!!!!!
  28. 140201
  29. k
  30. interpolation doesn't remove the ticking
  31. 140131
  32. j
  33. >>> The lower the frequency, the less ticking.
  34. - try interpolation
  35. 140201
  36. - got this restored to the way it was last night
  37. and then reinstated the changes. I had a couple of
  38. changes to the right channel that were incorrect or
  39. weren't carried over from the left channel changes
  40. i
  41. - don't know why but this version seems to have more "presence"
  42. than previous versions.
  43. The presence occurred when "sign = 1" was put in front of the left.
  44. It essentially makes it a passthrough.
  45. If both have "sign=1" then it is identical to passthrough
  46. Ticking is still not fixed
  47. h
  48. - add sign reversal. It seems to make audio much clearer
  49. BUT it hasn't got rid of the ticking noise
  50. g
  51. - I wasn't even using delay_depth!!!!
  52. 140131
  53. f
  54. - added code to print the processor and memory usage every 5 seconds
  55. NOW the problem is to try to remove the ticking
  56. e
  57. FOUND the problem with the right channel. It was also in the left channel
  58. but the placement of the delay line arrays made it more noticeable in the
  59. right channel. I was not calculating idx properly. In particular, the
  60. resuling index could be negative.
  61. I have shortened the delay line to only 2*AUDIO_BLOCK_SAMPLES
  62. - removed redundancies in the update code. rewrite the block
  63. instead of getting a new one
  64. Haven't solved the noise in the right channel yet.
  65. Tried duplicating right channel code to left but noise stays on the right
  66. 140130
  67. d
  68. The noise stays in the right channel even if it is calculated first
  69. Switching the L/R inputs doesn't switch the noise to the left channel
  70. c
  71. >> Now add a sinusoidal modulation to the offset
  72. There's an awful noise in both channels but it is much louder in
  73. the right channel. NOPE - it is ONLY in the right channel
  74. but the audio does sound like it is working (sort of) except that it
  75. is rather tinny. Maybe it needs to have the interpolation added.
  76. b
  77. - this works with clip16_6s.wav.
  78. The original of this audio file was from http://www.donreiman.com/Chorus/Chorus.htm
  79. I reworked it with Goldwave to make it a stereo WAV file
  80. But with Rick Wakewan's Jane Seymour it seems to act more like
  81. a high-pass filter.
  82. a
  83. - removed FIR stuff and changed the name to AudioEffectChorus
  84. it's basically a blank template and compiles.
  85. From: http://www.cs.cf.ac.uk/Dave/CM0268/PDF/10_CM0268_Audio_FX.pdf
  86. about Comb filter effects
  87. Effect Delay range (ms) Modulation
  88. Resonator 0 - 20 None
  89. Flanger 0 - 15 Sinusoidal (approx 1Hz)
  90. Chorus 25 - 50 None
  91. Echo >50 None
  92. FMI:
  93. The audio board uses the following pins.
  94. 6 - MEMCS
  95. 7 - MOSI
  96. 9 - BCLK
  97. 10 - SDCS
  98. 11 - MCLK
  99. 12 - MISO
  100. 13 - RX
  101. 14 - SCLK
  102. 15 - VOL
  103. 18 - SDA
  104. 19 - SCL
  105. 22 - TX
  106. 23 - LRCLK
  107. AudioProcessorUsage()
  108. AudioProcessorUsageMax()
  109. AudioProcessorUsageMaxReset()
  110. AudioMemoryUsage()
  111. AudioMemoryUsageMax()
  112. AudioMemoryUsageMaxReset()
  113. The CPU usage is an integer from 0 to 100, and the memory is from 0 to however
  114. many blocks you provided with AudioMemory().
  115. */
  116. #include <arm_math.h>
  117. #include <Audio.h>
  118. #include <Wire.h>
  119. //#include <WM8731.h>
  120. #include <SD.h>
  121. #include <SPI.h>
  122. #include <Bounce.h>
  123. // Number of samples in ONE channel
  124. #define FLANGE_DELAY_LENGTH (6*AUDIO_BLOCK_SAMPLES)
  125. // Allocate the delay line for left and right channels
  126. // The delayline will hold left and right samples so it
  127. // should be declared to be twice as long as the desired
  128. // number of samples in one channel
  129. #define FLANGE_DELAYLINE (FLANGE_DELAY_LENGTH*2)
  130. // The delay line for left and right channels
  131. short delayline[FLANGE_DELAYLINE];
  132. // If this pin is grounded the FIR filter is turned which
  133. // makes just pass through the audio
  134. // Don't use any of the pins listed above
  135. #define PASSTHRU_PIN 1
  136. Bounce b_passthru = Bounce(PASSTHRU_PIN,15);
  137. //const int myInput = AUDIO_INPUT_MIC;
  138. const int myInput = AUDIO_INPUT_LINEIN;
  139. AudioInputI2S audioInput; // audio shield: mic or line-in
  140. AudioEffectFlange myEffect;
  141. AudioOutputI2S audioOutput; // audio shield: headphones & line-out
  142. // Create Audio connections between the components
  143. // Both channels of the audio input go to the FIR filter
  144. AudioConnection c1(audioInput, 0, myEffect, 0);
  145. AudioConnection c2(audioInput, 1, myEffect, 1);
  146. // both channels from the FIR filter go to the audio output
  147. AudioConnection c3(myEffect, 0, audioOutput, 0);
  148. AudioConnection c4(myEffect, 1, audioOutput, 1);
  149. AudioControlSGTL5000 audioShield;
  150. /*
  151. int s_idx = FLANGE_DELAY_LENGTH/2;
  152. int s_depth = FLANGE_DELAY_LENGTH/16;
  153. double s_freq = 1;
  154. // <<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
  155. // 12
  156. int s_idx = FLANGE_DELAY_LENGTH/2;
  157. int s_depth = FLANGE_DELAY_LENGTH/8;
  158. double s_freq = .125;
  159. // with .125 the ticking is about 1Hz with music
  160. // but with the noise sample it is a bit slower than that
  161. // <<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
  162. */
  163. /*
  164. // <<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
  165. // 12
  166. int s_idx = FLANGE_DELAY_LENGTH/2;
  167. int s_depth = FLANGE_DELAY_LENGTH/12;
  168. double s_freq = .125;
  169. // with .125 the ticking is about 1Hz with music
  170. // but with the noise sample it is a bit slower than that
  171. // <<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
  172. */
  173. /*
  174. //12
  175. int s_idx = 15*FLANGE_DELAY_LENGTH/16;
  176. int s_depth = 15*FLANGE_DELAY_LENGTH/16;
  177. double s_freq = 0;
  178. */
  179. /*
  180. //12
  181. int s_idx = 2*FLANGE_DELAY_LENGTH/4;
  182. int s_depth = FLANGE_DELAY_LENGTH/8;
  183. double s_freq = .0625;
  184. */
  185. //12 - good with Eric Clapton Unplugged
  186. /*
  187. int s_idx = 3*FLANGE_DELAY_LENGTH/4;
  188. int s_depth = FLANGE_DELAY_LENGTH/8;
  189. double s_freq = .0625;
  190. */
  191. int s_idx = FLANGE_DELAY_LENGTH/4;
  192. int s_depth = FLANGE_DELAY_LENGTH/4;
  193. double s_freq = .5;
  194. void setup() {
  195. Serial.begin(9600);
  196. while (!Serial) ;
  197. delay(3000);
  198. pinMode(PASSTHRU_PIN,INPUT_PULLUP);
  199. // It doesn't work properly with any less than 8
  200. // but that was an earlier version. Processor and
  201. // memory usage are now (ver j)
  202. // Proc = 24 (24), Mem = 4 (4)
  203. AudioMemory(8);
  204. audioShield.enable();
  205. audioShield.inputSelect(myInput);
  206. audioShield.volume(50);
  207. // Warn that the passthru pin is grounded
  208. if(!digitalRead(PASSTHRU_PIN)) {
  209. Serial.print("PASSTHRU_PIN (");
  210. Serial.print(PASSTHRU_PIN);
  211. Serial.println(") is grounded");
  212. }
  213. // Set up the flange effect
  214. // address of delayline
  215. // total number of samples (left AND right) in the delay line
  216. // Index (in samples) into the delay line for the added voice
  217. // Depth of the flange effect
  218. // frequency of the flange effect
  219. myEffect.begin(delayline,FLANGE_DELAYLINE,s_idx,s_depth,s_freq);
  220. // I want output on the line out too
  221. audioShield.unmuteLineout();
  222. Serial.println("setup done");
  223. AudioProcessorUsageMaxReset();
  224. AudioMemoryUsageMaxReset();
  225. }
  226. // audio volume
  227. int volume = 0;
  228. unsigned long last_time = millis();
  229. void loop()
  230. {
  231. // Volume control
  232. int n = analogRead(15);
  233. if (n != volume) {
  234. volume = n;
  235. audioShield.volume((float)n / 10.23);
  236. }
  237. if(1) {
  238. if(millis() - last_time >= 5000) {
  239. Serial.print("Proc = ");
  240. Serial.print(AudioProcessorUsage());
  241. Serial.print(" (");
  242. Serial.print(AudioProcessorUsageMax());
  243. Serial.print("), Mem = ");
  244. Serial.print(AudioMemoryUsage());
  245. Serial.print(" (");
  246. Serial.print(AudioMemoryUsageMax());
  247. Serial.println(")");
  248. last_time = millis();
  249. }
  250. }
  251. // update the button
  252. b_passthru.update();
  253. // If the passthru button is pushed, save the current
  254. // filter index and then switch the filter to passthru
  255. if(b_passthru.fallingEdge()) {
  256. myEffect.modify(DELAY_PASSTHRU,0,0);
  257. }
  258. // If passthru button is released, restore the effect
  259. if(b_passthru.risingEdge()) {
  260. myEffect.modify(s_idx,s_depth,s_freq);
  261. }
  262. }