~ubuntu-branches/ubuntu/trusty/phonon/trusty-updates

« back to all changes in this revision

Viewing changes to xine/kequalizer_plugin.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Modestas Vainius
  • Date: 2011-03-11 21:39:20 UTC
  • mfrom: (6.1.4 experimental)
  • Revision ID: james.westby@ubuntu.com-20110311213920-pvkmqc1gdpy88uzx
Tags: 4:4.6.0really4.4.4-2
* Drop phonon-backends-dbg from phonon-dbg Recommends/Breaks. No longer
  needed.
* Readd packaging copyright/licensing to debian/copyright.
* Bump libphonon-dev Breaks/Replaces to << 4:4.6.0really4.4.4 for
  libphononexperimental-dev. experimental/avcaptureinterface.h header which
  used to be there up to 4.4.4 (see changelog below).
* Switch debian/rules build engine to dhmk (qt-kde-team/2/*):
  - build-depend on pkg-kde-tools >= 0.11;
  - port debian/rules to dhmk keeping it dh compatible as much as possible.
* Drop unused ${shlibs:Depends} from libphonon-dev and
  libphononexperimental-dev packages.
* Add README.Debian to phonon-backend-null package.
* Remove phonon-backend-null.lintian-overrides: phonon-backend-null is no
  longer and empty package due to README.Debian (see above).
* Release to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  This file is part of the KDE project
2
 
    Copyright (C) 2009 Artur Szymiec <artur.szymiec@gmail.com>
3
 
 
4
 
    This program is free software; you can redistribute it and/or
5
 
    modify it under the terms of the GNU Library General Public
6
 
    License as published by the Free Software Foundation; either
7
 
    version 2 of the License, or (at your option) any later version.
8
 
 
9
 
    This library is distributed in the hope that it will be useful,
10
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
    Library General Public License for more details.
13
 
 
14
 
    You should have received a copy of the GNU Library General Public License
15
 
    along with this library; see the file COPYING.LIB.  If not, write to
16
 
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 
    Boston, MA 02110-1301, USA.
18
 
 
19
 
*/
20
 
 
21
 
/* Equalizer GPL code Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
22
 
   Equalizer filter, implementation of a 10 band time domain graphic
23
 
   equalizer using IIR filters. The IIR filters are implemented using a
24
 
   Direct Form II approach, but has been modified (b1 == 0 always) to
25
 
   save computation.
26
 
   
27
 
   Adopted to phnon xine engine plugin by Artur Szymiec in 2009 artur.szymiec@gmail.com
28
 
*/
29
 
 
30
 
#ifndef I18N_NOOP
31
 
#define I18N_NOOP(x) x
32
 
#endif
33
 
 
34
 
#include "backend.h"
35
 
 
36
 
#include <QObject>
37
 
#include <cmath>
38
 
 
39
 
#define __STDC_FORMAT_MACROS
40
 
#include <inttypes.h>
41
 
 
42
 
#include <xine.h>
43
 
extern "C" {
44
 
// xine headers use the reserved keyword this:
45
 
#define this this_xine
46
 
#include <xine/compat.h>
47
 
#include <xine/post.h>
48
 
#include <xine/xineutils.h>
49
 
#undef this
50
 
 
51
 
#define KEQUALIZER_MAX_GAIN 12.0
52
 
#define KEQUALIZER_L       2      // Storage for filter taps
53
 
#define KEQUALIZER_KM      10     // Max number of bands 
54
 
#define KEQUALIZER_Q       1.2247449 
55
 
/* Q value for band-pass filters 1.2247=(3/2)^(1/2)
56
 
gives 4dB suppression @ Fc*2 and Fc/2 */
57
 
#define KEQUALIZER_CF {60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000}
58
 
// Maximum and minimum gain for the bands
59
 
#define KEQUALIZER_G_MAX   +12.0
60
 
#define KEQUALIZER_G_MIN   -12.0
61
 
#define KEQUALIZER_CHANNELS_MAX 6
62
 
 
63
 
typedef struct
64
 
{
65
 
    post_class_t post_class;
66
 
    xine_t *xine;
67
 
} kequalizer_class_t;
68
 
 
69
 
typedef struct KEqualizerPlugin
70
 
{
71
 
    post_plugin_t post;
72
 
 
73
 
    /* private data */
74
 
    pthread_mutex_t    lock;
75
 
    xine_post_in_t params_input;
76
 
 
77
 
    int rate;
78
 
    int bits;
79
 
    double preAmp;
80
 
    double eqBands[10];
81
 
    //kequalizer_s kequalizer_t;
82
 
    float   a[KEQUALIZER_KM][KEQUALIZER_L];             // A weights
83
 
    float   b[KEQUALIZER_KM][KEQUALIZER_L];             // B weights
84
 
    float   wq[KEQUALIZER_CHANNELS_MAX][KEQUALIZER_KM][KEQUALIZER_L];    // Circular buffer for W data
85
 
    float   g[KEQUALIZER_CHANNELS_MAX][KEQUALIZER_KM];        // Gain factor for each channel and band
86
 
    int     K;                    // Number of used eq bands
87
 
    int     channels;             // Number of channels
88
 
    /* Functions */
89
 
    void equalize_Buffer(xine_post_t *this_gen,audio_buffer_t *buf);
90
 
    void eq_calc_Bp2(float* a, float* b, float fc, float q);
91
 
    void eq_calc_Gains(xine_post_t *this_gen);
92
 
    void eq_setup_Filters(xine_post_t *this_gen);
93
 
} kequalizer_plugin_t;
94
 
 
95
 
/**************************************************************************
96
 
 * parameters
97
 
 *************************************************************************/
98
 
 
99
 
typedef struct
100
 
{
101
 
    double preAmp;
102
 
    double eqBands[10];
103
 
} kequalizer_parameters_t;
104
 
 
105
 
/*
106
 
 * description of params struct
107
 
 */
108
 
START_PARAM_DESCR(kequalizer_parameters_t)
109
 
 
110
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, preAmp, NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Equalizer pre-amp gain"))
111
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[0], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 1 60Hz Gain"))
112
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[1], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 2 170Hz Gain"))
113
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[2], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 3 310Hz Gain"))
114
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[3], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 4 600Hz Gain"))
115
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[4], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 5 1000Hz Gain"))
116
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[5], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 6 3000Hz Gain"))
117
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[6], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 7 6000Hz Gain"))
118
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[7], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 8 12000Hz Gain"))
119
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[8], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 9 14000Hz Gain"))
120
 
PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, eqBands[9], NULL, -KEQUALIZER_MAX_GAIN, KEQUALIZER_MAX_GAIN, 0, I18N_NOOP("Band 10 16000Hz Gain"))
121
 
 
122
 
END_PARAM_DESCR(param_descr)
123
 
 
124
 
static int set_parameters (xine_post_t *this_gen, void *param_gen) 
125
 
{
126
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(this_gen);
127
 
    kequalizer_parameters_t *param = static_cast<kequalizer_parameters_t *>(param_gen);
128
 
 
129
 
    pthread_mutex_lock (&that->lock);
130
 
    
131
 
    that->preAmp = param->preAmp;
132
 
    for (int i=0;i<=9;i++){
133
 
        that->eqBands[i]=param->eqBands[i];
134
 
    }
135
 
  
136
 
    that->eq_calc_Gains(this_gen);
137
 
    
138
 
    const char *x = "kequalizer:";
139
 
    Phonon::Xine::debug() << Q_FUNC_INFO
140
 
        << x
141
 
        << param->preAmp
142
 
        << param->eqBands[0]
143
 
        << param->eqBands[1]
144
 
        << param->eqBands[2]
145
 
        << param->eqBands[3]
146
 
        << param->eqBands[4]
147
 
        << param->eqBands[5]
148
 
        << param->eqBands[6]
149
 
        << param->eqBands[7]
150
 
        << param->eqBands[8]
151
 
        << param->eqBands[9]
152
 
        ;    
153
 
    pthread_mutex_unlock (&that->lock);
154
 
    
155
 
    return 1;
156
 
}
157
 
 
158
 
static int get_parameters (xine_post_t *this_gen, void *param_gen) 
159
 
{
160
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(this_gen);
161
 
    kequalizer_parameters_t *param = static_cast<kequalizer_parameters_t *>(param_gen);
162
 
 
163
 
    pthread_mutex_lock (&that->lock);
164
 
    
165
 
    param->preAmp = that->preAmp;
166
 
    for (int i=0;i<=9;i++){
167
 
        param->eqBands[i]=that->eqBands[i];
168
 
    }
169
 
    
170
 
    pthread_mutex_unlock (&that->lock);
171
 
 
172
 
    return 1;
173
 
}
174
 
 
175
 
static xine_post_api_descr_t *get_param_descr()
176
 
{
177
 
    return &param_descr;
178
 
}
179
 
 
180
 
static char *get_help ()
181
 
{
182
 
    static QByteArray helpText(
183
 
           QObject::tr("Equalizes audio using the very good IIR equalizer code by  "
184
 
                 "Anders Johansson adopted from Audacious project.\n"
185
 
                 "\n"
186
 
                 "Parameters:\n"
187
 
                 "Preamp gain - used to alter up or down all gain values\n"
188
 
                 "10 Equalizer bands - actual IIR equalizer parameters.\n").toUtf8());
189
 
    return helpText.data();
190
 
}
191
 
 
192
 
static xine_post_api_t post_api = {
193
 
    set_parameters,
194
 
    get_parameters,
195
 
    get_param_descr,
196
 
    get_help,
197
 
};
198
 
 
199
 
 
200
 
/**************************************************************************
201
 
 * xine audio post plugin functions
202
 
 *************************************************************************/
203
 
 
204
 
static int kequalizer_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
205
 
                             uint32_t bits, uint32_t rate, int mode)
206
 
{
207
 
    post_audio_port_t *port = reinterpret_cast<post_audio_port_t *>(port_gen);
208
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(port->post);
209
 
    xine_post_t *post = reinterpret_cast<xine_post_t *>(port->post);
210
 
 
211
 
    _x_post_rewire(&that->post);
212
 
    _x_post_inc_usage(port);
213
 
 
214
 
    port->stream = stream;
215
 
    port->bits = bits;
216
 
    port->rate = rate;
217
 
    port->mode = mode;
218
 
    that->rate = rate;
219
 
    that->bits = bits;
220
 
    
221
 
    switch (mode) {
222
 
    case AO_CAP_MODE_STEREO:
223
 
        that->channels = 2;
224
 
        break;
225
 
    case AO_CAP_MODE_4CHANNEL:
226
 
        that->channels = 4;
227
 
        break;
228
 
    case AO_CAP_MODE_4_1CHANNEL:
229
 
    case AO_CAP_MODE_5CHANNEL:
230
 
    case AO_CAP_MODE_5_1CHANNEL:
231
 
        that->channels = 6;
232
 
        break;
233
 
    }
234
 
    
235
 
    that->eq_setup_Filters(post);
236
 
    that->eq_calc_Gains(post);
237
 
    
238
 
    return port->original_port->open(port->original_port, stream, bits, rate, mode);
239
 
}
240
 
 
241
 
static void kequalizer_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream)
242
 
{
243
 
    post_audio_port_t *port = reinterpret_cast<post_audio_port_t *>(port_gen);
244
 
 
245
 
    port->stream = NULL;
246
 
    port->original_port->close(port->original_port, stream);
247
 
    _x_post_dec_usage(port);
248
 
}
249
 
 
250
 
static void kequalizer_port_put_buffer(xine_audio_port_t *port_gen,
251
 
        audio_buffer_t *buf, xine_stream_t *stream)
252
 
{
253
 
    post_audio_port_t *port = reinterpret_cast<post_audio_port_t *>(port_gen);
254
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(port->post);
255
 
    xine_post_t *post = reinterpret_cast<xine_post_t *>(port->post);
256
 
    
257
 
    // Do actual equalization
258
 
    that->equalize_Buffer(post,buf);
259
 
    // and send the modified buffer to the original port
260
 
    port->original_port->put_buffer(port->original_port, buf, stream);
261
 
    return;
262
 
}
263
 
 
264
 
static void kequalizer_dispose(post_plugin_t *this_gen)
265
 
{
266
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(this_gen);
267
 
 
268
 
    if (_x_post_dispose(this_gen)) {
269
 
        pthread_mutex_destroy(&that->lock);
270
 
        free(that);
271
 
    }
272
 
}
273
 
 
274
 
/* plugin class functions */
275
 
static post_plugin_t *kequalizer_open_plugin(post_class_t *class_gen, int inputs,
276
 
                                          xine_audio_port_t **audio_target,
277
 
                                          xine_video_port_t **video_target)
278
 
{
279
 
    Q_UNUSED(class_gen);
280
 
    Q_UNUSED(inputs);
281
 
    Q_UNUSED(video_target);
282
 
    kequalizer_plugin_t *that;
283
 
    //deprecated: kequalizer_plugin_t *that = static_cast<kequalizer_plugin_t *>(xine_xmalloc(sizeof(kequalizer_plugin_t)));
284
 
    xine_xmalloc_aligned(2,sizeof(kequalizer_plugin_t),(void**)(&that));
285
 
    post_in_t           *input;
286
 
    post_out_t          *output;
287
 
    xine_post_in_t      *input_api;
288
 
    post_audio_port_t   *port;
289
 
 
290
 
    // refuse to work without an audio port to decorate
291
 
    if (!that || !audio_target || !audio_target[0]) {
292
 
        free(that);
293
 
        return NULL;
294
 
    }
295
 
 
296
 
    // creates 1 audio I/O, 0 video I/O
297
 
    _x_post_init(&that->post, 1, 0);
298
 
    pthread_mutex_init (&that->lock, NULL);
299
 
 
300
 
    // init private data
301
 
   
302
 
    // the following call wires our plugin in front of the given audio_target
303
 
    port = _x_post_intercept_audio_port(&that->post, audio_target[0], &input, &output);
304
 
    // the methods of new_port are all forwarded to audio_target, overwrite a few of them here:
305
 
    port->new_port.open       = kequalizer_port_open;
306
 
    port->new_port.close      = kequalizer_port_close;
307
 
    port->new_port.put_buffer = kequalizer_port_put_buffer;
308
 
 
309
 
    // add a parameter input to the plugin
310
 
    input_api       = &that->params_input;
311
 
    input_api->name = "parameters";
312
 
    input_api->type = XINE_POST_DATA_PARAMETERS;
313
 
    input_api->data = &post_api;
314
 
    xine_list_push_back(that->post.input, input_api);
315
 
 
316
 
    that->post.xine_post.audio_input[0] = &port->new_port;
317
 
 
318
 
    // our own cleanup function
319
 
    that->post.dispose = kequalizer_dispose;
320
 
 
321
 
    return &that->post;
322
 
}
323
 
 
324
 
#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && (XINE_MINOR_VERSION < 1 || (XINE_MINOR_VERSION == 1 && XINE_SUB_VERSION < 90)))
325
 
#define NEED_DESCRIPTION_FUNCTION 1
326
 
#else
327
 
#define NEED_DESCRIPTION_FUNCTION 0
328
 
#endif
329
 
 
330
 
#define PLUGIN_DESCRIPTION I18N_NOOP("Fade in or fade out with different fade curves")
331
 
#define PLUGIN_IDENTIFIER "KVolumeFader"
332
 
 
333
 
#if NEED_DESCRIPTION_FUNCTION
334
 
static char *kequalizer_get_identifier(post_class_t *class_gen)
335
 
{
336
 
    Q_UNUSED(class_gen);
337
 
    return PLUGIN_IDENTIFIER;
338
 
}
339
 
 
340
 
static char *kequalizer_get_description(post_class_t *class_gen)
341
 
{
342
 
    Q_UNUSED(class_gen);
343
 
    static QByteArray description(QObject::tr(PLUGIN_DESCRIPTION).toUtf8());
344
 
    return description.data();
345
 
}
346
 
#endif
347
 
 
348
 
static void kequalizer_class_dispose(post_class_t *class_gen)
349
 
{
350
 
    free(class_gen);
351
 
}
352
 
 
353
 
/* plugin class initialization function */
354
 
void *init_kequalizer_plugin (xine_t *xine, void *)
355
 
{
356
 
    kequalizer_class_t *_class = static_cast<kequalizer_class_t *>(malloc(sizeof(kequalizer_class_t)));
357
 
 
358
 
    if (!_class) {
359
 
        return NULL;
360
 
    }
361
 
 
362
 
    _class->post_class.open_plugin     = kequalizer_open_plugin;
363
 
#if NEED_DESCRIPTION_FUNCTION
364
 
    _class->post_class.get_identifier  = kequalizer_get_identifier;
365
 
    _class->post_class.get_description = kequalizer_get_description;
366
 
#else
367
 
    _class->post_class.description     = PLUGIN_DESCRIPTION;
368
 
    _class->post_class.text_domain     = "phonon-xine";
369
 
    _class->post_class.identifier      = PLUGIN_IDENTIFIER;
370
 
#endif
371
 
    _class->post_class.dispose         = kequalizer_class_dispose;
372
 
 
373
 
    _class->xine                       = xine;
374
 
 
375
 
    return _class;
376
 
}
377
 
 
378
 
/* Filter functions */
379
 
 
380
 
// 2nd order Band-pass Filter design
381
 
void KEqualizerPlugin::eq_calc_Bp2(float* a, float* b, float fc, float q)
382
 
383
 
    double th= 2.0 * M_PI * fc;
384
 
    double C = (1.0 - tan(th*q/2.0))/(1.0 + tan(th*q/2.0));
385
 
 
386
 
    a[0] = (1.0 + C) * cos(th);
387
 
    a[1] = -1 * C;
388
 
  
389
 
    b[0] = (1.0 - C)/2.0;
390
 
    b[1] = -1.0050;
391
 
}
392
 
 
393
 
void KEqualizerPlugin::eq_calc_Gains(xine_post_t *this_gen)
394
 
{
395
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(this_gen);
396
 
    // Sanity check
397
 
    if(that->channels<1 || that->channels>KEQUALIZER_CHANNELS_MAX)
398
 
       return;
399
 
    // adjust gains including preamp value
400
 
    float b[10];
401
 
    float adj = 0.0;
402
 
    
403
 
    // Get bands from config
404
 
    for(int i = 0; i < 10; i++){
405
 
        b[i] = that->eqBands[i] + that->preAmp;
406
 
    }   
407
 
    
408
 
    for(int i = 0; i < 10; i++)
409
 
        if(fabsf(b[i]) > fabsf(adj)) adj = b[i];
410
 
 
411
 
    if(fabsf(adj) > KEQUALIZER_G_MAX) {
412
 
        adj = adj > 0.0 ? KEQUALIZER_G_MAX - adj : -KEQUALIZER_G_MAX - adj;
413
 
        for(int i = 0; i < 10; i++) b[i] += adj;
414
 
    }
415
 
     // Recalculate set gains to internal coeficient gains
416
 
    for(int i=0;i<that->channels;i++){
417
 
        
418
 
        for(int k = 0 ; k<KEQUALIZER_KM ; k++){
419
 
            if(b[k] > KEQUALIZER_G_MAX){
420
 
                b[k]=KEQUALIZER_G_MAX;
421
 
            }else if(b[k] < KEQUALIZER_G_MIN){
422
 
                b[k]=KEQUALIZER_G_MIN;
423
 
            }
424
 
            that->g[i][k] = pow(10.0,b[k]/20.0)-1.0;
425
 
       }
426
 
    }
427
 
}
428
 
 
429
 
void KEqualizerPlugin::eq_setup_Filters(xine_post_t *this_gen)
430
 
{
431
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(this_gen);
432
 
    int k =0;
433
 
    float F[KEQUALIZER_KM] = KEQUALIZER_CF;
434
 
 
435
 
    // Calculate number of active filters
436
 
    that->K=KEQUALIZER_KM;
437
 
    while(F[that->K-1] > (float)that->rate/(KEQUALIZER_Q*2.0))
438
 
      that->K--;
439
 
    
440
 
    if(that->K != KEQUALIZER_KM){
441
 
        Phonon::Xine::debug() << Q_FUNC_INFO 
442
 
        << "[kequalizer] Limiting the number of filters to" 
443
 
        << "due to low sample rate =>"
444
 
        << that->K;
445
 
    }
446
 
    // Generate filter taps
447
 
    for(k=0;k<that->K;k++)
448
 
      that->eq_calc_Bp2(that->a[k],that->b[k],F[k]/((float)that->rate),KEQUALIZER_Q);
449
 
}
450
 
 
451
 
void KEqualizerPlugin::equalize_Buffer(xine_post_t *this_gen, audio_buffer_t *buf)
452
 
{
453
 
    kequalizer_plugin_t *that = reinterpret_cast<kequalizer_plugin_t *>(this_gen);
454
 
    const int bufferLength = buf->num_frames * that->channels;
455
 
    
456
 
    if (buf->format.bits == 16 || buf->format.bits == 0) {
457
 
        int16_t         ci   = that->channels;            // Index for channels
458
 
        int16_t         nch  = that->channels;             // Number of channels
459
 
 
460
 
        while(ci--){
461
 
        float*        g   = that->g[ci];      // Gain factor 
462
 
        int16_t*      in  = ((int16_t*)static_cast<int16_t *>(buf->mem))+ci;
463
 
        int16_t*      out = ((int16_t*)static_cast<int16_t *>(buf->mem))+ci;
464
 
        int16_t*      end = in + bufferLength;//sizeof(int16_t); // Block loop end
465
 
        
466
 
            while(in < end){
467
 
                  register int      k  = 0;         // Frequency band index
468
 
                  register float    yt = *in;       // Current input sample
469
 
                  in+=nch;
470
 
         
471
 
                  // Run the filters
472
 
                  for(;k<that->K;k++){
473
 
                        // Pointer to circular buffer wq
474
 
                        register float* wq = that->wq[ci][k];
475
 
                        // Calculate output from AR part of current filter
476
 
                        register float w=yt*that->b[k][0] + wq[0]*that->a[k][0] + wq[1]*that->a[k][1];
477
 
                        // Calculate output form MA part of current filter
478
 
                        yt+=(w + wq[1]*that->b[k][1])*g[k];
479
 
                        // Update circular buffer
480
 
                        wq[1] = wq[0];
481
 
                        wq[0] = w;
482
 
                  }
483
 
                  // Output data to buffer 
484
 
                  // NOTE maybe we need to add more sophisticated convertion method from float to ine like in libSAD with dithering ??
485
 
                  // NOTE for now this clipping have to be enough
486
 
                  *out =  yt <= (float)32767 ? ( yt >= (float)-32768 ? (int16_t)yt : -32768 ) : 32767;
487
 
                  out+=nch;//nch;
488
 
                  } 
489
 
        }
490
 
    }else{
491
 
        Phonon::Xine::debug() << Q_FUNC_INFO << "broken bits " << buf->format.bits;    
492
 
    }
493
 
}
494
 
 
495
 
 
496
 
} // extern "C"