smalldiff.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. //smalldiff.cpp
  21. //implements diffuse reverberator for small rooms, based on gardner nested allpasses
  22. #include "reverberator.h"
  23. small_diffuser::small_diffuser(unsigned int pre_delay,
  24. const NESTDATA *apdata1,
  25. const NESTDATA *apdata2,double fb_gain,double lp_coeff){
  26. ap1_data = *apdata1;
  27. ap2_data = *apdata2;
  28. predelay_time = pre_delay;
  29. lpgain = fb_gain;
  30. lpcoeff = lp_coeff;
  31. ap1 = ap2 = 0;
  32. lp1 = 0;
  33. predelay = 0;
  34. out1 = out2 = 0.0f;
  35. }
  36. small_diffuser::~small_diffuser()
  37. {
  38. delete ap1;
  39. delete ap2;
  40. if(predelay)
  41. delete predelay;
  42. delete lp1;
  43. }
  44. bool small_diffuser::create(void)
  45. {
  46. if(ap1_data.time1 == 0 || ap1_data.gain1 <= 0.0)
  47. return false;
  48. if(ap1_data.time2 ==0 || ap1_data.gain2 <= 0.0)
  49. return false;
  50. if(ap2_data.time1 == 0 || ap2_data.gain1 < 0.0)
  51. return false;
  52. if(ap2_data.time2 ==0 || ap2_data.gain2 < 0.0)
  53. return false;
  54. ap1 = new nested_allpass(ap1_data.time1,ap1_data.time2,ap1_data.time3,
  55. ap1_data.gain1,ap1_data.gain2,ap1_data.gain3,ap1_data.delay1,ap1_data.delay2);
  56. if(!ap1->create())
  57. return false;
  58. if(ap2_data.gain1 != 0.0){ //allow ap to eliminate second block
  59. ap2 = new nested_allpass(ap2_data.time1,ap2_data.time2,ap2_data.time3,
  60. ap2_data.gain1,ap2_data.gain2,ap2_data.gain3,ap2_data.delay1,ap2_data.delay2);
  61. if(!ap2->create())
  62. return false;
  63. }
  64. if(predelay_time > 0){
  65. predelay = new delay(predelay_time,1.0);
  66. if(!predelay->create())
  67. return false;
  68. }
  69. if(lpcoeff > 0.0)
  70. lp1 = new lowpass1(lpcoeff);
  71. return true;
  72. }
  73. float small_diffuser::tick(float insam)
  74. {
  75. float ip = insam;
  76. double temp;
  77. if(lp1)
  78. temp = lp1->tick((out2 + out1)*0.5f);
  79. else
  80. temp = (out2 + out1)*0.5f;
  81. ip += (float)(lpgain * temp);
  82. if(predelay)
  83. ip = predelay->tick(ip);
  84. out1 = ap1->tick(ip);
  85. if(ap2)
  86. out2 = ap2->tick(out1);
  87. return (out1 + out2) /** 0.5f*/;
  88. }