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.

MVerb.h 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. // Copyright (c) 2010 Martin Eastwood
  2. // This code is distributed under the terms of the GNU General Public License
  3. // MVerb is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // at your option) any later version.
  7. //
  8. // MVerb is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this MVerb. If not, see <http://www.gnu.org/licenses/>.
  15. #ifndef EMVERB_H
  16. #define EMVERB_H
  17. #include <cmath>
  18. #include <cstring>
  19. //forward declaration
  20. template<typename T, int maxLength> class Allpass;
  21. template<typename T, int maxLength> class StaticAllpassFourTap;
  22. template<typename T, int maxLength> class StaticDelayLine;
  23. template<typename T, int maxLength> class StaticDelayLineFourTap;
  24. template<typename T, int maxLength> class StaticDelayLineEightTap;
  25. template<typename T, int OverSampleCount> class StateVariable;
  26. template<typename T>
  27. class MVerb
  28. {
  29. private:
  30. Allpass<T, 96000> allpass[4];
  31. StaticAllpassFourTap<T, 96000> allpassFourTap[4];
  32. StateVariable<T,4> bandwidthFilter[2];
  33. StateVariable<T,4> damping[2];
  34. StaticDelayLine<T, 96000> predelay;
  35. StaticDelayLineFourTap<T, 96000> staticDelayLine[4];
  36. StaticDelayLineEightTap<T, 96000> earlyReflectionsDelayLine[2];
  37. T SampleRate, DampingFreq, Density1, Density2, BandwidthFreq, PreDelayTime, Decay, Gain, Mix, EarlyMix, Size;
  38. T MixSmooth, EarlyLateSmooth, BandwidthSmooth, DampingSmooth, PredelaySmooth, SizeSmooth, DensitySmooth, DecaySmooth;
  39. T PreviousLeftTank, PreviousRightTank;
  40. int ControlRate, ControlRateCounter;
  41. public:
  42. enum
  43. {
  44. DAMPINGFREQ=0,
  45. DENSITY,
  46. BANDWIDTHFREQ,
  47. DECAY,
  48. PREDELAY,
  49. SIZE,
  50. GAIN,
  51. MIX,
  52. EARLYMIX,
  53. NUM_PARAMS
  54. };
  55. MVerb(){
  56. DampingFreq = 18000.;
  57. BandwidthFreq = 18000.;
  58. SampleRate = 44100.;
  59. Decay = 0.5;
  60. Gain = 1.;
  61. Mix = 1.;
  62. Size = 1.;
  63. EarlyMix = 1.;
  64. PreviousLeftTank = 0.;
  65. PreviousRightTank = 0.;
  66. PreDelayTime = 100 * (SampleRate / 1000);
  67. MixSmooth = EarlyLateSmooth = BandwidthSmooth = DampingSmooth = PredelaySmooth = SizeSmooth = DecaySmooth = DensitySmooth = 0.;
  68. ControlRate = SampleRate / 1000;
  69. ControlRateCounter = 0;
  70. reset();
  71. }
  72. ~MVerb(){
  73. //nowt to do here
  74. }
  75. void process(const T **inputs, T **outputs, int sampleFrames){
  76. T OneOverSampleFrames = 1. / sampleFrames;
  77. T MixDelta = (Mix - MixSmooth) * OneOverSampleFrames;
  78. T EarlyLateDelta = (EarlyMix - EarlyLateSmooth) * OneOverSampleFrames;
  79. T BandwidthDelta = (((BandwidthFreq * 18400.) + 100.) - BandwidthSmooth) * OneOverSampleFrames;
  80. T DampingDelta = (((DampingFreq * 18400.) + 100.) - DampingSmooth) * OneOverSampleFrames;
  81. T PredelayDelta = ((PreDelayTime * 200 * (SampleRate / 1000)) - PredelaySmooth) * OneOverSampleFrames;
  82. T SizeDelta = (Size - SizeSmooth) * OneOverSampleFrames;
  83. T DecayDelta = (((0.7995f * Decay) + 0.005) - DecaySmooth) * OneOverSampleFrames;
  84. T DensityDelta = (((0.7995f * Density1) + 0.005) - DensitySmooth) * OneOverSampleFrames;
  85. for(int i=0;i<sampleFrames;++i){
  86. T left = inputs[0][i];
  87. T right = inputs[1][i];
  88. MixSmooth += MixDelta;
  89. EarlyLateSmooth += EarlyLateDelta;
  90. BandwidthSmooth += BandwidthDelta;
  91. DampingSmooth += DampingDelta;
  92. PredelaySmooth += PredelayDelta;
  93. SizeSmooth += SizeDelta;
  94. DecaySmooth += DecayDelta;
  95. DensitySmooth += DensityDelta;
  96. if (ControlRateCounter >= ControlRate){
  97. ControlRateCounter = 0;
  98. bandwidthFilter[0].Frequency(BandwidthSmooth);
  99. bandwidthFilter[1].Frequency(BandwidthSmooth);
  100. damping[0].Frequency(DampingSmooth);
  101. damping[1].Frequency(DampingSmooth);
  102. }
  103. ++ControlRateCounter;
  104. predelay.SetLength(PredelaySmooth);
  105. Density2 = DecaySmooth + 0.15;
  106. if (Density2 > 0.5)
  107. Density2 = 0.5;
  108. if (Density2 < 0.25)
  109. Density2 = 0.25;
  110. allpassFourTap[1].SetFeedback(Density2);
  111. allpassFourTap[3].SetFeedback(Density2);
  112. allpassFourTap[0].SetFeedback(Density1);
  113. allpassFourTap[2].SetFeedback(Density1);
  114. T bandwidthLeft = bandwidthFilter[0](left) ;
  115. T bandwidthRight = bandwidthFilter[1](right) ;
  116. T earlyReflectionsL = earlyReflectionsDelayLine[0] ( bandwidthLeft * 0.5 + bandwidthRight * 0.3 )
  117. + earlyReflectionsDelayLine[0].GetIndex(2) * 0.6
  118. + earlyReflectionsDelayLine[0].GetIndex(3) * 0.4
  119. + earlyReflectionsDelayLine[0].GetIndex(4) * 0.3
  120. + earlyReflectionsDelayLine[0].GetIndex(5) * 0.3
  121. + earlyReflectionsDelayLine[0].GetIndex(6) * 0.1
  122. + earlyReflectionsDelayLine[0].GetIndex(7) * 0.1
  123. + ( bandwidthLeft * 0.4 + bandwidthRight * 0.2 ) * 0.5 ;
  124. T earlyReflectionsR = earlyReflectionsDelayLine[1] ( bandwidthLeft * 0.3 + bandwidthRight * 0.5 )
  125. + earlyReflectionsDelayLine[1].GetIndex(2) * 0.6
  126. + earlyReflectionsDelayLine[1].GetIndex(3) * 0.4
  127. + earlyReflectionsDelayLine[1].GetIndex(4) * 0.3
  128. + earlyReflectionsDelayLine[1].GetIndex(5) * 0.3
  129. + earlyReflectionsDelayLine[1].GetIndex(6) * 0.1
  130. + earlyReflectionsDelayLine[1].GetIndex(7) * 0.1
  131. + ( bandwidthLeft * 0.2 + bandwidthRight * 0.4 ) * 0.5 ;
  132. T predelayMonoInput = predelay(( bandwidthRight + bandwidthLeft ) * 0.5f);
  133. T smearedInput = predelayMonoInput;
  134. for(int j=0;j<4;j++)
  135. smearedInput = allpass[j] ( smearedInput );
  136. T leftTank = allpassFourTap[0] ( smearedInput + PreviousRightTank ) ;
  137. leftTank = staticDelayLine[0] (leftTank);
  138. leftTank = damping[0](leftTank);
  139. leftTank = allpassFourTap[1](leftTank);
  140. leftTank = staticDelayLine[1](leftTank);
  141. T rightTank = allpassFourTap[2] (smearedInput + PreviousLeftTank) ;
  142. rightTank = staticDelayLine[2](rightTank);
  143. rightTank = damping[1] (rightTank);
  144. rightTank = allpassFourTap[3](rightTank);
  145. rightTank = staticDelayLine[3](rightTank);
  146. PreviousLeftTank = leftTank * DecaySmooth;
  147. PreviousRightTank = rightTank * DecaySmooth;
  148. T accumulatorL = (0.6*staticDelayLine[2].GetIndex(1))
  149. +(0.6*staticDelayLine[2].GetIndex(2))
  150. -(0.6*allpassFourTap[3].GetIndex(1))
  151. +(0.6*staticDelayLine[3].GetIndex(1))
  152. -(0.6*staticDelayLine[0].GetIndex(1))
  153. -(0.6*allpassFourTap[1].GetIndex(1))
  154. -(0.6*staticDelayLine[1].GetIndex(1));
  155. T accumulatorR = (0.6*staticDelayLine[0].GetIndex(2))
  156. +(0.6*staticDelayLine[0].GetIndex(3))
  157. -(0.6*allpassFourTap[1].GetIndex(2))
  158. +(0.6*staticDelayLine[1].GetIndex(2))
  159. -(0.6*staticDelayLine[2].GetIndex(3))
  160. -(0.6*allpassFourTap[3].GetIndex(2))
  161. -(0.6*staticDelayLine[3].GetIndex(2));
  162. accumulatorL = ((accumulatorL * EarlyMix) + ((1 - EarlyMix) * earlyReflectionsL));
  163. accumulatorR = ((accumulatorR * EarlyMix) + ((1 - EarlyMix) * earlyReflectionsR));
  164. left = ( left + MixSmooth * ( accumulatorL - left ) ) * Gain;
  165. right = ( right + MixSmooth * ( accumulatorR - right ) ) * Gain;
  166. outputs[0][i] = left;
  167. outputs[1][i] = right;
  168. }
  169. }
  170. void reset(){
  171. ControlRateCounter = 0;
  172. bandwidthFilter[0].SetSampleRate (SampleRate );
  173. bandwidthFilter[1].SetSampleRate (SampleRate );
  174. bandwidthFilter[0].Reset();
  175. bandwidthFilter[1].Reset();
  176. damping[0].SetSampleRate (SampleRate );
  177. damping[1].SetSampleRate (SampleRate );
  178. damping[0].Reset();
  179. damping[1].Reset();
  180. predelay.Clear();
  181. predelay.SetLength(PreDelayTime);
  182. allpass[0].Clear();
  183. allpass[1].Clear();
  184. allpass[2].Clear();
  185. allpass[3].Clear();
  186. allpass[0].SetLength (0.0048 * SampleRate);
  187. allpass[1].SetLength (0.0036 * SampleRate);
  188. allpass[2].SetLength (0.0127 * SampleRate);
  189. allpass[3].SetLength (0.0093 * SampleRate);
  190. allpass[0].SetFeedback (0.75);
  191. allpass[1].SetFeedback (0.75);
  192. allpass[2].SetFeedback (0.625);
  193. allpass[3].SetFeedback (0.625);
  194. allpassFourTap[0].Clear();
  195. allpassFourTap[1].Clear();
  196. allpassFourTap[2].Clear();
  197. allpassFourTap[3].Clear();
  198. allpassFourTap[0].SetLength(0.020 * SampleRate * Size);
  199. allpassFourTap[1].SetLength(0.060 * SampleRate * Size);
  200. allpassFourTap[2].SetLength(0.030 * SampleRate * Size);
  201. allpassFourTap[3].SetLength(0.089 * SampleRate * Size);
  202. allpassFourTap[0].SetFeedback(Density1);
  203. allpassFourTap[1].SetFeedback(Density2);
  204. allpassFourTap[2].SetFeedback(Density1);
  205. allpassFourTap[3].SetFeedback(Density2);
  206. allpassFourTap[0].SetIndex(0,0,0,0);
  207. allpassFourTap[1].SetIndex(0,0.006 * SampleRate * Size, 0.041 * SampleRate * Size, 0);
  208. allpassFourTap[2].SetIndex(0,0,0,0);
  209. allpassFourTap[3].SetIndex(0,0.031 * SampleRate * Size, 0.011 * SampleRate * Size, 0);
  210. staticDelayLine[0].Clear();
  211. staticDelayLine[1].Clear();
  212. staticDelayLine[2].Clear();
  213. staticDelayLine[3].Clear();
  214. staticDelayLine[0].SetLength(0.15 * SampleRate * Size);
  215. staticDelayLine[1].SetLength(0.12 * SampleRate * Size);
  216. staticDelayLine[2].SetLength(0.14 * SampleRate * Size);
  217. staticDelayLine[3].SetLength(0.11 * SampleRate * Size);
  218. staticDelayLine[0].SetIndex(0, 0.067 * SampleRate * Size, 0.011 * SampleRate * Size , 0.121 * SampleRate * Size);
  219. staticDelayLine[1].SetIndex(0, 0.036 * SampleRate * Size, 0.089 * SampleRate * Size , 0);
  220. staticDelayLine[2].SetIndex(0, 0.0089 * SampleRate * Size, 0.099 * SampleRate * Size , 0);
  221. staticDelayLine[3].SetIndex(0, 0.067 * SampleRate * Size, 0.0041 * SampleRate * Size , 0);
  222. earlyReflectionsDelayLine[0].Clear();
  223. earlyReflectionsDelayLine[1].Clear();
  224. earlyReflectionsDelayLine[0].SetLength(0.089 * SampleRate);
  225. earlyReflectionsDelayLine[0].SetIndex (0, 0.0199*SampleRate, 0.0219*SampleRate, 0.0354*SampleRate,0.0389*SampleRate, 0.0414*SampleRate, 0.0692*SampleRate, 0);
  226. earlyReflectionsDelayLine[1].SetLength(0.069 * SampleRate);
  227. earlyReflectionsDelayLine[1].SetIndex (0, 0.0099*SampleRate, 0.011*SampleRate, 0.0182*SampleRate,0.0189*SampleRate, 0.0213*SampleRate, 0.0431*SampleRate, 0);
  228. }
  229. void setParameter(int index, T value){
  230. switch(index){
  231. case DAMPINGFREQ:
  232. DampingFreq = /* 1. - */ value; // FIXME?
  233. break;
  234. case DENSITY:
  235. Density1 = value;
  236. break;
  237. case BANDWIDTHFREQ:
  238. BandwidthFreq = value;
  239. break;
  240. case PREDELAY:
  241. PreDelayTime = value;
  242. break;
  243. case SIZE:
  244. Size = value;
  245. allpassFourTap[0].Clear();
  246. allpassFourTap[1].Clear();
  247. allpassFourTap[2].Clear();
  248. allpassFourTap[3].Clear();
  249. allpassFourTap[0].SetLength(0.020 * SampleRate * Size);
  250. allpassFourTap[1].SetLength(0.060 * SampleRate * Size);
  251. allpassFourTap[2].SetLength(0.030 * SampleRate * Size);
  252. allpassFourTap[3].SetLength(0.089 * SampleRate * Size);
  253. allpassFourTap[1].SetIndex(0,0.006 * SampleRate * Size, 0.041 * SampleRate * Size, 0);
  254. allpassFourTap[3].SetIndex(0,0.031 * SampleRate * Size, 0.011 * SampleRate * Size, 0);
  255. staticDelayLine[0].Clear();
  256. staticDelayLine[1].Clear();
  257. staticDelayLine[2].Clear();
  258. staticDelayLine[3].Clear();
  259. staticDelayLine[0].SetLength(0.15 * SampleRate * Size);
  260. staticDelayLine[1].SetLength(0.12 * SampleRate * Size);
  261. staticDelayLine[2].SetLength(0.14 * SampleRate * Size);
  262. staticDelayLine[3].SetLength(0.11 * SampleRate * Size);
  263. staticDelayLine[0].SetIndex(0, 0.067 * SampleRate * Size, 0.011 * SampleRate * Size , 0.121 * SampleRate * Size);
  264. staticDelayLine[1].SetIndex(0, 0.036 * SampleRate * Size, 0.089 * SampleRate * Size , 0);
  265. staticDelayLine[2].SetIndex(0, 0.0089 * SampleRate * Size, 0.099 * SampleRate * Size , 0);
  266. staticDelayLine[3].SetIndex(0, 0.067 * SampleRate * Size, 0.0041 * SampleRate * Size , 0);
  267. break;
  268. case DECAY:
  269. Decay = value;
  270. break;
  271. case GAIN:
  272. Gain = value;
  273. break;
  274. case MIX:
  275. Mix = value;
  276. break;
  277. case EARLYMIX:
  278. EarlyMix = value;
  279. break;
  280. }
  281. }
  282. float getParameter(int index) const{
  283. switch(index){
  284. case DAMPINGFREQ:
  285. return DampingFreq;
  286. break;
  287. case DENSITY:
  288. return Density1;
  289. break;
  290. case BANDWIDTHFREQ:
  291. return BandwidthFreq;
  292. break;
  293. case PREDELAY:
  294. return PreDelayTime;
  295. break;
  296. case SIZE:
  297. return Size;
  298. break;
  299. case DECAY:
  300. return Decay;
  301. break;
  302. case GAIN:
  303. return Gain;
  304. break;
  305. case MIX:
  306. return Mix;
  307. break;
  308. case EARLYMIX:
  309. return EarlyMix;
  310. break;
  311. default: return 0.f;
  312. break;
  313. }
  314. }
  315. void setSampleRate(T sr){
  316. SampleRate = sr;
  317. ControlRate = SampleRate / 1000;
  318. reset();
  319. }
  320. };
  321. template<typename T, int maxLength>
  322. class Allpass
  323. {
  324. private:
  325. T buffer[maxLength];
  326. int index;
  327. int Length;
  328. T Feedback;
  329. public:
  330. Allpass()
  331. {
  332. SetLength ( maxLength - 1 );
  333. Clear();
  334. Feedback = 0.5;
  335. }
  336. T operator()(T input)
  337. {
  338. T output;
  339. T bufout;
  340. bufout = buffer[index];
  341. T temp = input * -Feedback;
  342. output = bufout + temp;
  343. buffer[index] = input + ((bufout+temp)*Feedback);
  344. if(++index>=Length) index = 0;
  345. return output;
  346. }
  347. void SetLength (int Length)
  348. {
  349. if( Length >= maxLength )
  350. Length = maxLength;
  351. if( Length < 0 )
  352. Length = 0;
  353. this->Length = Length;
  354. }
  355. void SetFeedback(T feedback)
  356. {
  357. Feedback = feedback;
  358. }
  359. void Clear()
  360. {
  361. std::memset(buffer, 0, sizeof(buffer));
  362. index = 0;
  363. }
  364. int GetLength() const
  365. {
  366. return Length;
  367. }
  368. };
  369. template<typename T, int maxLength>
  370. class StaticAllpassFourTap
  371. {
  372. private:
  373. T buffer[maxLength];
  374. int index1, index2, index3, index4;
  375. int Length;
  376. T Feedback;
  377. public:
  378. StaticAllpassFourTap()
  379. {
  380. SetLength ( maxLength - 1 );
  381. Clear();
  382. Feedback = 0.5;
  383. }
  384. T operator()(T input)
  385. {
  386. T output;
  387. T bufout;
  388. bufout = buffer[index1];
  389. T temp = input * -Feedback;
  390. output = bufout + temp;
  391. buffer[index1] = input + ((bufout+temp)*Feedback);
  392. if(++index1>=Length)
  393. index1 = 0;
  394. if(++index2 >= Length)
  395. index2 = 0;
  396. if(++index3 >= Length)
  397. index3 = 0;
  398. if(++index4 >= Length)
  399. index4 = 0;
  400. return output;
  401. }
  402. void SetIndex (int Index1, int Index2, int Index3, int Index4)
  403. {
  404. index1 = Index1;
  405. index2 = Index2;
  406. index3 = Index3;
  407. index4 = Index4;
  408. }
  409. T GetIndex (int Index)
  410. {
  411. switch (Index)
  412. {
  413. case 0:
  414. return buffer[index1];
  415. break;
  416. case 1:
  417. return buffer[index2];
  418. break;
  419. case 2:
  420. return buffer[index3];
  421. break;
  422. case 3:
  423. return buffer[index4];
  424. break;
  425. default:
  426. return buffer[index1];
  427. break;
  428. }
  429. }
  430. void SetLength (int Length)
  431. {
  432. if( Length >= maxLength )
  433. Length = maxLength;
  434. if( Length < 0 )
  435. Length = 0;
  436. this->Length = Length;
  437. }
  438. void Clear()
  439. {
  440. std::memset(buffer, 0, sizeof(buffer));
  441. index1 = index2 = index3 = index4 = 0;
  442. }
  443. void SetFeedback(T feedback)
  444. {
  445. Feedback = feedback;
  446. }
  447. int GetLength() const
  448. {
  449. return Length;
  450. }
  451. };
  452. template<typename T, int maxLength>
  453. class StaticDelayLine
  454. {
  455. private:
  456. T buffer[maxLength];
  457. int index;
  458. int Length;
  459. T Feedback;
  460. public:
  461. StaticDelayLine()
  462. {
  463. SetLength ( maxLength - 1 );
  464. Clear();
  465. }
  466. T operator()(T input)
  467. {
  468. T output = buffer[index];
  469. buffer[index++] = input;
  470. if(index >= Length)
  471. index = 0;
  472. return output;
  473. }
  474. void SetLength (int Length)
  475. {
  476. if( Length >= maxLength )
  477. Length = maxLength;
  478. if( Length < 0 )
  479. Length = 0;
  480. this->Length = Length;
  481. }
  482. void Clear()
  483. {
  484. std::memset(buffer, 0, sizeof(buffer));
  485. index = 0;
  486. }
  487. int GetLength() const
  488. {
  489. return Length;
  490. }
  491. };
  492. template<typename T, int maxLength>
  493. class StaticDelayLineFourTap
  494. {
  495. private:
  496. T buffer[maxLength];
  497. int index1, index2, index3, index4;
  498. int Length;
  499. T Feedback;
  500. public:
  501. StaticDelayLineFourTap()
  502. {
  503. SetLength ( maxLength - 1 );
  504. Clear();
  505. }
  506. //get ouput and iterate
  507. T operator()(T input)
  508. {
  509. T output = buffer[index1];
  510. buffer[index1++] = input;
  511. if(index1 >= Length)
  512. index1 = 0;
  513. if(++index2 >= Length)
  514. index2 = 0;
  515. if(++index3 >= Length)
  516. index3 = 0;
  517. if(++index4 >= Length)
  518. index4 = 0;
  519. return output;
  520. }
  521. void SetIndex (int Index1, int Index2, int Index3, int Index4)
  522. {
  523. index1 = Index1;
  524. index2 = Index2;
  525. index3 = Index3;
  526. index4 = Index4;
  527. }
  528. T GetIndex (int Index)
  529. {
  530. switch (Index)
  531. {
  532. case 0:
  533. return buffer[index1];
  534. break;
  535. case 1:
  536. return buffer[index2];
  537. break;
  538. case 2:
  539. return buffer[index3];
  540. break;
  541. case 3:
  542. return buffer[index4];
  543. break;
  544. default:
  545. return buffer[index1];
  546. break;
  547. }
  548. }
  549. void SetLength (int Length)
  550. {
  551. if( Length >= maxLength )
  552. Length = maxLength;
  553. if( Length < 0 )
  554. Length = 0;
  555. this->Length = Length;
  556. }
  557. void Clear()
  558. {
  559. std::memset(buffer, 0, sizeof(buffer));
  560. index1 = index2 = index3 = index4 = 0;
  561. }
  562. int GetLength() const
  563. {
  564. return Length;
  565. }
  566. };
  567. template<typename T, int maxLength>
  568. class StaticDelayLineEightTap
  569. {
  570. private:
  571. T buffer[maxLength];
  572. int index1, index2, index3, index4, index5, index6, index7, index8;
  573. int Length;
  574. T Feedback;
  575. public:
  576. StaticDelayLineEightTap()
  577. {
  578. SetLength ( maxLength - 1 );
  579. Clear();
  580. }
  581. //get ouput and iterate
  582. T operator()(T input)
  583. {
  584. T output = buffer[index1];
  585. buffer[index1++] = input;
  586. if(index1 >= Length)
  587. index1 = 0;
  588. if(++index2 >= Length)
  589. index2 = 0;
  590. if(++index3 >= Length)
  591. index3 = 0;
  592. if(++index4 >= Length)
  593. index4 = 0;
  594. if(++index5 >= Length)
  595. index5 = 0;
  596. if(++index6 >= Length)
  597. index6 = 0;
  598. if(++index7 >= Length)
  599. index7 = 0;
  600. if(++index8 >= Length)
  601. index8 = 0;
  602. return output;
  603. }
  604. void SetIndex (int Index1, int Index2, int Index3, int Index4, int Index5, int Index6, int Index7, int Index8)
  605. {
  606. index1 = Index1;
  607. index2 = Index2;
  608. index3 = Index3;
  609. index4 = Index4;
  610. index5 = Index5;
  611. index6 = Index6;
  612. index7 = Index7;
  613. index8 = Index8;
  614. }
  615. T GetIndex (int Index)
  616. {
  617. switch (Index)
  618. {
  619. case 0:
  620. return buffer[index1];
  621. break;
  622. case 1:
  623. return buffer[index2];
  624. break;
  625. case 2:
  626. return buffer[index3];
  627. break;
  628. case 3:
  629. return buffer[index4];
  630. break;
  631. case 4:
  632. return buffer[index5];
  633. break;
  634. case 5:
  635. return buffer[index6];
  636. break;
  637. case 6:
  638. return buffer[index7];
  639. break;
  640. case 7:
  641. return buffer[index8];
  642. break;
  643. default:
  644. return buffer[index1];
  645. break;
  646. }
  647. }
  648. void SetLength (int Length)
  649. {
  650. if( Length >= maxLength )
  651. Length = maxLength;
  652. if( Length < 0 )
  653. Length = 0;
  654. this->Length = Length;
  655. }
  656. void Clear()
  657. {
  658. std::memset(buffer, 0, sizeof(buffer));
  659. index1 = index2 = index3 = index4 = index5 = index6 = index7 = index8 = 0;
  660. }
  661. int GetLength() const
  662. {
  663. return Length;
  664. }
  665. };
  666. template<typename T, int OverSampleCount>
  667. class StateVariable
  668. {
  669. public:
  670. enum FilterType
  671. {
  672. LOWPASS,
  673. HIGHPASS,
  674. BANDPASS,
  675. NOTCH,
  676. FilterTypeCount
  677. };
  678. private:
  679. T sampleRate;
  680. T frequency;
  681. T q;
  682. T f;
  683. T low;
  684. T high;
  685. T band;
  686. T notch;
  687. T *out;
  688. public:
  689. StateVariable()
  690. {
  691. SetSampleRate(44100.);
  692. Frequency(1000.);
  693. Resonance(0);
  694. Type(LOWPASS);
  695. Reset();
  696. }
  697. T operator()(T input)
  698. {
  699. for(unsigned int i = 0; i < OverSampleCount; i++)
  700. {
  701. low += f * band + 1e-25;
  702. high = input - low - q * band;
  703. band += f * high;
  704. notch = low + high;
  705. }
  706. return *out;
  707. }
  708. void Reset()
  709. {
  710. low = high = band = notch = 0;
  711. }
  712. void SetSampleRate(T sampleRate)
  713. {
  714. this->sampleRate = sampleRate * OverSampleCount;
  715. UpdateCoefficient();
  716. }
  717. void Frequency(T frequency)
  718. {
  719. this->frequency = frequency;
  720. UpdateCoefficient();
  721. }
  722. void Resonance(T resonance)
  723. {
  724. this->q = 2 - 2 * resonance;
  725. }
  726. void Type(int type)
  727. {
  728. switch(type)
  729. {
  730. case LOWPASS:
  731. out = &low;
  732. break;
  733. case HIGHPASS:
  734. out = &high;
  735. break;
  736. case BANDPASS:
  737. out = &band;
  738. break;
  739. case NOTCH:
  740. out = &notch;
  741. break;
  742. default:
  743. out = &low;
  744. break;
  745. }
  746. }
  747. private:
  748. void UpdateCoefficient()
  749. {
  750. f = 2. * std::sin(M_PI * frequency / sampleRate);
  751. }
  752. };
  753. #endif