Audio plugin host https://kx.studio/carla
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.

Echo.cpp 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Echo.cpp - Echo effect
  4. Copyright (C) 2002-2005 Nasca Octavian Paul
  5. Copyright (C) 2009-2010 Mark McCurry
  6. Author: Nasca Octavian Paul
  7. Mark McCurry
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of version 2 of the GNU General Public License
  10. as published by the Free Software Foundation.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License (version 2 or later) for more details.
  15. You should have received a copy of the GNU General Public License (version 2)
  16. along with this program; if not, write to the Free Software Foundation,
  17. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <cmath>
  20. #include "Echo.h"
  21. #define MAX_DELAY 2
  22. Echo::Echo(bool insertion_, float *efxoutl_, float *efxoutr_, unsigned int srate, int bufsize)
  23. :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0, srate, bufsize),
  24. Pvolume(50),
  25. Pdelay(60),
  26. Plrdelay(100),
  27. Pfb(40),
  28. Phidamp(60),
  29. delayTime(1),
  30. lrdelay(0),
  31. avgDelay(0),
  32. delay(new float[(int)(MAX_DELAY * srate)],
  33. new float[(int)(MAX_DELAY * srate)]),
  34. old(0.0f),
  35. pos(0),
  36. delta(1),
  37. ndelta(1)
  38. {
  39. initdelays();
  40. setpreset(Ppreset);
  41. }
  42. Echo::~Echo()
  43. {
  44. delete[] delay.l;
  45. delete[] delay.r;
  46. }
  47. //Cleanup the effect
  48. void Echo::cleanup(void)
  49. {
  50. memset(delay.l, 0, MAX_DELAY * samplerate * sizeof(float));
  51. memset(delay.r, 0, MAX_DELAY * samplerate * sizeof(float));
  52. old = Stereo<float>(0.0f);
  53. }
  54. inline int max(int a, int b)
  55. {
  56. return a > b ? a : b;
  57. }
  58. //Initialize the delays
  59. void Echo::initdelays(void)
  60. {
  61. cleanup();
  62. //number of seconds to delay left chan
  63. float dl = avgDelay - lrdelay;
  64. //number of seconds to delay right chan
  65. float dr = avgDelay + lrdelay;
  66. ndelta.l = max(1, (int) (dl * samplerate));
  67. ndelta.r = max(1, (int) (dr * samplerate));
  68. }
  69. //Effect output
  70. void Echo::out(const Stereo<float *> &input)
  71. {
  72. for(int i = 0; i < buffersize; ++i) {
  73. float ldl = delay.l[pos.l];
  74. float rdl = delay.r[pos.r];
  75. ldl = ldl * (1.0f - lrcross) + rdl * lrcross;
  76. rdl = rdl * (1.0f - lrcross) + ldl * lrcross;
  77. efxoutl[i] = ldl * 2.0f;
  78. efxoutr[i] = rdl * 2.0f;
  79. ldl = input.l[i] * pangainL - ldl * fb;
  80. rdl = input.r[i] * pangainR - rdl * fb;
  81. //LowPass Filter
  82. old.l = delay.l[(pos.l + delta.l) % (MAX_DELAY * samplerate)] =
  83. ldl * hidamp + old.l * (1.0f - hidamp);
  84. old.r = delay.r[(pos.r + delta.r) % (MAX_DELAY * samplerate)] =
  85. rdl * hidamp + old.r * (1.0f - hidamp);
  86. //increment
  87. ++pos.l; // += delta.l;
  88. ++pos.r; // += delta.r;
  89. //ensure that pos is still in bounds
  90. pos.l %= MAX_DELAY * samplerate;
  91. pos.r %= MAX_DELAY * samplerate;
  92. //adjust delay if needed
  93. delta.l = (15 * delta.l + ndelta.l) / 16;
  94. delta.r = (15 * delta.r + ndelta.r) / 16;
  95. }
  96. }
  97. //Parameter control
  98. void Echo::setvolume(unsigned char _Pvolume)
  99. {
  100. Pvolume = _Pvolume;
  101. if(insertion == 0) {
  102. outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
  103. volume = 1.0f;
  104. }
  105. else
  106. volume = outvolume = Pvolume / 127.0f;
  107. if(Pvolume == 0)
  108. cleanup();
  109. }
  110. void Echo::setdelay(unsigned char _Pdelay)
  111. {
  112. Pdelay = _Pdelay;
  113. avgDelay = (Pdelay / 127.0f * 1.5f); //0 .. 1.5 sec
  114. initdelays();
  115. }
  116. void Echo::setlrdelay(unsigned char _Plrdelay)
  117. {
  118. float tmp;
  119. Plrdelay = _Plrdelay;
  120. tmp =
  121. (powf(2.0f, fabsf(Plrdelay - 64.0f) / 64.0f * 9.0f) - 1.0f) / 1000.0f;
  122. if(Plrdelay < 64.0f)
  123. tmp = -tmp;
  124. lrdelay = tmp;
  125. initdelays();
  126. }
  127. void Echo::setfb(unsigned char _Pfb)
  128. {
  129. Pfb = _Pfb;
  130. fb = Pfb / 128.0f;
  131. }
  132. void Echo::sethidamp(unsigned char _Phidamp)
  133. {
  134. Phidamp = _Phidamp;
  135. hidamp = 1.0f - Phidamp / 127.0f;
  136. }
  137. void Echo::setpreset(unsigned char npreset)
  138. {
  139. const int PRESET_SIZE = 7;
  140. const int NUM_PRESETS = 9;
  141. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  142. {67, 64, 35, 64, 30, 59, 0 }, //Echo 1
  143. {67, 64, 21, 64, 30, 59, 0 }, //Echo 2
  144. {67, 75, 60, 64, 30, 59, 10}, //Echo 3
  145. {67, 60, 44, 64, 30, 0, 0 }, //Simple Echo
  146. {67, 60, 102, 50, 30, 82, 48}, //Canyon
  147. {67, 64, 44, 17, 0, 82, 24}, //Panning Echo 1
  148. {81, 60, 46, 118, 100, 68, 18}, //Panning Echo 2
  149. {81, 60, 26, 100, 127, 67, 36}, //Panning Echo 3
  150. {62, 64, 28, 64, 100, 90, 55} //Feedback Echo
  151. };
  152. if(npreset >= NUM_PRESETS)
  153. npreset = NUM_PRESETS - 1;
  154. for(int n = 0; n < PRESET_SIZE; ++n)
  155. changepar(n, presets[npreset][n]);
  156. if(insertion)
  157. setvolume(presets[npreset][0] / 2); //lower the volume if this is insertion effect
  158. Ppreset = npreset;
  159. }
  160. void Echo::changepar(int npar, unsigned char value)
  161. {
  162. switch(npar) {
  163. case 0:
  164. setvolume(value);
  165. break;
  166. case 1:
  167. setpanning(value);
  168. break;
  169. case 2:
  170. setdelay(value);
  171. break;
  172. case 3:
  173. setlrdelay(value);
  174. break;
  175. case 4:
  176. setlrcross(value);
  177. break;
  178. case 5:
  179. setfb(value);
  180. break;
  181. case 6:
  182. sethidamp(value);
  183. break;
  184. }
  185. }
  186. unsigned char Echo::getpar(int npar) const
  187. {
  188. switch(npar) {
  189. case 0: return Pvolume;
  190. case 1: return Ppanning;
  191. case 2: return Pdelay;
  192. case 3: return Plrdelay;
  193. case 4: return Plrcross;
  194. case 5: return Pfb;
  195. case 6: return Phidamp;
  196. default: return 0; // in case of bogus parameter number
  197. }
  198. }