freeverb.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "freeverb.h"
  2. const float muted = 0;
  3. const float fixedgain = 0.015f;
  4. const float scalewet = 3;
  5. const float scaledry = 2;
  6. const float scaledamp = 0.4f;
  7. const float scaleroom = 0.28f;
  8. const float offsetroom = 0.7f;
  9. const float initialroom = 0.5f;
  10. const float initialdamp = 0.5f;
  11. const float initialwet = 1 / 3;//(scalewet);
  12. const float initialdry = 0;
  13. const float initialwidth = 1;
  14. const float initialmode = 0;
  15. const float freezemode = 0.5f;
  16. float undenormalise(void *sample)
  17. {
  18. if (((*(unsigned int*)sample) & 0x7f800000) == 0)
  19. return 0.0f;
  20. return *(float*)sample;
  21. }
  22. void comb_init(comb* pcombobj)
  23. {
  24. pcombobj->filterstore = 0;
  25. pcombobj->bufidx = 0;
  26. }
  27. void comb_setbuffer(comb* pcombobj,float *buf, int size)
  28. {
  29. pcombobj->buffer = buf;
  30. pcombobj->bufsize = size;
  31. }
  32. float comb_process(comb* pcombobj,float input)
  33. {
  34. float output;
  35. output = pcombobj->buffer[pcombobj->bufidx];
  36. undenormalise(&output);
  37. pcombobj->filterstore = (output * pcombobj->damp2) + (pcombobj->filterstore * pcombobj->damp1);
  38. undenormalise(&pcombobj->filterstore);
  39. pcombobj->buffer[pcombobj->bufidx] = input + (pcombobj->filterstore * pcombobj->feedback);
  40. if (++pcombobj->bufidx >= pcombobj->bufsize)
  41. pcombobj->bufidx = 0;
  42. return output;
  43. }
  44. void comb_mute(comb* pcombobj)
  45. {
  46. int i = 0;
  47. for (i = 0; i < pcombobj->bufsize; i++)
  48. pcombobj->buffer[i] = 0;
  49. }
  50. void comb_setdamp(comb* pcombobj,float val)
  51. {
  52. pcombobj->damp1 = val;
  53. pcombobj->damp2 = 1 - val;
  54. }
  55. float comb_getdamp(comb* pcombobj)
  56. {
  57. return pcombobj->damp1;
  58. }
  59. void comb_setfeedback(comb* pcombobj,float val)
  60. {
  61. pcombobj->feedback = val;
  62. }
  63. float comb_getfeedback(comb* pcombobj)
  64. {
  65. return pcombobj->feedback;
  66. }
  67. void allpass_init(allpass* pallpassobj)
  68. {
  69. pallpassobj->bufidx = 0;
  70. }
  71. void allpass_setbuffer(allpass* pallpassobj,float *buf, int size)
  72. {
  73. pallpassobj->buffer = buf;
  74. pallpassobj->bufsize = size;
  75. }
  76. float allpass_process(allpass* pallpassobj,float input)
  77. {
  78. float output;
  79. float bufout;
  80. bufout = pallpassobj->buffer[pallpassobj->bufidx];
  81. undenormalise(&bufout);
  82. output = -input + bufout;
  83. pallpassobj->buffer[pallpassobj->bufidx] = input + (bufout * pallpassobj->feedback);
  84. if (++pallpassobj->bufidx >= pallpassobj->bufsize)
  85. pallpassobj->bufidx = 0;
  86. return output;
  87. }
  88. void allpass_mute(allpass* pallpassobj)
  89. {
  90. int i = 0;
  91. for (i = 0; i < pallpassobj->bufsize; i++)
  92. pallpassobj->buffer[i] = 0;
  93. }
  94. void allpass_setfeedback(allpass* pallpassobj,float val)
  95. {
  96. pallpassobj->feedback = val;
  97. }
  98. float allpass_getfeedback(allpass* pallpassobj)
  99. {
  100. return pallpassobj->feedback;
  101. }
  102. void revmodel_init(revmodel* pmodelobj)
  103. {
  104. comb_init(pmodelobj->combL+0);
  105. comb_init(pmodelobj->combL+1);
  106. comb_init(pmodelobj->combL+2);
  107. comb_init(pmodelobj->combL+3);
  108. comb_init(pmodelobj->combL+4);
  109. comb_init(pmodelobj->combL+5);
  110. comb_init(pmodelobj->combL+6);
  111. comb_init(pmodelobj->combL+7);
  112. comb_setbuffer(pmodelobj->combL+0,pmodelobj->bufcombL1,combtuningL1);
  113. comb_setbuffer(pmodelobj->combL+1,pmodelobj->bufcombL2,combtuningL2);
  114. comb_setbuffer(pmodelobj->combL+2,pmodelobj->bufcombL3,combtuningL3);
  115. comb_setbuffer(pmodelobj->combL+3,pmodelobj->bufcombL4,combtuningL4);
  116. comb_setbuffer(pmodelobj->combL+4,pmodelobj->bufcombL5,combtuningL5);
  117. comb_setbuffer(pmodelobj->combL+5,pmodelobj->bufcombL6,combtuningL6);
  118. comb_setbuffer(pmodelobj->combL+6,pmodelobj->bufcombL7,combtuningL7);
  119. comb_setbuffer(pmodelobj->combL+7,pmodelobj->bufcombL8,combtuningL8);
  120. allpass_init(pmodelobj->allpassL+0);
  121. allpass_init(pmodelobj->allpassL+1);
  122. allpass_init(pmodelobj->allpassL+2);
  123. allpass_init(pmodelobj->allpassL+3);
  124. allpass_setbuffer(pmodelobj->allpassL+0,pmodelobj->bufallpassL1,allpasstuningL1);
  125. allpass_setbuffer(pmodelobj->allpassL+1,pmodelobj->bufallpassL2,allpasstuningL2);
  126. allpass_setbuffer(pmodelobj->allpassL+2,pmodelobj->bufallpassL3,allpasstuningL3);
  127. allpass_setbuffer(pmodelobj->allpassL+3,pmodelobj->bufallpassL4,allpasstuningL4);
  128. allpass_setfeedback(pmodelobj->allpassL+0,0.5f);
  129. allpass_setfeedback(pmodelobj->allpassL+1,0.5f);
  130. allpass_setfeedback(pmodelobj->allpassL+2,0.5f);
  131. allpass_setfeedback(pmodelobj->allpassL+3,0.5f);
  132. revmodel_setwet(pmodelobj,initialwet);
  133. revmodel_setroomsize(pmodelobj,initialroom);
  134. revmodel_setdry(pmodelobj,initialdry);
  135. revmodel_setdamp(pmodelobj,initialdamp);
  136. revmodel_setwidth(pmodelobj,initialwidth);
  137. revmodel_setmode(pmodelobj,initialmode);
  138. revmodel_mute(pmodelobj);
  139. }
  140. void revmodel_mute(revmodel* pmodelobj)
  141. {
  142. int i=0;
  143. if (revmodel_getmode(pmodelobj) >= freezemode)
  144. return;
  145. for (i = 0; i < numcombs; i++) {
  146. comb_mute(pmodelobj->combL+i);
  147. }
  148. for (i = 0; i < numallpasses; i++) {
  149. allpass_mute(pmodelobj->allpassL+i);
  150. }
  151. }
  152. float revmodel_processsample(revmodel* pmodelobj,float in)
  153. {
  154. float samp = in;
  155. float mono_out = 0.0f;
  156. float mono_in = samp;
  157. float input = (mono_in) * pmodelobj->gain;
  158. int i = 0;
  159. for(i=0; i<numcombs; i++)
  160. {
  161. mono_out += comb_process(pmodelobj->combL+i,input);
  162. }
  163. for(i=0; i<numallpasses; i++)
  164. {
  165. mono_out = allpass_process(pmodelobj->allpassL+i,mono_out);
  166. }
  167. samp = mono_in * pmodelobj->dry + mono_out * pmodelobj->wet1;
  168. if (samp>32767)
  169. samp=32767;
  170. if (samp<-32768)
  171. samp=-32768;
  172. return samp;
  173. }
  174. void revmodel_update(revmodel* pmodelobj)
  175. {
  176. int i;
  177. pmodelobj->wet1 = pmodelobj->wet * (pmodelobj->width / 2 + 0.5f);
  178. if (pmodelobj->mode >= freezemode)
  179. {
  180. pmodelobj->roomsize1 = 1;
  181. pmodelobj->damp1 = 0;
  182. pmodelobj->gain = muted;
  183. }
  184. else
  185. {
  186. pmodelobj->roomsize1 = pmodelobj->roomsize;
  187. pmodelobj->damp1 = pmodelobj->damp;
  188. pmodelobj->gain = fixedgain;
  189. }
  190. for (i = 0; i < numcombs; i++)
  191. {
  192. comb_setfeedback(pmodelobj->combL+i,pmodelobj->roomsize1);
  193. }
  194. for (i = 0; i < numcombs; i++) {
  195. comb_setdamp(pmodelobj->combL+i,pmodelobj->damp1);
  196. }
  197. }
  198. void revmodel_setroomsize(revmodel* pmodelobj,float value)
  199. {
  200. pmodelobj->roomsize = (value * scaleroom) + offsetroom;
  201. revmodel_update(pmodelobj);
  202. }
  203. float revmodel_getroomsize(revmodel* pmodelobj)
  204. {
  205. return (pmodelobj->roomsize - offsetroom) / scaleroom;
  206. }
  207. void revmodel_setdamp(revmodel* pmodelobj,float value)
  208. {
  209. pmodelobj->damp = value * scaledamp;
  210. revmodel_update(pmodelobj);
  211. }
  212. float revmodel_getdamp(revmodel* pmodelobj)
  213. {
  214. return pmodelobj->damp / scaledamp;
  215. }
  216. void revmodel_setwet(revmodel* pmodelobj,float value)
  217. {
  218. pmodelobj->wet = value * scalewet;
  219. revmodel_update(pmodelobj);
  220. }
  221. float revmodel_getwet(revmodel* pmodelobj)
  222. {
  223. return pmodelobj->wet / scalewet;
  224. }
  225. void revmodel_setdry(revmodel* pmodelobj,float value)
  226. {
  227. pmodelobj->dry = value * scaledry;
  228. }
  229. float revmodel_getdry(revmodel* pmodelobj)
  230. {
  231. return pmodelobj->dry / scaledry;
  232. }
  233. void revmodel_setwidth(revmodel* pmodelobj,float value)
  234. {
  235. pmodelobj->width = value;
  236. revmodel_update(pmodelobj);
  237. }
  238. float revmodel_getwidth(revmodel* pmodelobj)
  239. {
  240. return pmodelobj->width;
  241. }
  242. void revmodel_setmode(revmodel* pmodelobj,float value)
  243. {
  244. pmodelobj->mode = value;
  245. revmodel_update(pmodelobj);
  246. }
  247. float revmodel_getmode(revmodel* pmodelobj)
  248. {
  249. if (pmodelobj->mode >= freezemode)
  250. return 1;
  251. else
  252. return 0;
  253. }