~ubuntu-branches/ubuntu/raring/lmms/raring-proposed

« back to all changes in this revision

Viewing changes to plugins/ladspa_effect/swh/dyson_compress_1403.c

  • Committer: Charlie Smotherman
  • Date: 2012-12-05 22:08:38 UTC
  • mfrom: (33.1.7 lmms_0.4.13)
  • Revision ID: cjsmo@cableone.net-20121205220838-09pjfzew9m5023hr
* New  Upstream release.
  - Minor tweaking to ZynAddSubFX, CALF, SWH plugins  and Stefan Fendt's RC
    filters.
  - Added UI fixes: Magnentic effect of knobs and Piano-roll fixes
  - Updated German localization and copyright year
* debian/lmms-common.install:
  - added /usr/share/applications so the lmms.desktop file will correctly
    install (LP: #863366)
  - This should also fix the Software Center not displaying lmms in sound
    and video (LP: #824231)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
#include <string.h>
 
3
#ifndef WIN32
 
4
#include "config.h"
 
5
#endif
 
6
 
 
7
#ifdef ENABLE_NLS
 
8
#include <libintl.h>
 
9
#endif
 
10
 
 
11
#define         _ISOC9X_SOURCE  1
 
12
#define         _ISOC99_SOURCE  1
 
13
#define         __USE_ISOC99    1
 
14
#define         __USE_ISOC9X    1
 
15
 
 
16
#include <math.h>
 
17
 
 
18
#include "ladspa.h"
 
19
 
 
20
#ifdef WIN32
 
21
#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport)
 
22
int bIsFirstTime = 1; 
 
23
void _init(); // forward declaration
 
24
#else
 
25
#define _WINDOWS_DLL_EXPORT_ 
 
26
#endif
 
27
 
 
28
#line 10 "dyson_compress_1403.xml"
 
29
 
 
30
/*
 
31
 * Copyright (c) 1996, John S. Dyson
 
32
 * All rights reserved.
 
33
 *
 
34
 * Redistribution and use in source and binary forms, with or without
 
35
 * modification, are permitted provided that the following conditions
 
36
 * are met:
 
37
 * 1. Redistributions of source code must retain the above copyright
 
38
 *    notice, this list of conditions and the following disclaimer.
 
39
 * 2. Redistributions in binary form must reproduce the above copyright
 
40
 *    notice, this list of conditions and the following disclaimer in the
 
41
 *    documentation and/or other materials provided with the distribution.
 
42
 *
 
43
 * This code (easily) runs realtime on a P5-166 w/EDO, Triton-II on FreeBSD.
 
44
 *
 
45
 * More info/comments: dyson@freebsd.org
 
46
 *
 
47
 * This program provides compression of a stereo 16bit audio stream,
 
48
 * such as that contained by a 16Bit wav file.  Extreme measures have
 
49
 * been taken to make the compression as subtile as possible.  One
 
50
 * possible purpose for this code would be to master cassette tapes from
 
51
 * CD's for playback in automobiles where dynamic range needs to be
 
52
 * restricted.
 
53
 *
 
54
 * Suitably recoded for an embedded DSP, this would make a killer audio
 
55
 * compressor for broadcast or recording.  When writing this code, I
 
56
 * ignored the issues of roundoff error or trucation -- Pentiums have
 
57
 * really nice FP processors :-).
 
58
 */
 
59
 
 
60
      #include <ladspa-util.h>
 
61
 
 
62
      #define MAXLEVEL 0.9f
 
63
      #define NFILT 12
 
64
      #define NEFILT 17
 
65
 
 
66
      /* These filters should filter at least the lowest audio freq */
 
67
      #define RLEVELSQ0FILTER .001
 
68
      #define RLEVELSQ1FILTER .010
 
69
      /* These are the attack time for the rms measurement */
 
70
      #define RLEVELSQ0FFILTER .001
 
71
      #define RLEVELSQEFILTER .001
 
72
    
 
73
      #define RMASTERGAIN0FILTER .000003
 
74
    
 
75
      #define RPEAKGAINFILTER .001
 
76
 
 
77
      #define MAXFASTGAIN 3
 
78
      #define MAXSLOWGAIN 9
 
79
 
 
80
      #define FLOORLEVEL 0.06
 
81
 
 
82
      float hardlimit(float value, float knee, float limit) {
 
83
        float ab = fabs(value);
 
84
        if (ab >= limit) {
 
85
          value = value > 0 ? limit : -limit;
 
86
        }
 
87
 
 
88
        return value;
 
89
      }
 
90
 
 
91
#define DYSONCOMPRESS_PEAK_LIMIT       0
 
92
#define DYSONCOMPRESS_RELEASE_TIME     1
 
93
#define DYSONCOMPRESS_CFRATE           2
 
94
#define DYSONCOMPRESS_CRATE            3
 
95
#define DYSONCOMPRESS_INPUT            4
 
96
#define DYSONCOMPRESS_OUTPUT           5
 
97
 
 
98
static LADSPA_Descriptor *dysonCompressDescriptor = NULL;
 
99
 
 
100
typedef struct {
 
101
        LADSPA_Data *peak_limit;
 
102
        LADSPA_Data *release_time;
 
103
        LADSPA_Data *cfrate;
 
104
        LADSPA_Data *crate;
 
105
        LADSPA_Data *input;
 
106
        LADSPA_Data *output;
 
107
        LADSPA_Data *delay;
 
108
        float        extra_maxlevel;
 
109
        float        lastrgain;
 
110
        float        maxgain;
 
111
        float        mingain;
 
112
        float        ndelay;
 
113
        unsigned int ndelayptr;
 
114
        int          peaklimitdelay;
 
115
        float        rgain;
 
116
        float        rlevelsq0;
 
117
        float        rlevelsq1;
 
118
        LADSPA_Data *rlevelsqe;
 
119
        LADSPA_Data *rlevelsqn;
 
120
        float        rmastergain0;
 
121
        float        rpeakgain0;
 
122
        float        rpeakgain1;
 
123
        float        rpeaklimitdelay;
 
124
        float        sample_rate;
 
125
        LADSPA_Data run_adding_gain;
 
126
} DysonCompress;
 
127
 
 
128
_WINDOWS_DLL_EXPORT_
 
129
const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
 
130
 
 
131
#ifdef WIN32
 
132
        if (bIsFirstTime) {
 
133
                _init();
 
134
                bIsFirstTime = 0;
 
135
        }
 
136
#endif
 
137
        switch (index) {
 
138
        case 0:
 
139
                return dysonCompressDescriptor;
 
140
        default:
 
141
                return NULL;
 
142
        }
 
143
}
 
144
 
 
145
static void activateDysonCompress(LADSPA_Handle instance) {
 
146
        DysonCompress *plugin_data = (DysonCompress *)instance;
 
147
        LADSPA_Data *delay = plugin_data->delay;
 
148
        float extra_maxlevel = plugin_data->extra_maxlevel;
 
149
        float lastrgain = plugin_data->lastrgain;
 
150
        float maxgain = plugin_data->maxgain;
 
151
        float mingain = plugin_data->mingain;
 
152
        float ndelay = plugin_data->ndelay;
 
153
        unsigned int ndelayptr = plugin_data->ndelayptr;
 
154
        int peaklimitdelay = plugin_data->peaklimitdelay;
 
155
        float rgain = plugin_data->rgain;
 
156
        float rlevelsq0 = plugin_data->rlevelsq0;
 
157
        float rlevelsq1 = plugin_data->rlevelsq1;
 
158
        LADSPA_Data *rlevelsqe = plugin_data->rlevelsqe;
 
159
        LADSPA_Data *rlevelsqn = plugin_data->rlevelsqn;
 
160
        float rmastergain0 = plugin_data->rmastergain0;
 
161
        float rpeakgain0 = plugin_data->rpeakgain0;
 
162
        float rpeakgain1 = plugin_data->rpeakgain1;
 
163
        float rpeaklimitdelay = plugin_data->rpeaklimitdelay;
 
164
        float sample_rate = plugin_data->sample_rate;
 
165
#line 105 "dyson_compress_1403.xml"
 
166
        unsigned int i;
 
167
 
 
168
        for (i=0; i<ndelay; i++) {
 
169
          delay[i] = 0;
 
170
        }
 
171
        for (i=0; i<NFILT + 1; i++) {
 
172
          rlevelsqn[i] = 0;
 
173
        }
 
174
        for (i=0; i<NEFILT + 1; i++) {
 
175
          rlevelsqe[i] = 0;
 
176
        }
 
177
 
 
178
        mingain = 10000;
 
179
        maxgain = 0;
 
180
 
 
181
        rpeaklimitdelay = 2500;
 
182
    
 
183
        rgain = rmastergain0 = 1.0;
 
184
        rlevelsq0 = 0;
 
185
        rlevelsq1 = 0;
 
186
    
 
187
        rpeakgain0 = 1.0;
 
188
        rpeakgain1 = 1.0;
 
189
        rpeaklimitdelay = 0;
 
190
        ndelayptr = 0;
 
191
        lastrgain = 1.0;
 
192
 
 
193
        extra_maxlevel = 0.0f;
 
194
        peaklimitdelay = 0;
 
195
        plugin_data->delay = delay;
 
196
        plugin_data->extra_maxlevel = extra_maxlevel;
 
197
        plugin_data->lastrgain = lastrgain;
 
198
        plugin_data->maxgain = maxgain;
 
199
        plugin_data->mingain = mingain;
 
200
        plugin_data->ndelay = ndelay;
 
201
        plugin_data->ndelayptr = ndelayptr;
 
202
        plugin_data->peaklimitdelay = peaklimitdelay;
 
203
        plugin_data->rgain = rgain;
 
204
        plugin_data->rlevelsq0 = rlevelsq0;
 
205
        plugin_data->rlevelsq1 = rlevelsq1;
 
206
        plugin_data->rlevelsqe = rlevelsqe;
 
207
        plugin_data->rlevelsqn = rlevelsqn;
 
208
        plugin_data->rmastergain0 = rmastergain0;
 
209
        plugin_data->rpeakgain0 = rpeakgain0;
 
210
        plugin_data->rpeakgain1 = rpeakgain1;
 
211
        plugin_data->rpeaklimitdelay = rpeaklimitdelay;
 
212
        plugin_data->sample_rate = sample_rate;
 
213
 
 
214
}
 
215
 
 
216
static void cleanupDysonCompress(LADSPA_Handle instance) {
 
217
#line 137 "dyson_compress_1403.xml"
 
218
        DysonCompress *plugin_data = (DysonCompress *)instance;
 
219
        free(plugin_data->delay);
 
220
        free(plugin_data->rlevelsqn);
 
221
        free(plugin_data->rlevelsqe);
 
222
        free(instance);
 
223
}
 
224
 
 
225
static void connectPortDysonCompress(
 
226
 LADSPA_Handle instance,
 
227
 unsigned long port,
 
228
 LADSPA_Data *data) {
 
229
        DysonCompress *plugin;
 
230
 
 
231
        plugin = (DysonCompress *)instance;
 
232
        switch (port) {
 
233
        case DYSONCOMPRESS_PEAK_LIMIT:
 
234
                plugin->peak_limit = data;
 
235
                break;
 
236
        case DYSONCOMPRESS_RELEASE_TIME:
 
237
                plugin->release_time = data;
 
238
                break;
 
239
        case DYSONCOMPRESS_CFRATE:
 
240
                plugin->cfrate = data;
 
241
                break;
 
242
        case DYSONCOMPRESS_CRATE:
 
243
                plugin->crate = data;
 
244
                break;
 
245
        case DYSONCOMPRESS_INPUT:
 
246
                plugin->input = data;
 
247
                break;
 
248
        case DYSONCOMPRESS_OUTPUT:
 
249
                plugin->output = data;
 
250
                break;
 
251
        }
 
252
}
 
253
 
 
254
static LADSPA_Handle instantiateDysonCompress(
 
255
 const LADSPA_Descriptor *descriptor,
 
256
 unsigned long s_rate) {
 
257
        DysonCompress *plugin_data = (DysonCompress *)malloc(sizeof(DysonCompress));
 
258
        LADSPA_Data *delay = NULL;
 
259
        float extra_maxlevel;
 
260
        float lastrgain;
 
261
        float maxgain;
 
262
        float mingain;
 
263
        float ndelay;
 
264
        unsigned int ndelayptr;
 
265
        int peaklimitdelay;
 
266
        float rgain;
 
267
        float rlevelsq0;
 
268
        float rlevelsq1;
 
269
        LADSPA_Data *rlevelsqe = NULL;
 
270
        LADSPA_Data *rlevelsqn = NULL;
 
271
        float rmastergain0;
 
272
        float rpeakgain0;
 
273
        float rpeakgain1;
 
274
        float rpeaklimitdelay;
 
275
        float sample_rate;
 
276
 
 
277
#line 78 "dyson_compress_1403.xml"
 
278
        sample_rate = (float)s_rate;
 
279
 
 
280
        mingain = 10000;
 
281
        maxgain = 0;
 
282
 
 
283
        rpeaklimitdelay = 2500;
 
284
    
 
285
        rgain = rmastergain0 = 1.0;
 
286
        rlevelsq0 = 0;
 
287
        rlevelsq1 = 0;
 
288
        ndelay = (int)(1.0 / RLEVELSQ0FFILTER);
 
289
 
 
290
        delay = calloc(ndelay, sizeof(LADSPA_Data));
 
291
        rlevelsqn = calloc(NFILT + 1, sizeof(float));
 
292
        rlevelsqe = calloc(NEFILT + 1, sizeof(float));
 
293
    
 
294
        rpeakgain0 = 1.0;
 
295
        rpeakgain1 = 1.0;
 
296
        rpeaklimitdelay = 0;
 
297
        ndelayptr = 0;
 
298
        lastrgain = 1.0;
 
299
 
 
300
        extra_maxlevel = 0.0f;
 
301
        peaklimitdelay = 0;
 
302
 
 
303
        plugin_data->delay = delay;
 
304
        plugin_data->extra_maxlevel = extra_maxlevel;
 
305
        plugin_data->lastrgain = lastrgain;
 
306
        plugin_data->maxgain = maxgain;
 
307
        plugin_data->mingain = mingain;
 
308
        plugin_data->ndelay = ndelay;
 
309
        plugin_data->ndelayptr = ndelayptr;
 
310
        plugin_data->peaklimitdelay = peaklimitdelay;
 
311
        plugin_data->rgain = rgain;
 
312
        plugin_data->rlevelsq0 = rlevelsq0;
 
313
        plugin_data->rlevelsq1 = rlevelsq1;
 
314
        plugin_data->rlevelsqe = rlevelsqe;
 
315
        plugin_data->rlevelsqn = rlevelsqn;
 
316
        plugin_data->rmastergain0 = rmastergain0;
 
317
        plugin_data->rpeakgain0 = rpeakgain0;
 
318
        plugin_data->rpeakgain1 = rpeakgain1;
 
319
        plugin_data->rpeaklimitdelay = rpeaklimitdelay;
 
320
        plugin_data->sample_rate = sample_rate;
 
321
 
 
322
        return (LADSPA_Handle)plugin_data;
 
323
}
 
324
 
 
325
#undef buffer_write
 
326
#undef RUN_ADDING
 
327
#undef RUN_REPLACING
 
328
 
 
329
#define buffer_write(b, v) (b = v)
 
330
#define RUN_ADDING    0
 
331
#define RUN_REPLACING 1
 
332
 
 
333
static void runDysonCompress(LADSPA_Handle instance, unsigned long sample_count) {
 
334
        DysonCompress *plugin_data = (DysonCompress *)instance;
 
335
 
 
336
        /* Peak limit (dB) (float value) */
 
337
        const LADSPA_Data peak_limit = *(plugin_data->peak_limit);
 
338
 
 
339
        /* Release time (s) (float value) */
 
340
        const LADSPA_Data release_time = *(plugin_data->release_time);
 
341
 
 
342
        /* Fast compression ratio (float value) */
 
343
        const LADSPA_Data cfrate = *(plugin_data->cfrate);
 
344
 
 
345
        /* Compression ratio (float value) */
 
346
        const LADSPA_Data crate = *(plugin_data->crate);
 
347
 
 
348
        /* Input (array of floats of length sample_count) */
 
349
        const LADSPA_Data * const input = plugin_data->input;
 
350
 
 
351
        /* Output (array of floats of length sample_count) */
 
352
        LADSPA_Data * const output = plugin_data->output;
 
353
        LADSPA_Data * delay = plugin_data->delay;
 
354
        float extra_maxlevel = plugin_data->extra_maxlevel;
 
355
        float lastrgain = plugin_data->lastrgain;
 
356
        float maxgain = plugin_data->maxgain;
 
357
        float mingain = plugin_data->mingain;
 
358
        float ndelay = plugin_data->ndelay;
 
359
        unsigned int ndelayptr = plugin_data->ndelayptr;
 
360
        int peaklimitdelay = plugin_data->peaklimitdelay;
 
361
        float rgain = plugin_data->rgain;
 
362
        float rlevelsq0 = plugin_data->rlevelsq0;
 
363
        float rlevelsq1 = plugin_data->rlevelsq1;
 
364
        LADSPA_Data * rlevelsqe = plugin_data->rlevelsqe;
 
365
        LADSPA_Data * rlevelsqn = plugin_data->rlevelsqn;
 
366
        float rmastergain0 = plugin_data->rmastergain0;
 
367
        float rpeakgain0 = plugin_data->rpeakgain0;
 
368
        float rpeakgain1 = plugin_data->rpeakgain1;
 
369
        float rpeaklimitdelay = plugin_data->rpeaklimitdelay;
 
370
        float sample_rate = plugin_data->sample_rate;
 
371
 
 
372
#line 143 "dyson_compress_1403.xml"
 
373
        unsigned long pos;
 
374
        float targetlevel = MAXLEVEL * DB_CO(peak_limit);
 
375
        float rgainfilter = 1.0f / (release_time * sample_rate);
 
376
        float fastgaincompressionratio = cfrate;
 
377
        float compressionratio = crate;
 
378
        float efilt;
 
379
        float levelsqe;
 
380
        float gain;
 
381
        float tgain;
 
382
        float d;
 
383
        float fastgain;
 
384
        float qgain;
 
385
        float tslowgain;
 
386
        float slowgain;
 
387
        float npeakgain;
 
388
        float new;
 
389
        float nrgain;
 
390
        float ngain;
 
391
        float ngsq;
 
392
        float tnrgain;
 
393
        float sqrtrpeakgain;
 
394
        float totalgain;
 
395
        unsigned int i;
 
396
 
 
397
        for (pos = 0; pos < sample_count; pos++) {
 
398
          // Ergh! this was originally meant to track a stereo signal
 
399
          float levelsq0 = 2.0f * (input[pos] * input[pos]);
 
400
 
 
401
          delay[ndelayptr] = input[pos];
 
402
          ndelayptr++;
 
403
 
 
404
          if (ndelayptr >= ndelay) {
 
405
            ndelayptr = 0;
 
406
          }
 
407
 
 
408
          if (levelsq0 > rlevelsq0) {
 
409
            rlevelsq0 = (levelsq0 * RLEVELSQ0FFILTER) +
 
410
             rlevelsq0 * (1 - RLEVELSQ0FFILTER);
 
411
          } else {
 
412
            rlevelsq0 = (levelsq0 * RLEVELSQ0FILTER) +
 
413
             rlevelsq0 * (1 - RLEVELSQ0FILTER);
 
414
          }
 
415
 
 
416
          if (rlevelsq0 <= FLOORLEVEL * FLOORLEVEL) {
 
417
            goto skipagc;
 
418
          }
 
419
 
 
420
          if (rlevelsq0 > rlevelsq1) {
 
421
            rlevelsq1 = rlevelsq0;
 
422
          } else {
 
423
            rlevelsq1 = rlevelsq0 * RLEVELSQ1FILTER +
 
424
              rlevelsq1 * (1 - RLEVELSQ1FILTER);
 
425
          }
 
426
 
 
427
          rlevelsqn[0] = rlevelsq1;
 
428
          for(i = 0; i < NFILT-1; i++) {
 
429
            if (rlevelsqn[i] > rlevelsqn[i+1])
 
430
              rlevelsqn[i+1] = rlevelsqn[i];
 
431
            else
 
432
              rlevelsqn[i+1] = rlevelsqn[i] * RLEVELSQ1FILTER +
 
433
                rlevelsqn[i+1] * (1 - RLEVELSQ1FILTER);
 
434
          }
 
435
 
 
436
          efilt = RLEVELSQEFILTER;
 
437
          levelsqe = rlevelsqe[0] = rlevelsqn[NFILT-1];
 
438
          for(i = 0; i < NEFILT-1; i++) {
 
439
            rlevelsqe[i+1] = rlevelsqe[i] * efilt +
 
440
              rlevelsqe[i+1] * (1.0 - efilt);
 
441
            if (rlevelsqe[i+1] > levelsqe)
 
442
              levelsqe = rlevelsqe[i+1];
 
443
            efilt *= 1.0f / 1.5f;
 
444
          }
 
445
 
 
446
          gain = targetlevel / sqrt(levelsqe);
 
447
          if (compressionratio < 0.99f) {
 
448
            if (compressionratio == 0.50f)
 
449
              gain = sqrt(gain);
 
450
            else
 
451
              gain = f_exp(log(gain) * compressionratio);
 
452
          }
 
453
 
 
454
          if (gain < rgain)
 
455
            rgain = gain * RLEVELSQEFILTER/2 +
 
456
              rgain * (1 - RLEVELSQEFILTER/2);
 
457
          else
 
458
            rgain = gain * rgainfilter +
 
459
              rgain * (1 - rgainfilter);
 
460
 
 
461
          lastrgain = rgain;
 
462
          if ( gain < lastrgain)
 
463
            lastrgain = gain;
 
464
 
 
465
        skipagc:;
 
466
 
 
467
          tgain = lastrgain;
 
468
    
 
469
          d = delay[ndelayptr];
 
470
    
 
471
          fastgain = tgain;
 
472
          if (fastgain > MAXFASTGAIN)
 
473
            fastgain = MAXFASTGAIN;
 
474
    
 
475
          if (fastgain < 0.0001)
 
476
            fastgain = 0.0001;
 
477
 
 
478
          qgain = f_exp(log(fastgain) * fastgaincompressionratio);
 
479
 
 
480
          tslowgain = tgain / qgain;
 
481
          if (tslowgain > MAXSLOWGAIN)
 
482
            tslowgain = MAXSLOWGAIN;
 
483
          if (tslowgain < rmastergain0)
 
484
            rmastergain0 = tslowgain;
 
485
          else
 
486
            rmastergain0 = tslowgain * RMASTERGAIN0FILTER +
 
487
              (1 - RMASTERGAIN0FILTER) * rmastergain0;
 
488
    
 
489
          slowgain = rmastergain0;
 
490
          npeakgain = slowgain * qgain;
 
491
    
 
492
          new = d * npeakgain;
 
493
          if (fabs(new) >= MAXLEVEL)
 
494
            nrgain = MAXLEVEL / fabs(new);
 
495
          else
 
496
            nrgain = 1.0;
 
497
    
 
498
          ngain = nrgain;
 
499
    
 
500
          ngsq = ngain * ngain;
 
501
          if (ngsq <= rpeakgain0) {
 
502
            rpeakgain0 = ngsq /* * 0.50 + rpeakgain0 * 0.50 */;
 
503
            rpeaklimitdelay = peaklimitdelay;
 
504
          } else if (rpeaklimitdelay == 0) {
 
505
            if (nrgain > 1.0)
 
506
              tnrgain = 1.0;
 
507
            else
 
508
              tnrgain = nrgain;
 
509
            rpeakgain0 = tnrgain * RPEAKGAINFILTER +
 
510
              (1.0 - RPEAKGAINFILTER) * rpeakgain0;
 
511
          }
 
512
 
 
513
          if (rpeakgain0 <= rpeakgain1) {
 
514
            rpeakgain1 = rpeakgain0;
 
515
            rpeaklimitdelay = peaklimitdelay;
 
516
          } else if (rpeaklimitdelay == 0) {
 
517
            rpeakgain1 = RPEAKGAINFILTER * rpeakgain0 +
 
518
              (1.0 - RPEAKGAINFILTER) * rpeakgain1;
 
519
          } else {
 
520
            --rpeaklimitdelay;
 
521
          }
 
522
 
 
523
          sqrtrpeakgain = sqrt(rpeakgain1);
 
524
          totalgain = npeakgain * sqrtrpeakgain;
 
525
    
 
526
          buffer_write(output[pos], new * sqrtrpeakgain);
 
527
    
 
528
          if (totalgain > maxgain)
 
529
            maxgain = totalgain;
 
530
          if (totalgain < mingain)
 
531
            mingain = totalgain;
 
532
          if (output[pos] > extra_maxlevel)
 
533
            extra_maxlevel = output[pos];
 
534
        }
 
535
 
 
536
        plugin_data->ndelayptr = ndelayptr;
 
537
        plugin_data->rlevelsq0 = rlevelsq0;
 
538
        plugin_data->rlevelsq1 = rlevelsq1;
 
539
        plugin_data->mingain = mingain;
 
540
        plugin_data->maxgain = maxgain;
 
541
        plugin_data->rpeaklimitdelay = rpeaklimitdelay;
 
542
        plugin_data->rgain = rgain;
 
543
        plugin_data->rmastergain0 = rmastergain0;
 
544
        plugin_data->rpeakgain0 = rpeakgain0;
 
545
        plugin_data->rpeakgain1 = rpeakgain1;
 
546
        plugin_data->lastrgain = lastrgain;
 
547
        plugin_data->extra_maxlevel = extra_maxlevel;
 
548
}
 
549
#undef buffer_write
 
550
#undef RUN_ADDING
 
551
#undef RUN_REPLACING
 
552
 
 
553
#define buffer_write(b, v) (b += (v) * run_adding_gain)
 
554
#define RUN_ADDING    1
 
555
#define RUN_REPLACING 0
 
556
 
 
557
static void setRunAddingGainDysonCompress(LADSPA_Handle instance, LADSPA_Data gain) {
 
558
        ((DysonCompress *)instance)->run_adding_gain = gain;
 
559
}
 
560
 
 
561
static void runAddingDysonCompress(LADSPA_Handle instance, unsigned long sample_count) {
 
562
        DysonCompress *plugin_data = (DysonCompress *)instance;
 
563
        LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
 
564
 
 
565
        /* Peak limit (dB) (float value) */
 
566
        const LADSPA_Data peak_limit = *(plugin_data->peak_limit);
 
567
 
 
568
        /* Release time (s) (float value) */
 
569
        const LADSPA_Data release_time = *(plugin_data->release_time);
 
570
 
 
571
        /* Fast compression ratio (float value) */
 
572
        const LADSPA_Data cfrate = *(plugin_data->cfrate);
 
573
 
 
574
        /* Compression ratio (float value) */
 
575
        const LADSPA_Data crate = *(plugin_data->crate);
 
576
 
 
577
        /* Input (array of floats of length sample_count) */
 
578
        const LADSPA_Data * const input = plugin_data->input;
 
579
 
 
580
        /* Output (array of floats of length sample_count) */
 
581
        LADSPA_Data * const output = plugin_data->output;
 
582
        LADSPA_Data * delay = plugin_data->delay;
 
583
        float extra_maxlevel = plugin_data->extra_maxlevel;
 
584
        float lastrgain = plugin_data->lastrgain;
 
585
        float maxgain = plugin_data->maxgain;
 
586
        float mingain = plugin_data->mingain;
 
587
        float ndelay = plugin_data->ndelay;
 
588
        unsigned int ndelayptr = plugin_data->ndelayptr;
 
589
        int peaklimitdelay = plugin_data->peaklimitdelay;
 
590
        float rgain = plugin_data->rgain;
 
591
        float rlevelsq0 = plugin_data->rlevelsq0;
 
592
        float rlevelsq1 = plugin_data->rlevelsq1;
 
593
        LADSPA_Data * rlevelsqe = plugin_data->rlevelsqe;
 
594
        LADSPA_Data * rlevelsqn = plugin_data->rlevelsqn;
 
595
        float rmastergain0 = plugin_data->rmastergain0;
 
596
        float rpeakgain0 = plugin_data->rpeakgain0;
 
597
        float rpeakgain1 = plugin_data->rpeakgain1;
 
598
        float rpeaklimitdelay = plugin_data->rpeaklimitdelay;
 
599
        float sample_rate = plugin_data->sample_rate;
 
600
 
 
601
#line 143 "dyson_compress_1403.xml"
 
602
        unsigned long pos;
 
603
        float targetlevel = MAXLEVEL * DB_CO(peak_limit);
 
604
        float rgainfilter = 1.0f / (release_time * sample_rate);
 
605
        float fastgaincompressionratio = cfrate;
 
606
        float compressionratio = crate;
 
607
        float efilt;
 
608
        float levelsqe;
 
609
        float gain;
 
610
        float tgain;
 
611
        float d;
 
612
        float fastgain;
 
613
        float qgain;
 
614
        float tslowgain;
 
615
        float slowgain;
 
616
        float npeakgain;
 
617
        float new;
 
618
        float nrgain;
 
619
        float ngain;
 
620
        float ngsq;
 
621
        float tnrgain;
 
622
        float sqrtrpeakgain;
 
623
        float totalgain;
 
624
        unsigned int i;
 
625
 
 
626
        for (pos = 0; pos < sample_count; pos++) {
 
627
          // Ergh! this was originally meant to track a stereo signal
 
628
          float levelsq0 = 2.0f * (input[pos] * input[pos]);
 
629
 
 
630
          delay[ndelayptr] = input[pos];
 
631
          ndelayptr++;
 
632
 
 
633
          if (ndelayptr >= ndelay) {
 
634
            ndelayptr = 0;
 
635
          }
 
636
 
 
637
          if (levelsq0 > rlevelsq0) {
 
638
            rlevelsq0 = (levelsq0 * RLEVELSQ0FFILTER) +
 
639
             rlevelsq0 * (1 - RLEVELSQ0FFILTER);
 
640
          } else {
 
641
            rlevelsq0 = (levelsq0 * RLEVELSQ0FILTER) +
 
642
             rlevelsq0 * (1 - RLEVELSQ0FILTER);
 
643
          }
 
644
 
 
645
          if (rlevelsq0 <= FLOORLEVEL * FLOORLEVEL) {
 
646
            goto skipagc;
 
647
          }
 
648
 
 
649
          if (rlevelsq0 > rlevelsq1) {
 
650
            rlevelsq1 = rlevelsq0;
 
651
          } else {
 
652
            rlevelsq1 = rlevelsq0 * RLEVELSQ1FILTER +
 
653
              rlevelsq1 * (1 - RLEVELSQ1FILTER);
 
654
          }
 
655
 
 
656
          rlevelsqn[0] = rlevelsq1;
 
657
          for(i = 0; i < NFILT-1; i++) {
 
658
            if (rlevelsqn[i] > rlevelsqn[i+1])
 
659
              rlevelsqn[i+1] = rlevelsqn[i];
 
660
            else
 
661
              rlevelsqn[i+1] = rlevelsqn[i] * RLEVELSQ1FILTER +
 
662
                rlevelsqn[i+1] * (1 - RLEVELSQ1FILTER);
 
663
          }
 
664
 
 
665
          efilt = RLEVELSQEFILTER;
 
666
          levelsqe = rlevelsqe[0] = rlevelsqn[NFILT-1];
 
667
          for(i = 0; i < NEFILT-1; i++) {
 
668
            rlevelsqe[i+1] = rlevelsqe[i] * efilt +
 
669
              rlevelsqe[i+1] * (1.0 - efilt);
 
670
            if (rlevelsqe[i+1] > levelsqe)
 
671
              levelsqe = rlevelsqe[i+1];
 
672
            efilt *= 1.0f / 1.5f;
 
673
          }
 
674
 
 
675
          gain = targetlevel / sqrt(levelsqe);
 
676
          if (compressionratio < 0.99f) {
 
677
            if (compressionratio == 0.50f)
 
678
              gain = sqrt(gain);
 
679
            else
 
680
              gain = f_exp(log(gain) * compressionratio);
 
681
          }
 
682
 
 
683
          if (gain < rgain)
 
684
            rgain = gain * RLEVELSQEFILTER/2 +
 
685
              rgain * (1 - RLEVELSQEFILTER/2);
 
686
          else
 
687
            rgain = gain * rgainfilter +
 
688
              rgain * (1 - rgainfilter);
 
689
 
 
690
          lastrgain = rgain;
 
691
          if ( gain < lastrgain)
 
692
            lastrgain = gain;
 
693
 
 
694
        skipagc:;
 
695
 
 
696
          tgain = lastrgain;
 
697
    
 
698
          d = delay[ndelayptr];
 
699
    
 
700
          fastgain = tgain;
 
701
          if (fastgain > MAXFASTGAIN)
 
702
            fastgain = MAXFASTGAIN;
 
703
    
 
704
          if (fastgain < 0.0001)
 
705
            fastgain = 0.0001;
 
706
 
 
707
          qgain = f_exp(log(fastgain) * fastgaincompressionratio);
 
708
 
 
709
          tslowgain = tgain / qgain;
 
710
          if (tslowgain > MAXSLOWGAIN)
 
711
            tslowgain = MAXSLOWGAIN;
 
712
          if (tslowgain < rmastergain0)
 
713
            rmastergain0 = tslowgain;
 
714
          else
 
715
            rmastergain0 = tslowgain * RMASTERGAIN0FILTER +
 
716
              (1 - RMASTERGAIN0FILTER) * rmastergain0;
 
717
    
 
718
          slowgain = rmastergain0;
 
719
          npeakgain = slowgain * qgain;
 
720
    
 
721
          new = d * npeakgain;
 
722
          if (fabs(new) >= MAXLEVEL)
 
723
            nrgain = MAXLEVEL / fabs(new);
 
724
          else
 
725
            nrgain = 1.0;
 
726
    
 
727
          ngain = nrgain;
 
728
    
 
729
          ngsq = ngain * ngain;
 
730
          if (ngsq <= rpeakgain0) {
 
731
            rpeakgain0 = ngsq /* * 0.50 + rpeakgain0 * 0.50 */;
 
732
            rpeaklimitdelay = peaklimitdelay;
 
733
          } else if (rpeaklimitdelay == 0) {
 
734
            if (nrgain > 1.0)
 
735
              tnrgain = 1.0;
 
736
            else
 
737
              tnrgain = nrgain;
 
738
            rpeakgain0 = tnrgain * RPEAKGAINFILTER +
 
739
              (1.0 - RPEAKGAINFILTER) * rpeakgain0;
 
740
          }
 
741
 
 
742
          if (rpeakgain0 <= rpeakgain1) {
 
743
            rpeakgain1 = rpeakgain0;
 
744
            rpeaklimitdelay = peaklimitdelay;
 
745
          } else if (rpeaklimitdelay == 0) {
 
746
            rpeakgain1 = RPEAKGAINFILTER * rpeakgain0 +
 
747
              (1.0 - RPEAKGAINFILTER) * rpeakgain1;
 
748
          } else {
 
749
            --rpeaklimitdelay;
 
750
          }
 
751
 
 
752
          sqrtrpeakgain = sqrt(rpeakgain1);
 
753
          totalgain = npeakgain * sqrtrpeakgain;
 
754
    
 
755
          buffer_write(output[pos], new * sqrtrpeakgain);
 
756
    
 
757
          if (totalgain > maxgain)
 
758
            maxgain = totalgain;
 
759
          if (totalgain < mingain)
 
760
            mingain = totalgain;
 
761
          if (output[pos] > extra_maxlevel)
 
762
            extra_maxlevel = output[pos];
 
763
        }
 
764
 
 
765
        plugin_data->ndelayptr = ndelayptr;
 
766
        plugin_data->rlevelsq0 = rlevelsq0;
 
767
        plugin_data->rlevelsq1 = rlevelsq1;
 
768
        plugin_data->mingain = mingain;
 
769
        plugin_data->maxgain = maxgain;
 
770
        plugin_data->rpeaklimitdelay = rpeaklimitdelay;
 
771
        plugin_data->rgain = rgain;
 
772
        plugin_data->rmastergain0 = rmastergain0;
 
773
        plugin_data->rpeakgain0 = rpeakgain0;
 
774
        plugin_data->rpeakgain1 = rpeakgain1;
 
775
        plugin_data->lastrgain = lastrgain;
 
776
        plugin_data->extra_maxlevel = extra_maxlevel;
 
777
}
 
778
 
 
779
void _init() {
 
780
        char **port_names;
 
781
        LADSPA_PortDescriptor *port_descriptors;
 
782
        LADSPA_PortRangeHint *port_range_hints;
 
783
 
 
784
#ifdef ENABLE_NLS
 
785
#define D_(s) dgettext(PACKAGE, s)
 
786
        setlocale(LC_ALL, "");
 
787
        bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
 
788
#else
 
789
#define D_(s) (s)
 
790
#endif
 
791
 
 
792
 
 
793
        dysonCompressDescriptor =
 
794
         (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
 
795
 
 
796
        if (dysonCompressDescriptor) {
 
797
                dysonCompressDescriptor->UniqueID = 1403;
 
798
                dysonCompressDescriptor->Label = "dysonCompress";
 
799
                dysonCompressDescriptor->Properties =
 
800
                 LADSPA_PROPERTY_HARD_RT_CAPABLE;
 
801
                dysonCompressDescriptor->Name =
 
802
                 D_("Dyson compressor");
 
803
                dysonCompressDescriptor->Maker =
 
804
                 "Steve Harris <steve@plugin.org.uk>";
 
805
                dysonCompressDescriptor->Copyright =
 
806
                 "GPL";
 
807
                dysonCompressDescriptor->PortCount = 6;
 
808
 
 
809
                port_descriptors = (LADSPA_PortDescriptor *)calloc(6,
 
810
                 sizeof(LADSPA_PortDescriptor));
 
811
                dysonCompressDescriptor->PortDescriptors =
 
812
                 (const LADSPA_PortDescriptor *)port_descriptors;
 
813
 
 
814
                port_range_hints = (LADSPA_PortRangeHint *)calloc(6,
 
815
                 sizeof(LADSPA_PortRangeHint));
 
816
                dysonCompressDescriptor->PortRangeHints =
 
817
                 (const LADSPA_PortRangeHint *)port_range_hints;
 
818
 
 
819
                port_names = (char **)calloc(6, sizeof(char*));
 
820
                dysonCompressDescriptor->PortNames =
 
821
                 (const char **)port_names;
 
822
 
 
823
                /* Parameters for Peak limit (dB) */
 
824
                port_descriptors[DYSONCOMPRESS_PEAK_LIMIT] =
 
825
                 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
 
826
                port_names[DYSONCOMPRESS_PEAK_LIMIT] =
 
827
                 D_("Peak limit (dB)");
 
828
                port_range_hints[DYSONCOMPRESS_PEAK_LIMIT].HintDescriptor =
 
829
                 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
 
830
                port_range_hints[DYSONCOMPRESS_PEAK_LIMIT].LowerBound = -30;
 
831
                port_range_hints[DYSONCOMPRESS_PEAK_LIMIT].UpperBound = 0;
 
832
 
 
833
                /* Parameters for Release time (s) */
 
834
                port_descriptors[DYSONCOMPRESS_RELEASE_TIME] =
 
835
                 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
 
836
                port_names[DYSONCOMPRESS_RELEASE_TIME] =
 
837
                 D_("Release time (s)");
 
838
                port_range_hints[DYSONCOMPRESS_RELEASE_TIME].HintDescriptor =
 
839
                 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW;
 
840
                port_range_hints[DYSONCOMPRESS_RELEASE_TIME].LowerBound = 0;
 
841
                port_range_hints[DYSONCOMPRESS_RELEASE_TIME].UpperBound = 1;
 
842
 
 
843
                /* Parameters for Fast compression ratio */
 
844
                port_descriptors[DYSONCOMPRESS_CFRATE] =
 
845
                 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
 
846
                port_names[DYSONCOMPRESS_CFRATE] =
 
847
                 D_("Fast compression ratio");
 
848
                port_range_hints[DYSONCOMPRESS_CFRATE].HintDescriptor =
 
849
                 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
 
850
                port_range_hints[DYSONCOMPRESS_CFRATE].LowerBound = 0;
 
851
                port_range_hints[DYSONCOMPRESS_CFRATE].UpperBound = 1;
 
852
 
 
853
                /* Parameters for Compression ratio */
 
854
                port_descriptors[DYSONCOMPRESS_CRATE] =
 
855
                 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
 
856
                port_names[DYSONCOMPRESS_CRATE] =
 
857
                 D_("Compression ratio");
 
858
                port_range_hints[DYSONCOMPRESS_CRATE].HintDescriptor =
 
859
                 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE;
 
860
                port_range_hints[DYSONCOMPRESS_CRATE].LowerBound = 0;
 
861
                port_range_hints[DYSONCOMPRESS_CRATE].UpperBound = 1;
 
862
 
 
863
                /* Parameters for Input */
 
864
                port_descriptors[DYSONCOMPRESS_INPUT] =
 
865
                 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
 
866
                port_names[DYSONCOMPRESS_INPUT] =
 
867
                 D_("Input");
 
868
                port_range_hints[DYSONCOMPRESS_INPUT].HintDescriptor = 0;
 
869
 
 
870
                /* Parameters for Output */
 
871
                port_descriptors[DYSONCOMPRESS_OUTPUT] =
 
872
                 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
 
873
                port_names[DYSONCOMPRESS_OUTPUT] =
 
874
                 D_("Output");
 
875
                port_range_hints[DYSONCOMPRESS_OUTPUT].HintDescriptor = 0;
 
876
 
 
877
                dysonCompressDescriptor->activate = activateDysonCompress;
 
878
                dysonCompressDescriptor->cleanup = cleanupDysonCompress;
 
879
                dysonCompressDescriptor->connect_port = connectPortDysonCompress;
 
880
                dysonCompressDescriptor->deactivate = NULL;
 
881
                dysonCompressDescriptor->instantiate = instantiateDysonCompress;
 
882
                dysonCompressDescriptor->run = runDysonCompress;
 
883
                dysonCompressDescriptor->run_adding = runAddingDysonCompress;
 
884
                dysonCompressDescriptor->set_run_adding_gain = setRunAddingGainDysonCompress;
 
885
        }
 
886
}
 
887
 
 
888
void _fini() {
 
889
        if (dysonCompressDescriptor) {
 
890
                free((LADSPA_PortDescriptor *)dysonCompressDescriptor->PortDescriptors);
 
891
                free((char **)dysonCompressDescriptor->PortNames);
 
892
                free((LADSPA_PortRangeHint *)dysonCompressDescriptor->PortRangeHints);
 
893
                free(dysonCompressDescriptor);
 
894
        }
 
895
 
 
896
}