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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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 "../Misc/Allocator.h"
  21. #include "Echo.h"
  22. #define MAX_DELAY 2
  23. Echo::Echo(EffectParams pars)
  24. :Effect(pars),
  25. Pvolume(50),
  26. Pdelay(60),
  27. Plrdelay(100),
  28. Pfb(40),
  29. Phidamp(60),
  30. delayTime(1),
  31. lrdelay(0),
  32. avgDelay(0),
  33. delay(memory.valloc<float>(MAX_DELAY * pars.srate),
  34. memory.valloc<float>(MAX_DELAY * pars.srate)),
  35. old(0.0f),
  36. pos(0),
  37. delta(1),
  38. ndelta(1)
  39. {
  40. initdelays();
  41. setpreset(Ppreset);
  42. }
  43. Echo::~Echo()
  44. {
  45. memory.devalloc(delay.l);
  46. memory.devalloc(delay.r);
  47. }
  48. //Cleanup the effect
  49. void Echo::cleanup(void)
  50. {
  51. memset(delay.l, 0, MAX_DELAY * samplerate * sizeof(float));
  52. memset(delay.r, 0, MAX_DELAY * samplerate * sizeof(float));
  53. old = Stereo<float>(0.0f);
  54. }
  55. inline int max(int a, int b)
  56. {
  57. return a > b ? a : b;
  58. }
  59. //Initialize the delays
  60. void Echo::initdelays(void)
  61. {
  62. cleanup();
  63. //number of seconds to delay left chan
  64. float dl = avgDelay - lrdelay;
  65. //number of seconds to delay right chan
  66. float dr = avgDelay + lrdelay;
  67. ndelta.l = max(1, (int) (dl * samplerate));
  68. ndelta.r = max(1, (int) (dr * samplerate));
  69. delta = ndelta;
  70. }
  71. //Effect output
  72. void Echo::out(const Stereo<float *> &input)
  73. {
  74. for(int i = 0; i < buffersize; ++i) {
  75. float ldl = delay.l[pos.l];
  76. float rdl = delay.r[pos.r];
  77. ldl = ldl * (1.0f - lrcross) + rdl * lrcross;
  78. rdl = rdl * (1.0f - lrcross) + ldl * lrcross;
  79. efxoutl[i] = ldl * 2.0f;
  80. efxoutr[i] = rdl * 2.0f;
  81. ldl = input.l[i] * pangainL - ldl * fb;
  82. rdl = input.r[i] * pangainR - rdl * fb;
  83. //LowPass Filter
  84. old.l = delay.l[(pos.l + delta.l) % (MAX_DELAY * samplerate)] =
  85. ldl * hidamp + old.l * (1.0f - hidamp);
  86. old.r = delay.r[(pos.r + delta.r) % (MAX_DELAY * samplerate)] =
  87. rdl * hidamp + old.r * (1.0f - hidamp);
  88. //increment
  89. ++pos.l; // += delta.l;
  90. ++pos.r; // += delta.r;
  91. //ensure that pos is still in bounds
  92. pos.l %= MAX_DELAY * samplerate;
  93. pos.r %= MAX_DELAY * samplerate;
  94. //adjust delay if needed
  95. delta.l = (15 * delta.l + ndelta.l) / 16;
  96. delta.r = (15 * delta.r + ndelta.r) / 16;
  97. }
  98. }
  99. //Parameter control
  100. void Echo::setvolume(unsigned char _Pvolume)
  101. {
  102. Pvolume = _Pvolume;
  103. if(insertion == 0) {
  104. outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
  105. volume = 1.0f;
  106. }
  107. else
  108. volume = outvolume = Pvolume / 127.0f;
  109. if(Pvolume == 0)
  110. cleanup();
  111. }
  112. void Echo::setdelay(unsigned char _Pdelay)
  113. {
  114. Pdelay = _Pdelay;
  115. avgDelay = (Pdelay / 127.0f * 1.5f); //0 .. 1.5 sec
  116. initdelays();
  117. }
  118. void Echo::setlrdelay(unsigned char _Plrdelay)
  119. {
  120. float tmp;
  121. Plrdelay = _Plrdelay;
  122. tmp =
  123. (powf(2.0f, fabsf(Plrdelay - 64.0f) / 64.0f * 9.0f) - 1.0f) / 1000.0f;
  124. if(Plrdelay < 64.0f)
  125. tmp = -tmp;
  126. lrdelay = tmp;
  127. initdelays();
  128. }
  129. void Echo::setfb(unsigned char _Pfb)
  130. {
  131. Pfb = _Pfb;
  132. fb = Pfb / 128.0f;
  133. }
  134. void Echo::sethidamp(unsigned char _Phidamp)
  135. {
  136. Phidamp = _Phidamp;
  137. hidamp = 1.0f - Phidamp / 127.0f;
  138. }
  139. void Echo::setpreset(unsigned char npreset)
  140. {
  141. const int PRESET_SIZE = 7;
  142. const int NUM_PRESETS = 9;
  143. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  144. {67, 64, 35, 64, 30, 59, 0 }, //Echo 1
  145. {67, 64, 21, 64, 30, 59, 0 }, //Echo 2
  146. {67, 75, 60, 64, 30, 59, 10}, //Echo 3
  147. {67, 60, 44, 64, 30, 0, 0 }, //Simple Echo
  148. {67, 60, 102, 50, 30, 82, 48}, //Canyon
  149. {67, 64, 44, 17, 0, 82, 24}, //Panning Echo 1
  150. {81, 60, 46, 118, 100, 68, 18}, //Panning Echo 2
  151. {81, 60, 26, 100, 127, 67, 36}, //Panning Echo 3
  152. {62, 64, 28, 64, 100, 90, 55} //Feedback Echo
  153. };
  154. if(npreset >= NUM_PRESETS)
  155. npreset = NUM_PRESETS - 1;
  156. for(int n = 0; n < PRESET_SIZE; ++n)
  157. changepar(n, presets[npreset][n]);
  158. if(insertion)
  159. setvolume(presets[npreset][0] / 2); //lower the volume if this is insertion effect
  160. Ppreset = npreset;
  161. }
  162. void Echo::changepar(int npar, unsigned char value)
  163. {
  164. switch(npar) {
  165. case 0:
  166. setvolume(value);
  167. break;
  168. case 1:
  169. setpanning(value);
  170. break;
  171. case 2:
  172. setdelay(value);
  173. break;
  174. case 3:
  175. setlrdelay(value);
  176. break;
  177. case 4:
  178. setlrcross(value);
  179. break;
  180. case 5:
  181. setfb(value);
  182. break;
  183. case 6:
  184. sethidamp(value);
  185. break;
  186. }
  187. }
  188. unsigned char Echo::getpar(int npar) const
  189. {
  190. switch(npar) {
  191. case 0: return Pvolume;
  192. case 1: return Ppanning;
  193. case 2: return Pdelay;
  194. case 3: return Plrdelay;
  195. case 4: return Plrcross;
  196. case 5: return Pfb;
  197. case 6: return Phidamp;
  198. default: return 0; // in case of bogus parameter number
  199. }
  200. }