External plugins for 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.

236 lines
5.4KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. SVFilter.cpp - Several state-variable filters
  4. Copyright (C) 2002-2005 Nasca Octavian Paul
  5. Author: Nasca Octavian Paul
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. */
  11. #include <cmath>
  12. #include <cstdio>
  13. #include <cstring>
  14. #include <cassert>
  15. #include "../Misc/Util.h"
  16. #include "SVFilter.h"
  17. #define errx(...) {}
  18. #define warnx(...) {}
  19. #ifndef errx
  20. #include <err.h>
  21. #endif
  22. namespace zyncarla {
  23. SVFilter::SVFilter(unsigned char Ftype, float Ffreq, float Fq,
  24. unsigned char Fstages, unsigned int srate, int bufsize)
  25. :Filter(srate, bufsize),
  26. type(Ftype),
  27. stages(Fstages),
  28. freq(Ffreq),
  29. q(Fq),
  30. gain(1.0f),
  31. needsinterpolation(false),
  32. firsttime(true)
  33. {
  34. if(stages >= MAX_FILTER_STAGES)
  35. stages = MAX_FILTER_STAGES;
  36. outgain = 1.0f;
  37. cleanup();
  38. setfreq_and_q(Ffreq, Fq);
  39. }
  40. SVFilter::~SVFilter()
  41. {}
  42. void SVFilter::cleanup()
  43. {
  44. for(int i = 0; i < MAX_FILTER_STAGES + 1; ++i)
  45. st[i].low = st[i].high = st[i].band = st[i].notch = 0.0f;
  46. oldabovenq = false;
  47. abovenq = false;
  48. }
  49. SVFilter::response::response(float b0, float b1, float b2,
  50. float a0, float a1 ,float a2)
  51. {
  52. a[0] = a0;
  53. a[1] = a1;
  54. a[2] = a2;
  55. b[0] = b0;
  56. b[1] = b1;
  57. b[2] = b2;
  58. }
  59. SVFilter::response SVFilter::computeResponse(int type,
  60. float freq, float pq, int stages, float gain, float fs)
  61. {
  62. typedef SVFilter::response res;
  63. float f = freq / fs * 4.0;
  64. if(f > 0.99999f)
  65. f = 0.99999f;
  66. float q = 1.0f - atanf(sqrtf(pq)) * 2.0f / PI;
  67. q = powf(q, 1.0f / (stages + 1));
  68. float qrt = sqrtf(q);
  69. float g = powf(gain, 1.0 / (stages + 1));
  70. if(type == 0) { //Low
  71. return res{0, g*f*f*qrt, 0,
  72. 1, (q*f+f*f-2), (1-q*f)};
  73. }
  74. if(type == 1) {//High
  75. //g *= qrt/(1+f*q);
  76. g *= qrt;
  77. return res{g, -2*g, g,
  78. //1, (f*f-2*f*q-2)/(1+f*q), 1};
  79. 1, (q*f+f*f-2), (1-q*f)};
  80. }
  81. if(type == 2) {//Band
  82. g *= f*qrt;
  83. return res{g, -g, 0,
  84. 1, (q*f+f*f-2), (1-q*f)};
  85. }
  86. if(type == 3 || true) {//Notch
  87. g *= qrt;
  88. return res{g, -2*g+g*f*f, g,
  89. 1, (q*f+f*f-2), (1-q*f)};
  90. }
  91. }
  92. void SVFilter::computefiltercoefs(void)
  93. {
  94. par.f = freq / samplerate_f * 4.0f;
  95. if(par.f > 0.99999f)
  96. par.f = 0.99999f;
  97. par.q = 1.0f - atanf(sqrtf(q)) * 2.0f / PI;
  98. par.q = powf(par.q, 1.0f / (stages + 1));
  99. par.q_sqrt = sqrtf(par.q);
  100. }
  101. void SVFilter::setfreq(float frequency)
  102. {
  103. if(frequency < 0.1f)
  104. frequency = 0.1f;
  105. float rap = freq / frequency;
  106. if(rap < 1.0f)
  107. rap = 1.0f / rap;
  108. oldabovenq = abovenq;
  109. abovenq = frequency > (samplerate_f / 2 - 500.0f);
  110. bool nyquistthresh = (abovenq ^ oldabovenq);
  111. //if the frequency is changed fast, it needs interpolation
  112. if((rap > 3.0f) || nyquistthresh) { //(now, filter and coefficients backup)
  113. if(!firsttime)
  114. needsinterpolation = true;
  115. ipar = par;
  116. }
  117. freq = frequency;
  118. computefiltercoefs();
  119. firsttime = false;
  120. }
  121. void SVFilter::setfreq_and_q(float frequency, float q_)
  122. {
  123. q = q_;
  124. setfreq(frequency);
  125. }
  126. void SVFilter::setq(float q_)
  127. {
  128. q = q_;
  129. computefiltercoefs();
  130. }
  131. void SVFilter::settype(int type_)
  132. {
  133. type = type_;
  134. computefiltercoefs();
  135. }
  136. void SVFilter::setgain(float dBgain)
  137. {
  138. gain = dB2rap(dBgain);
  139. computefiltercoefs();
  140. }
  141. void SVFilter::setstages(int stages_)
  142. {
  143. if(stages_ >= MAX_FILTER_STAGES)
  144. stages_ = MAX_FILTER_STAGES - 1;
  145. stages = stages_;
  146. cleanup();
  147. computefiltercoefs();
  148. }
  149. void SVFilter::singlefilterout(float *smp, fstage &x, parameters &par)
  150. {
  151. float *out = NULL;
  152. switch(type) {
  153. case 0:
  154. out = &x.low;
  155. break;
  156. case 1:
  157. out = &x.high;
  158. break;
  159. case 2:
  160. out = &x.band;
  161. break;
  162. case 3:
  163. out = &x.notch;
  164. break;
  165. default:
  166. out = &x.low;
  167. warnx("Impossible SVFilter type encountered [%d]", type);
  168. }
  169. for(int i = 0; i < buffersize; ++i) {
  170. x.low = x.low + par.f * x.band;
  171. x.high = par.q_sqrt * smp[i] - x.low - par.q * x.band;
  172. x.band = par.f * x.high + x.band;
  173. x.notch = x.high + x.low;
  174. smp[i] = *out;
  175. }
  176. }
  177. // simplifying the responses
  178. // xl = xl*z(-1) + pf*xb*z(-1)
  179. // xh = pq1*x - xl - pq*xb*z(-1)
  180. // xb = pf*xh + xb*z(-1)
  181. // xn = xh + xl
  182. //
  183. // xl = pf*xb*z(-1)/(1-z(-1))
  184. // xb = pf*xh/(1-z(-1))
  185. // xl = pf*pfxh*z(-1)/(1-z(-1))^2
  186. void SVFilter::filterout(float *smp)
  187. {
  188. for(int i = 0; i < stages + 1; ++i)
  189. singlefilterout(smp, st[i], par);
  190. if(needsinterpolation) {
  191. float ismp[buffersize];
  192. memcpy(ismp, smp, bufferbytes);
  193. for(int i = 0; i < stages + 1; ++i)
  194. singlefilterout(ismp, st[i], ipar);
  195. for(int i = 0; i < buffersize; ++i) {
  196. float x = i / buffersize_f;
  197. smp[i] = ismp[i] * (1.0f - x) + smp[i] * x;
  198. }
  199. needsinterpolation = false;
  200. }
  201. for(int i = 0; i < buffersize; ++i)
  202. smp[i] *= outgain;
  203. }
  204. }