tap_deesser.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /* -*- linux-c -*-
  2. Copyright (C) 2004 Tom Szilagyi
  3. This program 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 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. $Id: tap_deesser.c,v 1.7 2004/05/01 16:15:06 tszilagyi Exp $
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <math.h>
  20. #include <ladspa.h>
  21. #include "tap_utils.h"
  22. /* The Unique ID of the plugin: */
  23. #define ID_MONO 2147
  24. /* The port numbers for the plugin: */
  25. #define THRESHOLD 0
  26. #define FREQ 1
  27. #define SIDECHAIN 2
  28. #define MONITOR 3
  29. #define ATTENUAT 4
  30. #define INPUT 5
  31. #define OUTPUT 6
  32. /* Total number of ports */
  33. #define PORTCOUNT_MONO 7
  34. /* Bandwidth of sidechain lowpass/highpass filters */
  35. #define SIDECH_BW 0.3f
  36. /* Used to hold 10 ms gain data, enough for sample rates up to 192 kHz */
  37. #define RINGBUF_SIZE 2000
  38. /* 4 digits precision from 1.000 to 9.999 */
  39. LADSPA_Data log10_table[9000];
  40. /* The structure used to hold port connection information and state */
  41. typedef struct {
  42. LADSPA_Data * threshold;
  43. LADSPA_Data * audiomode;
  44. LADSPA_Data * freq;
  45. LADSPA_Data * sidechain;
  46. LADSPA_Data * monitor;
  47. LADSPA_Data * attenuat;
  48. LADSPA_Data * input;
  49. LADSPA_Data * output;
  50. biquad sidech_lo_filter;
  51. biquad sidech_hi_filter;
  52. LADSPA_Data * ringbuffer;
  53. unsigned long buflen;
  54. unsigned long pos;
  55. LADSPA_Data sum;
  56. LADSPA_Data old_freq;
  57. unsigned long sample_rate;
  58. LADSPA_Data run_adding_gain;
  59. } DeEsser;
  60. /* fast linear to decibel conversion using log10_table[] */
  61. LADSPA_Data fast_lin2db(LADSPA_Data lin) {
  62. unsigned long k;
  63. int exp = 0;
  64. LADSPA_Data mant = ABS(lin);
  65. /* sanity checks */
  66. if (mant == 0.0f)
  67. return(-1.0f/0.0f); /* -inf */
  68. if (mant == 1.0f/0.0f) /* +inf */
  69. return(mant);
  70. while (mant < 1.0f) {
  71. mant *= 10;
  72. exp --;
  73. }
  74. while (mant >= 10.0f) {
  75. mant /= 10;
  76. exp ++;
  77. }
  78. k = (mant - 0.999999f) * 1000.0f;
  79. return 20.0f * (log10_table[k] + exp);
  80. }
  81. /* Construct a new plugin instance. */
  82. LADSPA_Handle
  83. instantiate_DeEsser(const LADSPA_Descriptor * Descriptor,
  84. unsigned long SampleRate) {
  85. LADSPA_Handle * ptr;
  86. if ((ptr = malloc(sizeof(DeEsser))) != NULL) {
  87. ((DeEsser *)ptr)->sample_rate = SampleRate;
  88. ((DeEsser *)ptr)->run_adding_gain = 1.0f;
  89. /* init filters */
  90. biquad_init(&((DeEsser *)ptr)->sidech_lo_filter);
  91. biquad_init(&((DeEsser *)ptr)->sidech_hi_filter);
  92. /* alloc mem for ringbuffer */
  93. if ((((DeEsser *)ptr)->ringbuffer =
  94. calloc(RINGBUF_SIZE, sizeof(LADSPA_Data))) == NULL)
  95. return NULL;
  96. /* 10 ms attenuation data is stored */
  97. ((DeEsser *)ptr)->buflen = ((DeEsser *)ptr)->sample_rate / 100;
  98. ((DeEsser *)ptr)->pos = 0;
  99. ((DeEsser *)ptr)->sum = 0.0f;
  100. ((DeEsser *)ptr)->old_freq = 0;
  101. return ptr;
  102. }
  103. return NULL;
  104. }
  105. void
  106. activate_DeEsser(LADSPA_Handle Instance) {
  107. DeEsser * ptr = (DeEsser *)Instance;
  108. unsigned long i;
  109. for (i = 0; i < RINGBUF_SIZE; i++)
  110. ptr->ringbuffer[i] = 0.0f;
  111. }
  112. /* Connect a port to a data location. */
  113. void
  114. connect_port_DeEsser(LADSPA_Handle Instance,
  115. unsigned long Port,
  116. LADSPA_Data * DataLocation) {
  117. DeEsser * ptr;
  118. ptr = (DeEsser *)Instance;
  119. switch (Port) {
  120. case THRESHOLD:
  121. ptr->threshold = DataLocation;
  122. break;
  123. case FREQ:
  124. ptr->freq = DataLocation;
  125. break;
  126. case SIDECHAIN:
  127. ptr->sidechain = DataLocation;
  128. break;
  129. case MONITOR:
  130. ptr->monitor = DataLocation;
  131. break;
  132. case ATTENUAT:
  133. ptr->attenuat = DataLocation;
  134. *(ptr->attenuat) = 0.0f;
  135. break;
  136. case INPUT:
  137. ptr->input = DataLocation;
  138. break;
  139. case OUTPUT:
  140. ptr->output = DataLocation;
  141. break;
  142. }
  143. }
  144. void
  145. run_DeEsser(LADSPA_Handle Instance,
  146. unsigned long SampleCount) {
  147. DeEsser * ptr = (DeEsser *)Instance;
  148. LADSPA_Data * input = ptr->input;
  149. LADSPA_Data * output = ptr->output;
  150. LADSPA_Data threshold = LIMIT(*(ptr->threshold),-50.0f,10.0f);
  151. LADSPA_Data freq = LIMIT(*(ptr->freq),2000.0f,16000.0f);
  152. LADSPA_Data sidechain = LIMIT(*(ptr->sidechain),0.0f,1.0f);
  153. LADSPA_Data monitor = LIMIT(*(ptr->monitor),0.0f,1.0f);
  154. unsigned long sample_index;
  155. LADSPA_Data in = 0;
  156. LADSPA_Data out = 0;
  157. LADSPA_Data sidech = 0;
  158. LADSPA_Data ampl_db = 0.0f;
  159. LADSPA_Data attn = 0.0f;
  160. LADSPA_Data max_attn = 0.0f;
  161. if (ptr->old_freq != freq) {
  162. lp_set_params(&ptr->sidech_lo_filter, freq, SIDECH_BW, ptr->sample_rate);
  163. hp_set_params(&ptr->sidech_hi_filter, freq, SIDECH_BW, ptr->sample_rate);
  164. ptr->old_freq = freq;
  165. }
  166. for (sample_index = 0; sample_index < SampleCount; sample_index++) {
  167. in = *(input++);
  168. /* process sidechain filters */
  169. sidech = biquad_run(&ptr->sidech_hi_filter, in);
  170. if (sidechain > 0.1f)
  171. sidech = biquad_run(&ptr->sidech_lo_filter, sidech);
  172. ampl_db = fast_lin2db(sidech);
  173. if (ampl_db <= threshold)
  174. attn = 0.0f;
  175. else
  176. attn = -0.5f * (ampl_db - threshold);
  177. ptr->sum += attn;
  178. ptr->sum -= push_buffer(attn, ptr->ringbuffer, ptr->buflen, &ptr->pos);
  179. if (-1.0f * ptr->sum > max_attn)
  180. max_attn = -0.01f * ptr->sum;
  181. in *= db2lin(ptr->sum / 100.0f);
  182. /* output selector */
  183. if (monitor > 0.1f)
  184. out = sidech;
  185. else
  186. out = in;
  187. *(output++) = out;
  188. *(ptr->attenuat) = LIMIT(max_attn,0,10);
  189. }
  190. }
  191. void
  192. set_run_adding_gain_DeEsser(LADSPA_Handle Instance, LADSPA_Data gain) {
  193. DeEsser * ptr = (DeEsser *)Instance;
  194. ptr->run_adding_gain = gain;
  195. }
  196. void
  197. run_adding_DeEsser(LADSPA_Handle Instance,
  198. unsigned long SampleCount) {
  199. DeEsser * ptr = (DeEsser *)Instance;
  200. LADSPA_Data * input = ptr->input;
  201. LADSPA_Data * output = ptr->output;
  202. LADSPA_Data threshold = LIMIT(*(ptr->threshold),-50.0f,10.0f);
  203. LADSPA_Data freq = LIMIT(*(ptr->freq),2000.0f,16000.0f);
  204. LADSPA_Data sidechain = LIMIT(*(ptr->sidechain),0.0f,1.0f);
  205. LADSPA_Data monitor = LIMIT(*(ptr->monitor),0.0f,1.0f);
  206. unsigned long sample_index;
  207. LADSPA_Data in = 0;
  208. LADSPA_Data out = 0;
  209. LADSPA_Data sidech = 0;
  210. LADSPA_Data ampl_db = 0.0f;
  211. LADSPA_Data attn = 0.0f;
  212. LADSPA_Data max_attn = 0.0f;
  213. if (ptr->old_freq != freq) {
  214. lp_set_params(&ptr->sidech_lo_filter, freq, SIDECH_BW, ptr->sample_rate);
  215. hp_set_params(&ptr->sidech_hi_filter, freq, SIDECH_BW, ptr->sample_rate);
  216. ptr->old_freq = freq;
  217. }
  218. for (sample_index = 0; sample_index < SampleCount; sample_index++) {
  219. in = *(input++);
  220. /* process sidechain filters */
  221. sidech = biquad_run(&ptr->sidech_hi_filter, in);
  222. if (sidechain > 0.1f)
  223. sidech = biquad_run(&ptr->sidech_lo_filter, sidech);
  224. ampl_db = 20.0f * log10f(sidech);
  225. if (ampl_db <= threshold)
  226. attn = 0.0f;
  227. else
  228. attn = -0.5f * (ampl_db - threshold);
  229. ptr->sum += attn;
  230. ptr->sum -= push_buffer(attn, ptr->ringbuffer, ptr->buflen, &ptr->pos);
  231. if (-1.0f * ptr->sum > max_attn)
  232. max_attn = -0.01f * ptr->sum;
  233. in *= db2lin(ptr->sum / 100.0f);
  234. /* output selector */
  235. if (monitor > 0.1f)
  236. out = sidech;
  237. else
  238. out = in;
  239. *(output++) += ptr->run_adding_gain * out;
  240. *(ptr->attenuat) = LIMIT(max_attn,0,10);
  241. }
  242. }
  243. /* Throw away a DeEsser effect instance. */
  244. void
  245. cleanup_DeEsser(LADSPA_Handle Instance) {
  246. DeEsser * ptr = (DeEsser *)Instance;
  247. free(ptr->ringbuffer);
  248. free(Instance);
  249. }
  250. LADSPA_Descriptor * mono_descriptor = NULL;
  251. /* __attribute__((constructor)) tap_init() is called automatically when the plugin library is first
  252. loaded. */
  253. void
  254. __attribute__((constructor)) tap_init() {
  255. int i;
  256. char ** port_names;
  257. LADSPA_PortDescriptor * port_descriptors;
  258. LADSPA_PortRangeHint * port_range_hints;
  259. if ((mono_descriptor =
  260. (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
  261. exit(1);
  262. /* compute the log10 table */
  263. for (i = 0; i < 9000; i++)
  264. log10_table[i] = log10f(1.0f + i / 1000.0f);
  265. mono_descriptor->UniqueID = ID_MONO;
  266. mono_descriptor->Label = strdup("tap_deesser");
  267. mono_descriptor->Properties = 0;
  268. mono_descriptor->Name = strdup("TAP DeEsser");
  269. mono_descriptor->Maker = strdup("Tom Szilagyi");
  270. mono_descriptor->Copyright = strdup("GPL");
  271. mono_descriptor->PortCount = PORTCOUNT_MONO;
  272. if ((port_descriptors =
  273. (LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
  274. exit(1);
  275. mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
  276. port_descriptors[THRESHOLD] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  277. port_descriptors[FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  278. port_descriptors[SIDECHAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  279. port_descriptors[MONITOR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
  280. port_descriptors[ATTENUAT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
  281. port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
  282. port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
  283. if ((port_names =
  284. (char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
  285. exit(1);
  286. mono_descriptor->PortNames = (const char **)port_names;
  287. port_names[THRESHOLD] = strdup("Threshold Level [dB]");
  288. port_names[FREQ] = strdup("Frequency [Hz]");
  289. port_names[SIDECHAIN] = strdup("Sidechain Filter");
  290. port_names[MONITOR] = strdup("Monitor");
  291. port_names[ATTENUAT] = strdup("Attenuation [dB]");
  292. port_names[INPUT] = strdup("Input");
  293. port_names[OUTPUT] = strdup("Output");
  294. if ((port_range_hints =
  295. ((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
  296. exit(1);
  297. mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
  298. port_range_hints[THRESHOLD].HintDescriptor =
  299. (LADSPA_HINT_BOUNDED_BELOW |
  300. LADSPA_HINT_BOUNDED_ABOVE |
  301. LADSPA_HINT_DEFAULT_0);
  302. port_range_hints[FREQ].HintDescriptor =
  303. (LADSPA_HINT_BOUNDED_BELOW |
  304. LADSPA_HINT_BOUNDED_ABOVE |
  305. LADSPA_HINT_DEFAULT_LOW);
  306. port_range_hints[SIDECHAIN].HintDescriptor =
  307. (LADSPA_HINT_BOUNDED_BELOW |
  308. LADSPA_HINT_BOUNDED_ABOVE |
  309. LADSPA_HINT_INTEGER |
  310. LADSPA_HINT_DEFAULT_0);
  311. port_range_hints[MONITOR].HintDescriptor =
  312. (LADSPA_HINT_BOUNDED_BELOW |
  313. LADSPA_HINT_BOUNDED_ABOVE |
  314. LADSPA_HINT_INTEGER |
  315. LADSPA_HINT_DEFAULT_0);
  316. port_range_hints[ATTENUAT].HintDescriptor =
  317. (LADSPA_HINT_BOUNDED_BELOW |
  318. LADSPA_HINT_BOUNDED_ABOVE |
  319. LADSPA_HINT_DEFAULT_0);
  320. port_range_hints[THRESHOLD].LowerBound = -50;
  321. port_range_hints[THRESHOLD].UpperBound = 10;
  322. port_range_hints[FREQ].LowerBound = 2000;
  323. port_range_hints[FREQ].UpperBound = 16000;
  324. port_range_hints[SIDECHAIN].LowerBound = 0.0f;
  325. port_range_hints[SIDECHAIN].UpperBound = 1.01f;
  326. port_range_hints[MONITOR].LowerBound = 0.0f;
  327. port_range_hints[MONITOR].UpperBound = 1.01f;
  328. port_range_hints[ATTENUAT].LowerBound = 0.0f;
  329. port_range_hints[ATTENUAT].UpperBound = 10.0f;
  330. port_range_hints[INPUT].HintDescriptor = 0;
  331. port_range_hints[OUTPUT].HintDescriptor = 0;
  332. mono_descriptor->instantiate = instantiate_DeEsser;
  333. mono_descriptor->connect_port = connect_port_DeEsser;
  334. mono_descriptor->activate = activate_DeEsser;
  335. mono_descriptor->run = run_DeEsser;
  336. mono_descriptor->run_adding = run_adding_DeEsser;
  337. mono_descriptor->set_run_adding_gain = set_run_adding_gain_DeEsser;
  338. mono_descriptor->deactivate = NULL;
  339. mono_descriptor->cleanup = cleanup_DeEsser;
  340. }
  341. void
  342. delete_descriptor(LADSPA_Descriptor * descriptor) {
  343. unsigned long index;
  344. if (descriptor) {
  345. free((char *)descriptor->Label);
  346. free((char *)descriptor->Name);
  347. free((char *)descriptor->Maker);
  348. free((char *)descriptor->Copyright);
  349. free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
  350. for (index = 0; index < descriptor->PortCount; index++)
  351. free((char *)(descriptor->PortNames[index]));
  352. free((char **)descriptor->PortNames);
  353. free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
  354. free(descriptor);
  355. }
  356. }
  357. /* __attribute__((destructor)) tap_fini() is called automatically when the library is unloaded. */
  358. void
  359. __attribute__((destructor)) tap_fini() {
  360. delete_descriptor(mono_descriptor);
  361. }
  362. /* Return a descriptor of the requested plugin type. */
  363. const LADSPA_Descriptor *
  364. ladspa_descriptor(unsigned long Index) {
  365. switch (Index) {
  366. case 0:
  367. return mono_descriptor;
  368. default:
  369. return NULL;
  370. }
  371. }