reverberator.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488
  1. /*
  2. * Copyright (c) 1983-2013 Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. * This file is part of the CDP System.
  6. * The CDP System is free software; you can redistribute it
  7. * and/or modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * The CDP System 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.
  14. * See the GNU Lesser General Public License for more details.
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with the CDP System; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. // reverberator.cpp: implementation of the reverberator class.
  21. // see also tapdelay.cpp
  22. //TODO: simple delay for use with tapped delayline
  23. // NB blame VC6 for horrible code, new returns null...
  24. //////////////////////////////////////////////////////////////////////
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <memory.h>
  28. #include <math.h>
  29. #ifdef _DEBUG
  30. #include <assert.h>
  31. #endif
  32. #include "reverberator.h"
  33. #ifndef PI
  34. # define PI 3.141592653589793238462643
  35. #endif
  36. #ifndef TWOPI
  37. #define TWOPI (2.0 * PI)
  38. #endif
  39. #define ROOT2O2 (0.7071067811965475244)
  40. #define SPN 1.65436e-24 //RWD: use a proper MSVC version...?
  41. //////////////////////////////////////////////////////////////////////
  42. // Construction/Destruction
  43. //////////////////////////////////////////////////////////////////////
  44. //for example:
  45. //const deltap taps[4] = {{0.1,0.9},{0.25,.75},{0.5,.5},{0.618,.25}};
  46. //NB this accepts a zero taptime
  47. tapdelay::tapdelay(const deltap *taps,unsigned int ctaps,double sr) : dtaps(taps)
  48. {
  49. tapbuf = 0;
  50. ntaps = ctaps;
  51. buflen = 0;
  52. reader = 0;
  53. tapptr = 0;
  54. tapcoeff = 0;
  55. srate = sr;
  56. output_gain = 1.0;
  57. max_gain = 1.0;
  58. }
  59. #define SAFETY (2)
  60. bool tapdelay::create(void)
  61. {
  62. #ifdef _DEBUG
  63. assert(tapbuf==0);
  64. assert(ntaps > 0);
  65. #endif
  66. if(tapbuf)
  67. return false; //or some informative errorval...
  68. if(ntaps <=0)
  69. return false;
  70. buflen = (unsigned int)((dtaps[ntaps-1].pos * srate) + SAFETY);
  71. tapbuf = new double[buflen];
  72. if(!tapbuf)
  73. return false;
  74. memset(tapbuf,0,buflen*sizeof(double));
  75. tapptr = new unsigned int[ntaps];
  76. if(!tapptr){
  77. delete [] tapbuf; tapbuf = 0;
  78. return false;
  79. }
  80. tapcoeff = new double[ntaps];
  81. if(!tapcoeff) {
  82. delete [] tapbuf; tapbuf = 0;
  83. delete [] tapptr; tapptr = 0;
  84. return false;
  85. }
  86. //copy taps data, and get scalefac from total amps
  87. double sum = 0.0;
  88. for(unsigned int i = 0;i < ntaps;i++){
  89. //RWD.10.98 allow zero taptime, for input mix control...
  90. if(dtaps[i].pos == 0.0)
  91. tapptr[i] = 0;
  92. else
  93. tapptr[i] = buflen - (int)(dtaps[i].pos * srate);
  94. tapcoeff[i] = dtaps[i].val;
  95. sum += fabs(tapcoeff[i]);
  96. #ifdef _DEBUG
  97. assert(tapptr[i] < buflen);
  98. #endif
  99. }
  100. //some idiot might give us empty taps! */
  101. if(sum == 0.0){
  102. delete [] tapbuf; tapbuf = 0;
  103. delete [] tapptr; tapptr = 0;
  104. delete [] tapcoeff; tapcoeff = 0;
  105. return false;
  106. }
  107. max_gain = (double)ntaps / sum;
  108. one_over_ntaps = 1.0 / (double)ntaps;
  109. return true;
  110. }
  111. double tapdelay::get_maxgain(void)
  112. {
  113. return max_gain;
  114. }
  115. void tapdelay::set_gain(double gain)
  116. {
  117. output_gain = gain;
  118. }
  119. double tapdelay::tick(double insam)
  120. {
  121. double val = 0.0;
  122. tapbuf[reader++] = insam;
  123. if(reader == buflen)
  124. reader = 0;
  125. for(unsigned int i = 0;i < ntaps;i++) {
  126. val += ((tapbuf[tapptr[i]++]) * (tapcoeff[i]));
  127. if(tapptr[i] == buflen)
  128. tapptr[i] = 0;
  129. }
  130. val *= one_over_ntaps;
  131. return val * output_gain;
  132. }
  133. tapdelay::~tapdelay()
  134. {
  135. delete [] tapbuf;
  136. delete [] tapptr;
  137. delete [] tapcoeff;
  138. }
  139. delay::delay(unsigned int len, double gain)
  140. {
  141. delbuf= 0;
  142. dgain = gain;
  143. ptr = 0;
  144. buflen = len;
  145. }
  146. delay::~delay()
  147. {
  148. delete delbuf;
  149. }
  150. bool delay::create(void)
  151. {
  152. if(buflen <= 0)
  153. return false;
  154. if(delbuf)
  155. return false;
  156. delbuf = new double[buflen];
  157. if(!delbuf) {
  158. return false;
  159. }
  160. memset(delbuf,0,buflen*sizeof(double));
  161. return true;
  162. }
  163. double delay::tick(double insam)
  164. {
  165. double val;
  166. val = delbuf[ptr];
  167. delbuf[ptr++] = insam;
  168. if(ptr==buflen)
  169. ptr = 0;
  170. return val*dgain;
  171. }
  172. //////////////////////////////////////////////////////////////////////
  173. // allpassfilter
  174. //////////////////////////////////////////////////////////////////////
  175. //global helper functions: really belong in a new cdplib...except it's nice to have proper bool retval
  176. //straight from Csound: nreverb (vdelay.c)
  177. static bool prime( int val )
  178. {
  179. int i, last;
  180. last = (int)sqrt( (double)val );
  181. for ( i = 3; i <= last; i+=2 ) {
  182. if ( (val % i) == 0 ) return false;
  183. }
  184. return true;
  185. }
  186. unsigned int to_prime(double dur,double sr)
  187. {
  188. unsigned int time = (unsigned int) (dur * sr);
  189. if(time % 2== 0) time += 1;
  190. while(!prime(time))
  191. time +=2;
  192. return time;
  193. }
  194. #define VMODMAX (0.5)
  195. //standard allpass, with optional pre_delay
  196. allpassfilter::allpassfilter(long sr,unsigned int buflen, double ingain,unsigned int predelay = 0)
  197. {
  198. vmod = 0.1;
  199. vfreq = 0.5;
  200. rvbuf1 = 0;
  201. pre_dline = 0;
  202. writer1 = reader1 = 0;
  203. sinelfo = 0;
  204. noiselfo = 0;
  205. srate = sr;
  206. rvblen = buflen + (unsigned int)(buflen * VMODMAX);
  207. gain = ingain;
  208. pre_delay = predelay;
  209. }
  210. bool allpassfilter::create(void)
  211. {
  212. if((gain < -1.0) || (gain > 1.0)) //do I want negative gain vals?
  213. return false;
  214. rvbuf1 = new double[rvblen];
  215. if(!rvbuf1 ){
  216. #ifdef _DEBUG
  217. printf("\nallpass: failed to allocate buffer size %d",rvblen);
  218. #endif
  219. return false;
  220. }
  221. if(pre_delay > 0){
  222. pre_dline = new delay(pre_delay,1.0);
  223. if(!pre_dline->create()){
  224. #ifdef _DEBUG
  225. printf("\nallpass: can't create pre_dline" );
  226. #endif
  227. delete []rvbuf1; rvbuf1 = 0;
  228. return false;
  229. }
  230. }
  231. memset(rvbuf1,0,rvblen*sizeof(double));
  232. sinelfo = new fastlfo();
  233. sinelfo->init((double) srate,0.0,0,1);
  234. sinelfo->set_WaveType(LFO_SINE);
  235. sinelfo->set_freq(vfreq);
  236. sinelfo->set_mod(1.0);
  237. noiselfo = new fastlfo();
  238. noiselfo->init((double) srate,0.0,0,1);
  239. noiselfo->set_WaveType(LFO_RAND_GAUSS);
  240. noiselfo->set_freq(vfreq * 2.5);
  241. noiselfo->set_mod(1.0);
  242. return true;
  243. }
  244. void allpassfilter::set_vmod(double amount)
  245. {
  246. double numod = VMODMAX;
  247. if(amount < numod)
  248. numod = amount;
  249. vmod = numod;
  250. }
  251. void allpassfilter::set_vfreq(double freq)
  252. {
  253. vfreq = freq;
  254. sinelfo->set_freq(vfreq);
  255. noiselfo->set_freq(vfreq * 2.5);
  256. }
  257. /* TODO: optimize this: separate funcs for pre-dline and plain */
  258. double allpassfilter::tick(double insamp)
  259. {
  260. double output, input;
  261. input = insamp;
  262. output = (-gain) * input;
  263. output += rvbuf1[reader1++];
  264. input += gain * output;
  265. if(pre_dline)
  266. rvbuf1[writer1++] = pre_dline->tick(input);
  267. else
  268. rvbuf1[writer1++] = input;
  269. if(reader1 == rvblen)
  270. reader1 = 0;
  271. if(writer1 == rvblen)
  272. writer1 = 0;
  273. return output;
  274. }
  275. /* TODO: implement this! */
  276. double allpassfilter::vtick(double insamp)
  277. {
  278. double output, input;
  279. input = insamp;
  280. output = (-gain) * input;
  281. output += rvbuf1[reader1++];
  282. input += gain * output;
  283. if(pre_dline)
  284. rvbuf1[writer1++] = pre_dline->tick(input);
  285. else
  286. rvbuf1[writer1++] = input;
  287. if(reader1 == rvblen)
  288. reader1 = 0;
  289. if(writer1 == rvblen)
  290. writer1 = 0;
  291. return output;
  292. }
  293. allpassfilter::~allpassfilter()
  294. {
  295. delete [] rvbuf1;
  296. delete pre_dline;
  297. }
  298. //////////////////////////////////////////////////////////////////////
  299. //// nested_allpass
  300. //overall delay = ap1.pre_delay + ap2.pre_deay + ap1.length + ap2.length + post_delay
  301. nested_allpass::nested_allpass(double srate,double lpfreq, unsigned int outertime, unsigned int time1, unsigned int time2,
  302. double gain, double gain1, double gain2,
  303. unsigned int delay1 = 0, unsigned int delay2 = 0)
  304. {
  305. outer_gain = gain;
  306. outer_time = outertime;
  307. ap1_gain = gain1;
  308. ap2_gain = gain2;
  309. ap1_length = time1;
  310. ap2_length = time2;
  311. ap1_delay = delay1;
  312. ap2_delay = delay2;
  313. buf = 0;
  314. if(ap2_gain == 0.0)
  315. ap2_length = 0;
  316. ap1 = ap2 = 0;
  317. writer = reader = 0;
  318. lp = 0;
  319. lpfreq_ = lpfreq;
  320. sr_ = srate;
  321. }
  322. nested_allpass::~nested_allpass()
  323. {
  324. delete [] buf;
  325. delete ap1;
  326. delete ap2;
  327. //RWD
  328. delete lp;
  329. }
  330. bool nested_allpass::create(void)
  331. {
  332. if(outer_gain < -1.0 || outer_gain > 1.0)
  333. return false;
  334. if(outer_time <= 0)
  335. return false;
  336. buf = new double[outer_time];
  337. if(!buf)
  338. return false;
  339. memset(buf,0,outer_time * sizeof(double));
  340. if(ap1_length > 0 && ap1_gain > 0.0){
  341. ap1 = new allpassfilter((long)sr_,ap1_length,ap1_gain,ap1_delay);
  342. if(!ap1->create()){
  343. delete [] buf; buf = 0;
  344. return false;
  345. }
  346. }
  347. if(ap2_length >0 && ap2_gain > 0.0){
  348. ap2 = new allpassfilter((long)sr_,ap2_length,ap2_gain,ap2_delay);
  349. if(!ap2->create()){
  350. delete ap1; ap1 = 0;
  351. delete [] buf; buf = 0;
  352. return false;
  353. }
  354. }
  355. // RWD experiment: internal absorption damping
  356. lp = new onepole(lpfreq_,sr_,LOW_PASS);
  357. if(!lp){
  358. delete ap1; ap1 = 0;
  359. delete ap2; ap2 = 0;
  360. delete [] buf; buf = 0;
  361. return false;
  362. }
  363. damping_ = false;
  364. return true;
  365. }
  366. //messy casts - sort this out later...
  367. double nested_allpass::tick(double insam)
  368. {
  369. double output, input,nest_out;
  370. input = insam;
  371. output = (-outer_gain) * input;
  372. output += buf[reader++];
  373. input += outer_gain * output;
  374. //input is to two allpasses, and the post_delay, which acts as the overall allpass
  375. if(!ap2) { //no second allpass, may be one or no first allpass
  376. if(ap1)
  377. nest_out = ap1->tick(input);
  378. else
  379. //behave as normal allpass
  380. nest_out = input;
  381. }
  382. else
  383. nest_out = ap2->tick(ap1->tick(input));
  384. //RWD experiment!
  385. if(damping_)
  386. buf[writer++] = lp->tick(nest_out);
  387. else
  388. buf[writer++] = nest_out;
  389. //wrap indices
  390. if(writer == outer_time)
  391. writer = 0;
  392. if(reader == outer_time)
  393. reader = 0;
  394. return output;
  395. }
  396. //////////////////////////////////////////////////////////////////////
  397. // lpcomb
  398. //////////////////////////////////////////////////////////////////////
  399. lpcomb::lpcomb(unsigned int buflen, double fbgain, double lpcoeff, double pre = 1.0)
  400. {
  401. combbuf = 0;
  402. lp = 0;
  403. gain = fbgain;
  404. lpgain = lpcoeff;
  405. rvblen = buflen;
  406. prescale = pre;
  407. reader1 = writer1 = 0;
  408. }
  409. bool lpcomb::create(void)
  410. {
  411. if(prescale <= 0.0)
  412. return false;
  413. if((gain < -1.0 ) || (gain > 1.0)) //do I want negative gain vals?
  414. return false;
  415. combbuf = new double[rvblen];
  416. if(!combbuf)
  417. return false;
  418. lp = new lowpass1(lpgain);
  419. if(!lp){
  420. delete [] combbuf; combbuf = 0;
  421. return false;
  422. }
  423. memset(combbuf,0,rvblen*sizeof(double));
  424. return true;
  425. }
  426. //wet output only, unscaled
  427. double lpcomb::tick(double insam)
  428. {
  429. double input,output,lpsig;
  430. input = insam * prescale;
  431. output = combbuf[reader1++]; //do gain scaling outside
  432. lpsig = lp->tick(output);
  433. combbuf[writer1++] = input + (gain * lpsig) ; //feedback scaled output
  434. if(writer1 == rvblen)
  435. writer1 = 0;
  436. if(reader1 == rvblen)
  437. reader1 = 0;
  438. return output;
  439. }
  440. lpcomb::~lpcomb()
  441. {
  442. delete [] combbuf;
  443. delete lp;
  444. }
  445. //////////////////////////////////////////////////////////////////////
  446. // lowpass : perhaps a bit ott as a class, but it allows fairly independent fiddling
  447. //////////////////////////////////////////////////////////////////////
  448. lowpass1::lowpass1(double filtgain)
  449. {
  450. temp = output = 0.0;
  451. gain = filtgain;
  452. }
  453. lowpass1::~lowpass1()
  454. {
  455. }
  456. //IIR lowpass
  457. inline double lowpass1::tick(double insam)
  458. {
  459. output = temp;
  460. temp = insam + (output * gain);
  461. return output;
  462. }
  463. // NB allows zero frequency: straight pass-through
  464. onepole::onepole(double freq,double srate, int low_high)
  465. {
  466. if(freq == 0.0){
  467. a1 = 1.0;
  468. a2 = 0.0;
  469. }
  470. else {
  471. b = 2.0 - cos(TWOPI * (freq/srate));
  472. a2 = sqrt((b*b) - 1.0) - b;
  473. a1 = 1.0 + a2;
  474. if(low_high==HIGH_PASS)
  475. a2 = -a2;
  476. }
  477. lastout = 0.0;
  478. }
  479. onepole::~onepole()
  480. {
  481. //nothing to do
  482. }
  483. double onepole::tick(double input)
  484. {
  485. double output;
  486. output = a1*input - a2*lastout;
  487. lastout = output;
  488. return output;
  489. }
  490. //uses code from CDP eq.c
  491. tonecontrol::tonecontrol(double frq,double dbfac,int type,double srate)
  492. {
  493. freq = frq;
  494. boost = dbfac;
  495. sr = srate;
  496. tc_type = type;
  497. x1 = x2 = y1 = y2 = 0.0;
  498. a0 = a1 = a2 = b1 = b2 = 0.0;
  499. }
  500. tonecontrol::~tonecontrol()
  501. {
  502. //nothing to do;
  503. }
  504. bool tonecontrol::create(void)
  505. {
  506. if(sr <= 0.0)
  507. return false;
  508. if(freq <= 0.0)
  509. return false;
  510. //normalize freq
  511. freq /= sr;
  512. switch(tc_type){
  513. case(LOW_SHELVE):
  514. lshelve();
  515. break;
  516. case(HIGH_SHELVE):
  517. hshelve();
  518. break;
  519. default:
  520. return false;
  521. break;
  522. }
  523. return true;
  524. }
  525. double tonecontrol::tick(double input)
  526. {
  527. double out;
  528. if(boost== 0.0)
  529. return input;
  530. out = ((a0 * input) + (a1 * x1) + (a2 * x2) - (b1 * y1) - (b2 * y2));
  531. x2 = x1;
  532. x1 = input;
  533. y2 = y1;
  534. y1 = out;
  535. return out;
  536. }
  537. void tonecontrol::lshelve(void)
  538. {
  539. double a, A, F, tmp, b0, recipb0, asq, F2, gamma2, siggam2, gam2p1;
  540. double gamman, gammad, ta0, ta1, ta2, tb0, tb1, tb2, aa1, ab1;
  541. a = tan(PI * (freq - 0.25)); /* Warp factor */
  542. asq = a * a;
  543. A = pow(10.0, boost/20.0); /* Cvt dB to factor */
  544. if((boost < 6.0) && (boost > -6.0)) F = sqrt(A);
  545. else if (A > 1.0) F = A/sqrt(2.0);
  546. else F = A * sqrt(2.0);
  547. /* If |boost/cut| < 6dB, then doesn't make sense to use 3dB point.
  548. Use of root makes bandedge at half the boost/cut amount
  549. */
  550. F2 = F * F;
  551. tmp = A * A - F2;
  552. if(fabs(tmp) <= SPN) gammad = 1;
  553. else gammad = pow( (F2 - 1)/ tmp, 0.25); /* Fourth root */
  554. gamman = sqrt(A) * gammad;
  555. /* Once for the numerator */
  556. gamma2 = gamman * gamman;
  557. gam2p1 = 1 + gamma2;
  558. siggam2 = 2 * ROOT2O2 * gamman;
  559. ta0 = gam2p1 + siggam2;
  560. ta1 = -2 * (1 - gamma2);
  561. ta2 = gam2p1 - siggam2;
  562. /* And again for the denominator */
  563. gamma2 = gammad * gammad;
  564. gam2p1 = 1 + gamma2;
  565. siggam2 = 2 * ROOT2O2 * gammad;
  566. tb0 = gam2p1 + siggam2;
  567. tb1 = -2 * (1 - gamma2);
  568. tb2 = gam2p1 - siggam2;
  569. /* Now bilinear transform to proper centre frequency */
  570. aa1 = a * ta1;
  571. a0 = ta0 + aa1 + asq * ta2;
  572. a1 = 2 * a * (ta0 + ta2) + (1 + asq) * ta1;
  573. a2 = asq * ta0 + aa1 + ta2;
  574. ab1 = a * tb1;
  575. b0 = tb0 + ab1 + asq * tb2;
  576. b1 = 2 * a * (tb0 + tb2) + (1 + asq) * tb1;
  577. b2 = asq * tb0 + ab1 + tb2;
  578. /* Normalise b0 to 1.0 for realisability */
  579. recipb0 = 1 / b0;
  580. a0 *= recipb0;
  581. a1 *= recipb0;
  582. a2 *= recipb0;
  583. b1 *= recipb0;
  584. b2 *= recipb0;
  585. }
  586. void tonecontrol::hshelve(void)
  587. {
  588. double a, A, F, tmp, b0, recipb0, asq, F2, gamma2, siggam2, gam2p1;
  589. double gamman, gammad, ta0, ta1, ta2, tb0, tb1, tb2, aa1, ab1;
  590. a = tan(PI * (freq - 0.25)); /* Warp factor */
  591. asq = a * a;
  592. A = pow(10.0, boost/20.0); /* Cvt dB to factor */
  593. if(boost < 6.0 && boost > -6.0) F = sqrt(A);
  594. else if (A > 1.0) F = A/sqrt(2.0);
  595. else F = A * sqrt(2.0);
  596. /* If |boost/cut| < 6dB, then doesn't make sense to use 3dB point.
  597. Use of root makes bandedge at half the boost/cut amount
  598. */
  599. F2 = F * F;
  600. tmp = A * A - F2;
  601. if(fabs(tmp) <= SPN) gammad = 1;
  602. else gammad = pow( (F2 - 1)/ tmp, 0.25); /* Fourth root */
  603. gamman = sqrt(A) * gammad;
  604. /* Once for the numerator */
  605. gamma2 = gamman * gamman;
  606. gam2p1 = 1 + gamma2;
  607. siggam2 = 2 * ROOT2O2 * gamman;
  608. ta0 = gam2p1 + siggam2;
  609. ta1 = -2 * (1 - gamma2);
  610. ta2 = gam2p1 - siggam2;
  611. ta1 = -ta1;
  612. /* And again for the denominator */
  613. gamma2 = gammad * gammad;
  614. gam2p1 = 1 + gamma2;
  615. siggam2 = 2 * ROOT2O2 * gammad;
  616. tb0 = gam2p1 + siggam2;
  617. tb1 = -2 * (1 - gamma2);
  618. tb2 = gam2p1 - siggam2;
  619. tb1 = -tb1;
  620. /* Now bilinear transform to proper centre frequency */
  621. aa1 = a * ta1;
  622. a0 = ta0 + aa1 + asq * ta2;
  623. a1 = 2 * a * (ta0 + ta2) + (1 + asq) * ta1;
  624. a2 = asq * ta0 + aa1 + ta2;
  625. ab1 = a * tb1;
  626. b0 = tb0 + ab1 + asq * tb2;
  627. b1 = 2 * a * (tb0 + tb2) + (1 + asq) * tb1;
  628. b2 = asq * tb0 + ab1 + tb2;
  629. /* Normalise b0 to 1.0 for realisability */
  630. recipb0 = 1 / b0;
  631. a0 *= recipb0;
  632. a1 *= recipb0;
  633. a2 *= recipb0;
  634. b1 *= recipb0;
  635. b2 *= recipb0;
  636. }
  637. /***************** GARDNER DIFFUSERS ***************/
  638. // NOTE: the published Gardner designs are here modified by adding a onepole lp filter
  639. // in the internal outer feedback loop of each nested allpass filter.
  640. // When combined with the overall feedback filter, this will of course reduce the reverb decay time.
  641. // The option exists to bypass this overall feedback filter, and rely solely on the internal ones.
  642. // NOTE: to get an infinite reverb, all feedback filters have to be bypassed by setting lp_freq to 0.0
  643. // otherwise, the output will still decay eventually !
  644. small_diffuser::small_diffuser(unsigned int pre_delay,
  645. const NESTDATA *apdata1,
  646. const NESTDATA *apdata2,double fb_gain,double lp_freq,double srate){
  647. ap1_data = *apdata1;
  648. ap2_data = *apdata2;
  649. predelay_time = pre_delay;
  650. lpgain = fb_gain;
  651. lpfreq = lp_freq;
  652. ap1 = ap2 = 0;
  653. lp1 = 0;
  654. predelay = 0;
  655. out1 = out2 = 0.0;
  656. sr = srate;
  657. damping_ = false;
  658. }
  659. small_diffuser::~small_diffuser()
  660. {
  661. delete ap1;
  662. delete ap2;
  663. delete predelay;
  664. delete lp1;
  665. }
  666. bool small_diffuser::create(void)
  667. {
  668. if(ap1_data.time1 == 0 || ap1_data.gain1 <= 0.0){
  669. #ifdef _DEBUG
  670. printf("\ndiffuser: bad parameters(1)");
  671. #endif
  672. return false;
  673. }
  674. if(ap1_data.time2 ==0 || ap1_data.gain2 <= 0.0){
  675. #ifdef _DEBUG
  676. printf("\ndiffuser: bad parameters(2)");
  677. #endif
  678. return false;
  679. }
  680. if(ap2_data.time1 == 0 || ap2_data.gain1 < 0.0){
  681. #ifdef _DEBUG
  682. printf("\ndiffuser: bad parameters(3)");
  683. #endif
  684. return false;
  685. }
  686. if(ap2_data.time2 ==0 || ap2_data.gain2 < 0.0){
  687. #ifdef _DEBUG
  688. printf("\ndiffuser: bad parameters(4)");
  689. #endif
  690. return false;
  691. }
  692. if(sr <=0.0){
  693. #ifdef _DEBUG
  694. printf("\ndiffuser: bad srate parameter)");
  695. #endif
  696. return false;
  697. }
  698. if(lpfreq <0.0){
  699. #ifdef _DEBUG
  700. printf("\ndiffuser: bad freq parameter)");
  701. #endif
  702. return false;
  703. }
  704. ap1 = new nested_allpass(sr,lpfreq,ap1_data.time1,ap1_data.time2,ap1_data.time3,
  705. ap1_data.gain1,ap1_data.gain2,ap1_data.gain3);
  706. if(!ap1->create()){
  707. #ifdef _DEBUG
  708. printf("\ndiffuser: can't create first allpass");
  709. #endif
  710. return false;
  711. }
  712. if(ap2_data.gain1 != 0.0){ //allow ap to eliminate second block
  713. ap2 = new nested_allpass(sr,lpfreq,ap2_data.time1,ap2_data.time2,ap2_data.time3,
  714. ap2_data.gain1,ap2_data.gain2,ap2_data.gain3);
  715. if(!ap2->create()){
  716. #ifdef _DEBUG
  717. printf("\ndiffuser: can't create second allpass");
  718. #endif
  719. delete ap1; ap1 = 0;
  720. return false;
  721. }
  722. }
  723. if(predelay_time > 0){
  724. predelay = new delay(predelay_time,1.0);
  725. if(!predelay->create()){
  726. #ifdef _DEBUG
  727. printf("\ndiffuser: can't create predelay");
  728. #endif
  729. delete ap1; ap1 = 0;
  730. delete ap2; ap2 = 0;
  731. return false;
  732. }
  733. }
  734. // NB if lpfreq == 0, onepole is no-op - returns input
  735. lp1 = new onepole(lpfreq,sr,LOW_PASS);
  736. if(lp1 == 0){
  737. delete [] predelay; predelay = 0;
  738. delete ap1; ap1 = 0;
  739. delete ap2; ap2 = 0;
  740. return false;
  741. }
  742. ap1->set_damping(damping_);
  743. ap2->set_damping(damping_);
  744. return true;
  745. }
  746. double small_diffuser::tick(double insam)
  747. {
  748. double filter_out;
  749. double lp_in;
  750. double output;
  751. double ip;
  752. // may only contain one nested allpass filter:
  753. // input to filter is either out1 or out2
  754. if(ap2)
  755. lp_in = out2; //= both in series
  756. else
  757. lp_in = out1;
  758. // RWD NOTE: if the damping_ mechanism is preferred, this filter can be omitted and ...
  759. filter_out = lp1->tick(lp_in);
  760. // ... just use this
  761. // filter_out = lp_in ;
  762. ip = insam + lpgain * filter_out;
  763. if(predelay)
  764. ip = predelay->tick(ip);
  765. out1 = ap1->tick( ip);
  766. if(ap2){
  767. out2 = ap2->tick(out1);
  768. output = (out1 + out2) * 0.5;
  769. }
  770. else
  771. output = out1;
  772. return output;
  773. }
  774. //post-delay almost certainly doe not need to be prime...
  775. medium_diffuser::medium_diffuser(double post_delay,const NESTDATA *apdata1,
  776. const NESTDATA *apdata2,
  777. double gain,
  778. double lp_freq,
  779. double srate)
  780. {
  781. ap1_data = *apdata1;
  782. ap2_data = *apdata2;
  783. postdelay_time = to_prime(post_delay,srate);
  784. md_gain = gain;
  785. lpfreq = lp_freq;
  786. ap1 = ap2 = 0;
  787. ap3 = 0;
  788. lp1 = 0;
  789. delay1 = delay2 = postdelay = 0;
  790. sr = srate;
  791. out1 = out2 =out3 = 0.0;
  792. damping_ = false;
  793. }
  794. medium_diffuser::~medium_diffuser()
  795. {
  796. delete ap1;
  797. delete ap2;
  798. delete ap3;
  799. delete lp1;
  800. delete delay1;
  801. delete delay2;
  802. }
  803. bool medium_diffuser::create(void)
  804. {
  805. if(ap1_data.time1 == 0 || ap1_data.gain1 <= 0.0){
  806. #ifdef _DEBUG
  807. printf("\nmedium_diffuser: bad parameters(1)");
  808. #endif
  809. return false;
  810. }
  811. if(ap1_data.time2 ==0 || ap1_data.gain2 <= 0.0){
  812. #ifdef _DEBUG
  813. printf("\nmedium diffuser: bad parameters(2)");
  814. #endif
  815. return false;
  816. }
  817. if(ap2_data.time1 == 0 || ap2_data.gain1 < 0.0){
  818. #ifdef _DEBUG
  819. printf("\nmedium diffuser: bad parameters(3)");
  820. #endif
  821. return false;
  822. }
  823. if(ap2_data.time2 ==0 || ap2_data.gain2 < 0.0){
  824. #ifdef _DEBUG
  825. printf("\nmedium diffuser: bad parameters(4)");
  826. #endif
  827. return false;
  828. }
  829. if(sr <=0.0){
  830. #ifdef _DEBUG
  831. printf("\nmedium diffuser: bad srate parameter)");
  832. #endif
  833. return false;
  834. }
  835. if(lpfreq <0.0){
  836. #ifdef _DEBUG
  837. printf("\nmedium diffuser: bad freq parameter)");
  838. #endif
  839. return false;
  840. }
  841. ap1 = new nested_allpass(sr,lpfreq,ap1_data.time1,ap1_data.time2,ap1_data.time3,
  842. ap1_data.gain1,ap1_data.gain2,ap1_data.gain3);
  843. if(!ap1->create()){
  844. #ifdef _DEBUG
  845. printf("\nmedium diffuser: can't create first diffuser");
  846. #endif
  847. return false;
  848. }
  849. ap2 = new nested_allpass(sr,lpfreq,ap2_data.time1,ap2_data.time2,ap2_data.time3,
  850. ap2_data.gain1,ap2_data.gain2,ap2_data.gain3);
  851. if(!ap2->create()){
  852. #ifdef _DEBUG
  853. printf("\nmedium diffuser: can't create second diffuser");
  854. #endif
  855. delete ap1; ap1 = 0;
  856. return false;
  857. }
  858. ap3 = new allpassfilter((long)sr,to_prime(0.03,sr),0.5,to_prime(0.005,sr));
  859. if(!ap3->create()){
  860. #ifdef _DEBUG
  861. printf("\nmedium diffuser: can't create internal allpass filter");
  862. #endif
  863. delete ap1; ap1 = 0;
  864. delete ap2; ap2 = 0;
  865. return false;
  866. }
  867. if(postdelay_time > 0){
  868. postdelay = new delay(postdelay_time,1.0);
  869. if(!postdelay->create()){
  870. #ifdef _DEBUG
  871. printf("\nmedium diffuser: can't create postdelay");
  872. #endif
  873. delete ap1; ap1 = 0;
  874. delete ap2; ap2 = 0;
  875. delete ap3; ap3 = 0;
  876. return false;
  877. }
  878. }
  879. //internal fixed delays
  880. delay1 = new delay(to_prime(/*0.007*/0.067,sr),1.0);
  881. if(!delay1->create()){
  882. #ifdef _DEBUG
  883. printf("\nmedium diffuser: can't create internal delay1");
  884. #endif
  885. delete ap1; ap1 = 0;
  886. delete ap2; ap2 = 0;
  887. delete ap3; ap3 = 0;
  888. delete [] postdelay; postdelay = 0;
  889. return false;
  890. }
  891. delay2 = new delay(to_prime(0.015,sr),1.0);
  892. if(!delay2->create()){
  893. #ifdef _DEBUG
  894. printf("\nmedium diffuser: can't create internal delay2");
  895. #endif
  896. delete ap1; ap1 = 0;
  897. delete ap2; ap2 = 0;
  898. delete ap3; ap3 = 0;
  899. delete [] postdelay; postdelay = 0;
  900. delete delay1; delay1 = 0;
  901. return false;
  902. }
  903. lp1 = new onepole(lpfreq,sr,LOW_PASS);
  904. if(lp1 == 0){
  905. delete ap1; ap1 = 0;
  906. delete ap2; ap2 = 0;
  907. delete ap3; ap3 = 0;
  908. delete [] postdelay; postdelay = 0;
  909. delete delay1; delay1 = 0;
  910. delete delay2; delay2 = 0;
  911. return false;
  912. }
  913. if(lpfreq == 0.0)
  914. damping_ = false;
  915. ap1->set_damping(damping_);
  916. ap2->set_damping(damping_);
  917. return true;
  918. }
  919. double medium_diffuser::tick(double insam)
  920. {
  921. double filter_out;
  922. double output;
  923. //feedback from postdelay, thru lp filter
  924. // RWD NOTE: if the damping_ mechanism is preferred, this filter can be omitted and...
  925. filter_out = md_gain * lp1->tick(postdelay->tick(out3));
  926. // ... just use this
  927. //filter_out = (float)(md_gain * postdelay->tick(out3));
  928. //first nested-allpass, takes input plus feedback
  929. out1 = ap1->tick(insam + filter_out);
  930. //inner allpass with predelay, followed by plain delay
  931. out2 = delay1->tick(ap3->tick(out1));
  932. //second nested-allpass, takes direct input
  933. out3 = ap2->tick(insam + md_gain * delay2->tick(out2));
  934. output = 0.5 * (out1 + out2 + out3);
  935. return output;
  936. }
  937. large_diffuser::large_diffuser(const NESTDATA *apdata1,
  938. const NESTDATA *apdata2,
  939. double gain,
  940. double lp_freq,
  941. double srate)
  942. {
  943. ap1_data = *apdata1;
  944. ap2_data = *apdata2;
  945. ld_gain = gain;
  946. lpfreq = lp_freq;
  947. ap1 = ap2 = 0;
  948. ap3 = ap4 = 0;
  949. lp1 = 0;
  950. delay1 = delay2 = delay3 = delay4 = 0;
  951. sr = srate;
  952. out1 = out2 =out3 = 0.0;
  953. damping_ = false;
  954. }
  955. large_diffuser::~large_diffuser()
  956. {
  957. delete ap1;
  958. delete ap2;
  959. delete ap3;
  960. delete ap4;
  961. delete lp1;
  962. delete delay1;
  963. delete delay2;
  964. delete delay3;
  965. delete delay4;
  966. }
  967. bool large_diffuser::create(void)
  968. {
  969. if(ap1_data.time1 == 0 || ap1_data.gain1 <= 0.0){
  970. #ifdef _DEBUG
  971. printf("\nmedium_diffuser: bad parameters(1)");
  972. #endif
  973. return false;
  974. }
  975. if(ap1_data.time2 ==0 || ap1_data.gain2 <= 0.0){
  976. #ifdef _DEBUG
  977. printf("\nmedium diffuser: bad parameters(2)");
  978. #endif
  979. return false;
  980. }
  981. if(ap2_data.time1 == 0 || ap2_data.gain1 < 0.0){
  982. #ifdef _DEBUG
  983. printf("\nmedium diffuser: bad parameters(3)");
  984. #endif
  985. return false;
  986. }
  987. if(ap2_data.time2 ==0 || ap2_data.gain2 < 0.0){
  988. #ifdef _DEBUG
  989. printf("\nmedium diffuser: bad parameters(4)");
  990. #endif
  991. return false;
  992. }
  993. if(sr <=0.0){
  994. #ifdef _DEBUG
  995. printf("\nmedium diffuser: bad srate parameter)");
  996. #endif
  997. return false;
  998. }
  999. if(lpfreq <0.0){
  1000. #ifdef _DEBUG
  1001. printf("\nmedium diffuser: bad freq parameter)");
  1002. #endif
  1003. return false;
  1004. }
  1005. ap1 = new nested_allpass(sr,lpfreq,ap1_data.time1,ap1_data.time2,ap1_data.time3,
  1006. ap1_data.gain1,ap1_data.gain2,ap1_data.gain3);
  1007. if(!ap1->create()){
  1008. #ifdef _DEBUG
  1009. printf("\nlarge diffuser: can't create first nested_allpass");
  1010. #endif
  1011. return false;
  1012. }
  1013. ap2 = new nested_allpass(sr,lpfreq,ap2_data.time1,ap2_data.time2,ap2_data.time3,
  1014. ap2_data.gain1,ap2_data.gain2,ap2_data.gain3);
  1015. if(!ap2->create()){
  1016. #ifdef _DEBUG
  1017. printf("\nlarge diffuser: can't create second netsed_allpass");
  1018. #endif
  1019. cleanup();
  1020. return false;
  1021. }
  1022. ap3 = new allpassfilter((long) sr,to_prime(0.008,sr),0.3);
  1023. if(!ap3->create()){
  1024. #ifdef _DEBUG
  1025. printf("\nlarge diffuser: can't create first internal allpass filter");
  1026. #endif
  1027. cleanup();
  1028. return false;
  1029. }
  1030. ap4 = new allpassfilter((long)sr,to_prime(0.012,sr),0.3);
  1031. if(!ap4->create()){
  1032. #ifdef _DEBUG
  1033. printf("\nlarge diffuser: can't create second internal allpass filter");
  1034. #endif
  1035. cleanup();
  1036. return false;
  1037. }
  1038. //internal fixed delays
  1039. delay1 = new delay((unsigned int)(0.004 * sr),1.0);
  1040. if(!delay1->create()){
  1041. #ifdef _DEBUG
  1042. printf("\nlarge diffuser: can't create internal delay1");
  1043. #endif
  1044. cleanup();
  1045. return false;
  1046. }
  1047. delay2 = new delay((unsigned int)(0.017 * sr),1.0);
  1048. if(!delay2->create()){
  1049. #ifdef _DEBUG
  1050. printf("\nlarge diffuser: can't create internal delay2");
  1051. #endif
  1052. cleanup();
  1053. return false;
  1054. }
  1055. delay3 = new delay((unsigned int)(0.031 * sr),1.0);
  1056. if(!delay3->create()){
  1057. #ifdef _DEBUG
  1058. printf("\nlarge diffuser: can't create internal delay3");
  1059. #endif
  1060. cleanup();
  1061. return false;
  1062. }
  1063. delay4 = new delay((unsigned int)(0.003 * sr),1.0);
  1064. if(!delay4->create()){
  1065. #ifdef _DEBUG
  1066. printf("\nlarge diffuser: can't create internal delay4");
  1067. #endif
  1068. cleanup();
  1069. return false;
  1070. }
  1071. lp1 = new onepole(lpfreq,sr,LOW_PASS);
  1072. if(lp1 == 0){
  1073. cleanup();
  1074. return false;
  1075. }
  1076. if(lpfreq == 0.0)
  1077. damping_ = false;
  1078. ap1->set_damping(damping_);
  1079. ap2->set_damping(damping_);
  1080. return true;
  1081. }
  1082. void large_diffuser::cleanup()
  1083. {
  1084. delete lp1; lp1 = 0;
  1085. delete delay4; delay4 = 0;
  1086. delete delay3; delay3 = 0;
  1087. delete delay2; delay2 = 0;
  1088. delete delay1; delay1 = 0;
  1089. delete ap4; ap4 = 0;
  1090. delete ap3; ap3 = 0;
  1091. delete ap2; ap2 = 0;
  1092. delete ap1; ap1 = 0;
  1093. }
  1094. // NOTE: the three output taps from the diffuser can lead to discrete slap-back echoes in the output.
  1095. // possibly authentic, but may not suit all purposes. See rmverb.cpp: some delay lengths reduced from Gardner.
  1096. // This is possible because delays are discrete: they do not share single delay line buffer.
  1097. // true also of medium diffuser, but not so apparent as delays are smaller
  1098. double large_diffuser::tick(double insam)
  1099. {
  1100. double filter_out;
  1101. double output;
  1102. //feedback from lpfilter
  1103. // RWD NOTE: if the damping_ mechanism is preferred, this filter can be omitted and ...
  1104. filter_out = ld_gain * lp1->tick(out3);
  1105. // ... just use this
  1106. //filter_out = (float)(ld_gain * out3);
  1107. //first tap, from two plain allpasses, and trailing delay
  1108. out1 = delay1->tick(ap4->tick(ap3->tick(insam + filter_out)));
  1109. //second tap, from first nested allpass and delays at entrance and exit
  1110. out2 = delay3->tick(ap1->tick(delay2->tick(out1)));
  1111. //third tap, from second nested-allpass with leading delay
  1112. out3 = ap2->tick(delay4->tick(out2));
  1113. //out3 also goes into lpfilter... see above
  1114. //prescribed scale factors from Gardner
  1115. output = (out1 * 0.34) + (out2 * 0.14) + (out3 * 0.14);
  1116. // this seems to give relatively soft reverb tail: could try this:
  1117. //output = (float)((out1 * 0.7) + (out2 * 0.25) + (out3 * 0.25));
  1118. return output;
  1119. }
  1120. moorer::moorer(const MOORERDATA *pdata,double reverbtime,double damping,double srate)
  1121. {
  1122. mdata = *pdata;
  1123. reverb_time = reverbtime;
  1124. dampfac = damping;
  1125. sr = srate;
  1126. comb1 = comb2 = comb3 = comb4 = comb5 = comb6 = 0;
  1127. ap1 = ap2 = ap3 = ap4 = 0;
  1128. out = 0.0;
  1129. }
  1130. moorer::~moorer()
  1131. {
  1132. delete comb1;
  1133. delete comb2;
  1134. delete comb3;
  1135. delete comb4;
  1136. delete comb5;
  1137. delete comb6;
  1138. delete ap1;
  1139. delete ap2;
  1140. delete ap3;
  1141. delete ap4;
  1142. }
  1143. bool moorer::create(void)
  1144. {
  1145. fgain1 = 0.42 * dampfac;
  1146. fgain2 = 0.46 * dampfac;
  1147. fgain3 = 0.48 * dampfac;
  1148. fgain4 = 0.49 * dampfac;
  1149. fgain5 = 0.50 * dampfac;
  1150. fgain6 = 0.52 * dampfac;
  1151. scalefac = (1.0 / 6.0);
  1152. cgain1 = exp(log(0.001)*(mdata.ctime1/reverb_time)) * (1. - fgain1);
  1153. cgain2 = exp(log(0.001)*(mdata.ctime2/reverb_time)) * (1. - fgain2);
  1154. cgain3 = exp(log(0.001)*(mdata.ctime3/reverb_time)) * (1. - fgain3);
  1155. cgain4 = exp(log(0.001)*(mdata.ctime4/reverb_time)) * (1. - fgain4);
  1156. cgain5 = exp(log(0.001)*(mdata.ctime5/reverb_time)) * (1. - fgain5);
  1157. cgain6 = exp(log(0.001)*(mdata.ctime6/reverb_time)) * (1. - fgain6);
  1158. comb1 = new lpcomb(to_prime(mdata.ctime1,sr),cgain1,fgain1,1.0);
  1159. comb2 = new lpcomb(to_prime(mdata.ctime2,sr),cgain2,fgain2,1.0);
  1160. comb3 = new lpcomb(to_prime(mdata.ctime3,sr),cgain3,fgain3,1.0);
  1161. comb4 = new lpcomb(to_prime(mdata.ctime4,sr),cgain4,fgain4,1.0);
  1162. comb5 = new lpcomb(to_prime(mdata.ctime5,sr),cgain5,fgain5,1.0);
  1163. comb6 = new lpcomb(to_prime(mdata.ctime6,sr),cgain6,fgain6,1.0);
  1164. ap1 = new allpassfilter((long)sr,to_prime(mdata.atime1,sr),-0.6,0);
  1165. ap2 = new allpassfilter((long)sr,to_prime(mdata.atime2,sr),0.4,0);
  1166. ap3 = new allpassfilter((long)sr,to_prime(mdata.atime3,sr),-0.61,0);
  1167. ap4 = new allpassfilter((long)sr,to_prime(mdata.atime4,sr),0.39,0);
  1168. if(!
  1169. (comb1->create()
  1170. && comb2->create()
  1171. && comb3->create()
  1172. && comb4->create()
  1173. && comb5->create()
  1174. && comb6->create()
  1175. && ap1->create()
  1176. && ap2->create()
  1177. && ap3->create()
  1178. && ap4->create()
  1179. )) {
  1180. cleanup();
  1181. return false;
  1182. }
  1183. return true;
  1184. }
  1185. double moorer::tick(double insam)
  1186. {
  1187. out = comb1->tick(insam) +
  1188. comb2->tick(insam) +
  1189. comb3->tick(insam) +
  1190. comb4->tick(insam) +
  1191. comb5->tick(insam) +
  1192. comb6->tick(insam)
  1193. ;
  1194. out *= scalefac;
  1195. out = ap4->tick(ap3->tick(ap2->tick(ap1->tick(out))));
  1196. return out;
  1197. }
  1198. void moorer::cleanup()
  1199. {
  1200. delete comb6; comb6 = 0;
  1201. delete comb5; comb5 = 0;
  1202. delete comb4; comb4 = 0;
  1203. delete comb3; comb3 = 0;
  1204. delete comb2; comb2 = 0;
  1205. delete comb1; comb1 = 0;
  1206. delete ap4; ap4 = 0;
  1207. delete ap3; ap3 = 0;
  1208. delete ap2; ap2 = 0;
  1209. delete ap1; ap1 = 0;
  1210. }
  1211. /* vmtdelay *******************************/
  1212. vcomb4::vcomb4()
  1213. {
  1214. dl_buf = 0;
  1215. dl_length = 0;
  1216. dl_input_index = 0;
  1217. dl_srate = 0.0;
  1218. }
  1219. vcomb4::~vcomb4()
  1220. {
  1221. if(dl_buf && dl_length > 0)
  1222. delete [] dl_buf;
  1223. }
  1224. bool vcomb4::init(long srate,double length_secs)
  1225. {
  1226. unsigned long len_frames = (unsigned long)(srate * length_secs );
  1227. if(len_frames == 0)
  1228. return false;
  1229. /* round upwards to allow for interpolation */
  1230. len_frames++;
  1231. /* reject init if already created*/
  1232. /* TODO: more sexy error checking/reporting... */
  1233. if(dl_buf)
  1234. return false;
  1235. try {
  1236. dl_buf = new double[len_frames];
  1237. }
  1238. catch(...){
  1239. return false;
  1240. }
  1241. /* for VC 6 */
  1242. if(dl_buf == 0)
  1243. return false;
  1244. for(unsigned long i = 0; i < len_frames;i++)
  1245. dl_buf[i] = 0.0;
  1246. dl_length = len_frames;
  1247. dl_input_index = 0;
  1248. dl_srate = srate;
  1249. gain = 0.5;
  1250. return true;
  1251. }
  1252. bool vcomb4::init(const MOORERDATA *p_mdata,double reverbtime,double damping,double sr)
  1253. {
  1254. if(!init((long) sr,reverbtime))
  1255. return false;
  1256. return true;
  1257. }
  1258. double vcomb4::tick(double vdelay_1,double vdelay_2,double vdelay_3,double vdelay_4,double feedback,double input)
  1259. {
  1260. unsigned long base_readpos1,base_readpos2,base_readpos3,base_readpos4;
  1261. unsigned long next_index1,next_index2,next_index3,next_index4;
  1262. double vlength,dlength,frac;
  1263. double readpos1,readpos2,readpos3,readpos4;
  1264. double* buf = dl_buf;
  1265. dlength = (double) dl_length; /* get maxlen, save a cast later on */
  1266. /* read pointer is vlength ~behind~ write pointer */
  1267. /* tap1*/
  1268. vlength = dlength - (vdelay_1 * dl_srate);
  1269. vlength = vlength < dlength ? vlength : dlength; /* clip vdelay to max del length */
  1270. readpos1 = dl_input_index + vlength;
  1271. base_readpos1 = (unsigned long) ( readpos1);
  1272. if(base_readpos1 >= dl_length) /* wrap dl indices */
  1273. base_readpos1 -= dl_length;
  1274. next_index1 = base_readpos1 + 1;
  1275. if(next_index1 >= dl_length)
  1276. next_index1 -= dl_length;
  1277. /*tap2*/
  1278. vlength = dlength - (vdelay_2 * dl_srate);
  1279. vlength = vlength < dlength ? vlength : dlength;
  1280. readpos2 = dl_input_index + vlength;
  1281. base_readpos2 = (unsigned long) ( readpos2);
  1282. if(base_readpos2 >= dl_length) /* wrap dl indices */
  1283. base_readpos2 -= dl_length;
  1284. next_index2 = base_readpos2 + 1;
  1285. if(next_index2 >= dl_length)
  1286. next_index2 -= dl_length;
  1287. /*tap3*/
  1288. vlength = dlength - (vdelay_3 * dl_srate);
  1289. vlength = vlength < dlength ? vlength : dlength;
  1290. readpos3 = dl_input_index + vlength;
  1291. base_readpos3 = (unsigned long) ( readpos3);
  1292. if(base_readpos3 >= dl_length) /* wrap dl indices */
  1293. base_readpos3 -= dl_length;
  1294. next_index3 = base_readpos3 + 1;
  1295. if(next_index3 >= dl_length)
  1296. next_index3 -= dl_length;
  1297. /* tap4 */
  1298. vlength = dlength - (vdelay_4 * dl_srate);
  1299. vlength = vlength < dlength ? vlength : dlength;
  1300. readpos4 = dl_input_index + vlength;
  1301. base_readpos4 = (unsigned long) ( readpos4);
  1302. if(base_readpos4 >= dl_length) /* wrap dl indices */
  1303. base_readpos4 -= dl_length;
  1304. next_index4 = base_readpos4 + 1;
  1305. if(next_index4 >= dl_length)
  1306. next_index4 -= dl_length;
  1307. double outsum = 0.0;
  1308. fb1 *= feedback;
  1309. fb2 *= feedback;
  1310. fb3 *= feedback;
  1311. fb4 *= feedback;
  1312. /* basic interp of variable delay pos */
  1313. frac = readpos1 - (int) readpos1;
  1314. outsum += fb1 * (buf[base_readpos1]+((buf[next_index1] - buf[base_readpos1]) * frac));
  1315. frac = readpos2 - (int) readpos2;
  1316. outsum += fb2 * (buf[base_readpos2]+((buf[next_index2] - buf[base_readpos2]) * frac));
  1317. frac = readpos3 - (int) readpos3;
  1318. outsum += fb3 * (buf[base_readpos3]+((buf[next_index3] - buf[base_readpos3]) * frac));
  1319. frac = readpos4 - (int) readpos4;
  1320. outsum += fb4 * (buf[base_readpos4]+((buf[next_index4] - buf[base_readpos4]) * frac));
  1321. /* how do we scale all this?*/
  1322. input += gain * (outsum);
  1323. /* add in new sample + fraction of ouput, unscaled, for minimum decay at max feedback */
  1324. buf[dl_input_index++] = input + outsum * 0.25;
  1325. if(dl_input_index == dl_length)
  1326. dl_input_index = 0;
  1327. return input + outsum * 0.25;
  1328. }