1 #include <Python.h>
2 #include "mod_defs.h"
3 #include "pcm.h"
4 #include "pcmconv.h"
5 #include "bitstream.h"
6 #include "array.h"
7 #include "dither.c"
8 #include "replaygain.h"
9 
10 /*
11  *  ReplayGainAnalysis - analyzes input samples and give the recommended dB change
12  *  Copyright (C) 2001 David Robinson and Glen Sawyer
13  *  Modified 2010 by Brian Langenberger for use in Python Audio Tools
14  *
15  *  This library is free software; you can redistribute it and/or
16  *  modify it under the terms of the GNU Lesser General Public
17  *  License as published by the Free Software Foundation; either
18  *  version 2.1 of the License, or (at your option) any later version.
19  *
20  *  This library is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  *  Lesser General Public License for more details.
24  *
25  *  You should have received a copy of the GNU Lesser General Public
26  *  License along with this library; if not, write to the Free Software
27  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  *  concept and filter values by David Robinson (David@Robinson.org)
30  *    -- blame him if you think the idea is flawed
31  *  coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA
32  *    -- blame him if you think this runs too slowly, or the coding is otherwise flawed
33  *
34  *  For an explanation of the concepts and the basic algorithms involved, go to:
35  *    http://www.replaygain.org/
36  */
37 
38 #ifndef MIN
39 #define MIN(x, y) ((x) < (y) ? (x) : (y))
40 #endif
41 #ifndef MAX
42 #define MAX(x, y) ((x) > (y) ? (x) : (y))
43 #endif
44 
45 PyMethodDef module_methods[] = {
46     {NULL}
47 };
48 
49 PyGetSetDef ReplayGain_getseters[] = {
50     {"sample_rate",
51      (getter)ReplayGain_sample_rate, NULL, "sample rate", NULL},
52     {NULL}
53 };
54 
55 PyMethodDef ReplayGain_methods[] = {
56     {"update", (PyCFunction)ReplayGain_update,
57      METH_VARARGS, "update(FrameList) -> None"},
58     {"title_gain", (PyCFunction)ReplayGain_title_gain,
59      METH_NOARGS, "title_gain() -> title gain float"},
60     {"title_peak", (PyCFunction)ReplayGain_title_peak,
61      METH_NOARGS, "title_peak() -> title peak float"},
62     {"album_gain", (PyCFunction)ReplayGain_album_gain,
63      METH_NOARGS, "album_gain() -> album gain float"},
64     {"album_peak", (PyCFunction)ReplayGain_album_peak,
65      METH_NOARGS, "album_peak() -> album peak float"},
66     {"next_title", (PyCFunction)ReplayGain_next_title,
67      METH_NOARGS, "call after each title is completed"},
68     {NULL}
69 };
70 
71 PyTypeObject replaygain_ReplayGainType = {
72     PyVarObject_HEAD_INIT(NULL, 0)
73     "replaygain.ReplayGain",   /*tp_name*/
74     sizeof(replaygain_ReplayGain), /*tp_basicsize*/
75     0,                         /*tp_itemsize*/
76     (destructor)ReplayGain_dealloc, /*tp_dealloc*/
77     0,                         /*tp_print*/
78     0,                         /*tp_getattr*/
79     0,                         /*tp_setattr*/
80     0,                         /*tp_compare*/
81     0,                         /*tp_repr*/
82     0,                         /*tp_as_number*/
83     0,                         /*tp_as_sequence*/
84     0,                         /*tp_as_mapping*/
85     0,                         /*tp_hash */
86     0,                         /*tp_call*/
87     0,                         /*tp_str*/
88     0,                         /*tp_getattro*/
89     0,                         /*tp_setattro*/
90     0,                         /*tp_as_buffer*/
91     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
92     "ReplayGain objects",      /* tp_doc */
93     0,                         /* tp_traverse */
94     0,                         /* tp_clear */
95     0,                         /* tp_richcompare */
96     0,                         /* tp_weaklistoffset */
97     0,                         /* tp_iter */
98     0,                         /* tp_iternext */
99     ReplayGain_methods,        /* tp_methods */
100     0,                         /* tp_members */
101     ReplayGain_getseters,      /* tp_getset */
102     0,                         /* tp_base */
103     0,                         /* tp_dict */
104     0,                         /* tp_descr_get */
105     0,                         /* tp_descr_set */
106     0,                         /* tp_dictoffset */
107     (initproc)ReplayGain_init, /* tp_init */
108     0,                         /* tp_alloc */
109     ReplayGain_new,            /* tp_new */
110 };
111 
112 void
ReplayGain_dealloc(replaygain_ReplayGain * self)113 ReplayGain_dealloc(replaygain_ReplayGain* self)
114 {
115     Py_XDECREF(self->framelist_type);
116     Py_TYPE(self)->tp_free((PyObject*)self);
117 }
118 
119 PyObject*
ReplayGain_new(PyTypeObject * type,PyObject * args,PyObject * kwds)120 ReplayGain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
121 {
122     replaygain_ReplayGain *self;
123 
124     self = (replaygain_ReplayGain *)type->tp_alloc(type, 0);
125 
126     return (PyObject *)self;
127 }
128 
129 int
ReplayGain_init(replaygain_ReplayGain * self,PyObject * args,PyObject * kwds)130 ReplayGain_init(replaygain_ReplayGain *self, PyObject *args, PyObject *kwds)
131 {
132     long sample_rate;
133     PyObject *audiotools_pcm;
134     int  i;
135 
136     self->framelist_type = NULL;
137     self->sample_rate = 0;
138     self->title_peak = 0.0;
139     self->album_peak = 0.0;
140 
141     if (!PyArg_ParseTuple(args, "l", &sample_rate))
142         return -1;
143 
144     /*store FrameList type for later comparison*/
145     if ((audiotools_pcm = PyImport_ImportModule("audiotools.pcm")) != NULL) {
146         self->framelist_type = PyObject_GetAttrString(audiotools_pcm,
147                                                       "FrameList");
148         Py_DECREF(audiotools_pcm);
149     } else {
150         return -1;
151     }
152 
153     self->sample_rate = (unsigned)sample_rate;
154 
155     /* zero out initial values*/
156     for (i = 0; i < MAX_ORDER; i++ )
157         self->linprebuf[i] =
158             self->lstepbuf[i] =
159             self->loutbuf[i] =
160             self->rinprebuf[i] =
161             self->rstepbuf[i] =
162             self->routbuf[i] = 0.;
163 
164     switch (sample_rate) {
165     case 48000: self->freqindex = 0; break;
166     case 44100: self->freqindex = 1; break;
167     case 32000: self->freqindex = 2; break;
168     case 24000: self->freqindex = 3; break;
169     case 22050: self->freqindex = 4; break;
170     case 16000: self->freqindex = 5; break;
171     case 12000: self->freqindex = 6; break;
172     case 11025: self->freqindex = 7; break;
173     case  8000: self->freqindex = 8; break;
174     case 18900: self->freqindex = 9; break;
175     case 37800: self->freqindex = 10; break;
176     case 56000: self->freqindex = 11; break;
177     case 64000: self->freqindex = 12; break;
178     case 88200: self->freqindex = 13; break;
179     case 96000: self->freqindex = 14; break;
180     case 112000: self->freqindex = 15; break;
181     case 128000: self->freqindex = 16; break;
182     case 144000: self->freqindex = 17; break;
183     case 176400: self->freqindex = 18; break;
184     case 192000: self->freqindex = 19; break;
185     default:
186         PyErr_SetString(PyExc_ValueError,"unsupported sample rate");
187         return -1;
188     }
189 
190     self->sampleWindow = (int)ceil(sample_rate * RMS_WINDOW_TIME);
191 
192     self->lsum         = 0.;
193     self->rsum         = 0.;
194     self->totsamp      = 0;
195 
196     memset (self->A, 0, sizeof(self->A));
197 
198     self->linpre       = self->linprebuf + MAX_ORDER;
199     self->rinpre       = self->rinprebuf + MAX_ORDER;
200     self->lstep        = self->lstepbuf  + MAX_ORDER;
201     self->rstep        = self->rstepbuf  + MAX_ORDER;
202     self->lout         = self->loutbuf   + MAX_ORDER;
203     self->rout         = self->routbuf   + MAX_ORDER;
204 
205     memset (self->B, 0, sizeof(self->B));
206 
207 
208     return 0;
209 }
210 
211 PyObject*
ReplayGain_sample_rate(replaygain_ReplayGain * self,void * closure)212 ReplayGain_sample_rate(replaygain_ReplayGain *self, void *closure)
213 {
214     return Py_BuildValue("I", self->sample_rate);
215 }
216 
217 PyObject*
ReplayGain_next_title(replaygain_ReplayGain * self)218 ReplayGain_next_title(replaygain_ReplayGain *self)
219 {
220     /*reset initial values for next title*/
221     int    i;
222 
223     for ( i = 0; i < (int)(sizeof(self->A)/sizeof(*(self->A))); i++ ) {
224         self->B[i] += self->A[i];
225         self->A[i]  = 0;
226     }
227 
228     for ( i = 0; i < MAX_ORDER; i++ )
229         self->linprebuf[i] =
230             self->lstepbuf[i] =
231             self->loutbuf[i] =
232             self->rinprebuf[i] =
233             self->rstepbuf[i] =
234             self->routbuf[i] = 0.f;
235 
236     self->totsamp = 0;
237     self->lsum    = self->rsum = 0.;
238 
239     self->title_peak = 0.0;
240 
241     Py_INCREF(Py_None);
242     return Py_None;
243 }
244 
245 PyObject*
ReplayGain_update(replaygain_ReplayGain * self,PyObject * args)246 ReplayGain_update(replaygain_ReplayGain *self, PyObject *args)
247 {
248     pcm_FrameList* framelist;
249     aa_int* channels;
250     aa_double* channels_f;
251     unsigned channel;
252     int32_t peak_shift;
253 
254     if (!PyArg_ParseTuple(args, "O!", self->framelist_type, &framelist))
255         return NULL;
256 
257     /*if FrameList contains no samples, do nothing*/
258     if (framelist->samples_length == 0) {
259         Py_INCREF(Py_None);
260         return Py_None;
261     }
262 
263     channels = aa_int_new();
264 
265     /*split FrameList's packed ints into a set of channels
266       to a maximum of 2 channels*/
267     for (channel = 0; channel < MIN(framelist->channels, 2); channel++) {
268         a_int* channel_a = channels->append(channels);
269         unsigned frame;
270         channel_a->resize(channel_a, framelist->frames);
271         for (frame = 0; frame < framelist->frames; frame++) {
272             a_append(channel_a,
273                      framelist->samples[(frame * framelist->channels) +
274                                         channel]);
275         }
276     }
277 
278     /*if 1 channel, duplicate to other channel*/
279     if (framelist->channels == 1) {
280         channels->_[0]->copy(channels->_[0], channels->append(channels));
281     }
282 
283     /*calculate peak values*/
284     peak_shift = 1 << (framelist->bits_per_sample - 1);
285     for (channel = 0; channel < 2; channel++) {
286         a_int* channel_i = channels->_[channel];
287         int i;
288 
289         for (i = 0; i < channel_i->len; i++) {
290             const double peak = ((double)(abs(channel_i->_[i])) / peak_shift);
291             self->title_peak = MAX(self->title_peak, peak);
292             self->album_peak = MAX(self->album_peak, peak);
293         }
294     }
295 
296     /*convert left and right channels to 16-bit doubles*/
297     channels_f = aa_double_new();
298     for (channel = 0; channel < 2; channel++) {
299         a_int* channel_i = channels->_[channel];
300         a_double* channel_f = channels_f->append(channels_f);
301         int i;
302 
303         channel_f->resize(channel_f, channel_i->len);
304 
305         switch (framelist->bits_per_sample) {
306         case 8:
307             for (i = 0; i < channel_i->len; i++) {
308                 a_append(channel_f, (double)(channel_i->_[i] << 8));
309             }
310             break;
311         case 16:
312             for (i = 0; i < channel_i->len; i++) {
313                 a_append(channel_f, (double)(channel_i->_[i]));
314             }
315             break;
316         case 24:
317             for (i = 0; i < channel_i->len; i++) {
318                 a_append(channel_f, (double)(channel_i->_[i] >> 8));
319             }
320             break;
321         default:
322             PyErr_SetString(PyExc_ValueError,
323                             "unsupported bits per sample");
324             channels->del(channels);
325             channels_f->del(channels_f);
326             return NULL;
327         }
328     }
329 
330     /*perform gain analysis on channels*/
331     if (ReplayGain_analyze_samples(self,
332                                    channels_f->_[0]->_,
333                                    channels_f->_[1]->_,
334                                    channels_f->_[0]->len,
335                                    2) == GAIN_ANALYSIS_ERROR) {
336         PyErr_SetString(PyExc_ValueError, "ReplayGain calculation error");
337         channels->del(channels);
338         channels_f->del(channels_f);
339         return NULL;
340     }
341 
342     /*remove temporary arrays and return None*/
343     channels->del(channels);
344     channels_f->del(channels_f);
345 
346     Py_INCREF(Py_None);
347     return Py_None;
348 }
349 
350 PyObject*
ReplayGain_title_gain(replaygain_ReplayGain * self)351 ReplayGain_title_gain(replaygain_ReplayGain *self)
352 {
353     const double gain_value = ReplayGain_get_title_gain(self);
354     if (gain_value != GAIN_NOT_ENOUGH_SAMPLES) {
355         return Py_BuildValue("d", gain_value);
356     } else {
357         PyErr_SetString(PyExc_ValueError,
358                         "Not enough samples to perform calculation");
359         return NULL;
360     }
361 }
362 
363 PyObject*
ReplayGain_title_peak(replaygain_ReplayGain * self)364 ReplayGain_title_peak(replaygain_ReplayGain *self)
365 {
366     return Py_BuildValue("d", self->title_peak);
367 }
368 
369 PyObject*
ReplayGain_album_gain(replaygain_ReplayGain * self)370 ReplayGain_album_gain(replaygain_ReplayGain *self)
371 {
372     const double gain_value = ReplayGain_get_album_gain(self);
373     if (gain_value != GAIN_NOT_ENOUGH_SAMPLES) {
374         return Py_BuildValue("d", gain_value);
375     } else {
376         PyErr_SetString(PyExc_ValueError,
377                         "Not enough samples to perform calculation");
378         return NULL;
379     }
380 }
381 
382 PyObject*
ReplayGain_album_peak(replaygain_ReplayGain * self)383 ReplayGain_album_peak(replaygain_ReplayGain *self)
384 {
385     return Py_BuildValue("d", self->album_peak);
386 }
387 
388 PyGetSetDef ReplayGainReader_getseters[] = {
389     {"sample_rate",
390      (getter)ReplayGainReader_sample_rate, NULL, "sample rate", NULL},
391     {"bits_per_sample",
392      (getter)ReplayGainReader_bits_per_sample, NULL, "bits per sample", NULL},
393     {"channels",
394      (getter)ReplayGainReader_channels, NULL, "channels", NULL},
395     {"channel_mask",
396      (getter)ReplayGainReader_channel_mask, NULL, "channel_mask", NULL},
397     {NULL}
398 };
399 
400 PyMethodDef ReplayGainReader_methods[] = {
401     {"read", (PyCFunction)ReplayGainReader_read,
402      METH_VARARGS,
403      "Reads a pcm.FrameList with ReplayGain applied"},
404     {"close", (PyCFunction)ReplayGainReader_close,
405      METH_NOARGS, "Closes the substream"},
406     {NULL}
407 };
408 
409 PyTypeObject replaygain_ReplayGainReaderType = {
410     PyVarObject_HEAD_INIT(NULL, 0)
411     "replaygain.ReplayGainReader", /*tp_name*/
412     sizeof(replaygain_ReplayGainReader), /*tp_basicsize*/
413     0,                         /*tp_itemsize*/
414     (destructor)ReplayGainReader_dealloc, /*tp_dealloc*/
415     0,                         /*tp_print*/
416     0,                         /*tp_getattr*/
417     0,                         /*tp_setattr*/
418     0,                         /*tp_compare*/
419     0,                         /*tp_repr*/
420     0,                         /*tp_as_number*/
421     0,                         /*tp_as_sequence*/
422     0,                         /*tp_as_mapping*/
423     0,                         /*tp_hash */
424     0,                         /*tp_call*/
425     0,                         /*tp_str*/
426     0,                         /*tp_getattro*/
427     0,                         /*tp_setattro*/
428     0,                         /*tp_as_buffer*/
429     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
430     "ReplayGainReader objects",/* tp_doc */
431     0,                         /* tp_traverse */
432     0,                         /* tp_clear */
433     0,                         /* tp_richcompare */
434     0,                         /* tp_weaklistoffset */
435     0,                         /* tp_iter */
436     0,                         /* tp_iternext */
437     ReplayGainReader_methods,  /* tp_methods */
438     0,                         /* tp_members */
439     ReplayGainReader_getseters,/* tp_getset */
440     0,                         /* tp_base */
441     0,                         /* tp_dict */
442     0,                         /* tp_descr_get */
443     0,                         /* tp_descr_set */
444     0,                         /* tp_dictoffset */
445     (initproc)ReplayGainReader_init, /* tp_init */
446     0,                         /* tp_alloc */
447     ReplayGainReader_new,      /* tp_new */
448 };
449 
450 
451 
MOD_INIT(replaygain)452 MOD_INIT(replaygain)
453 {
454     PyObject* m;
455 
456     MOD_DEF(m, "replaygain",
457             "a ReplayGain calculation and synthesis module",
458             module_methods)
459 
460     replaygain_ReplayGainType.tp_new = PyType_GenericNew;
461     if (PyType_Ready(&replaygain_ReplayGainType) < 0)
462         return MOD_ERROR_VAL;
463 
464     replaygain_ReplayGainReaderType.tp_new = PyType_GenericNew;
465     if (PyType_Ready(&replaygain_ReplayGainReaderType) < 0)
466         return MOD_ERROR_VAL;
467 
468     Py_INCREF(&replaygain_ReplayGainType);
469     PyModule_AddObject(m, "ReplayGain",
470                        (PyObject *)&replaygain_ReplayGainType);
471 
472     Py_INCREF(&replaygain_ReplayGainReaderType);
473     PyModule_AddObject(m, "ReplayGainReader",
474                        (PyObject *)&replaygain_ReplayGainReaderType);
475 
476     return MOD_SUCCESS_VAL(m);
477 }
478 
479 
480 
481 
482 /* for each filter: */
483 /* [0] 48 kHz, [1] 44.1 kHz, [2] 32 kHz, [3] 24 kHz, [4] 22050 Hz, [5] 16 kHz, [6] 12 kHz, [7] is 11025 Hz, [8] 8 kHz */
484 
485 static const double ABYule[20][2*YULE_ORDER + 1] = {
486     /*48000Hz*/
487     {0.03857599435200, -3.84664617118067, -0.02160367184185,  7.81501653005538, -0.00123395316851,-11.34170355132042, -0.00009291677959, 13.05504219327545, -0.01655260341619,-12.28759895145294,  0.02161526843274,  9.48293806319790, -0.02074045215285, -5.87257861775999,  0.00594298065125,  2.75465861874613,  0.00306428023191, -0.86984376593551,  0.00012025322027,  0.13919314567432,  0.00288463683916 },
488 
489     /*44100Hz*/
490     {0.05418656406430, -3.47845948550071, -0.02911007808948,  6.36317777566148, -0.00848709379851, -8.54751527471874, -0.00851165645469,  9.47693607801280, -0.00834990904936, -8.81498681370155,  0.02245293253339,  6.85401540936998, -0.02596338512915, -4.39470996079559,  0.01624864962975,  2.19611684890774, -0.00240879051584, -0.75104302451432,  0.00674613682247,  0.13149317958808, -0.00187763777362 },
491 
492     /*32000Hz*/
493     {0.15457299681924, -2.37898834973084, -0.09331049056315,  2.84868151156327, -0.06247880153653, -2.64577170229825,  0.02163541888798,  2.23697657451713, -0.05588393329856, -1.67148153367602,  0.04781476674921,  1.00595954808547,  0.00222312597743, -0.45953458054983,  0.03174092540049,  0.16378164858596, -0.01390589421898, -0.05032077717131,  0.00651420667831,  0.02347897407020, -0.00881362733839 },
494 
495     /*24000Hz*/
496     {0.30296907319327, -1.61273165137247, -0.22613988682123,  1.07977492259970, -0.08587323730772, -0.25656257754070,  0.03282930172664, -0.16276719120440, -0.00915702933434, -0.22638893773906, -0.02364141202522,  0.39120800788284, -0.00584456039913, -0.22138138954925,  0.06276101321749,  0.04500235387352, -0.00000828086748,  0.02005851806501,  0.00205861885564,  0.00302439095741, -0.02950134983287 },
497 
498     /*22050Hz*/
499     {0.33642304856132, -1.49858979367799, -0.25572241425570,  0.87350271418188, -0.11828570177555,  0.12205022308084,  0.11921148675203, -0.80774944671438, -0.07834489609479,  0.47854794562326, -0.00469977914380, -0.12453458140019, -0.00589500224440, -0.04067510197014,  0.05724228140351,  0.08333755284107,  0.00832043980773, -0.04237348025746, -0.01635381384540,  0.02977207319925, -0.01760176568150 },
500 
501     /*16000Hz*/
502     {0.44915256608450, -0.62820619233671, -0.14351757464547,  0.29661783706366, -0.22784394429749, -0.37256372942400, -0.01419140100551,  0.00213767857124,  0.04078262797139, -0.42029820170918, -0.12398163381748,  0.22199650564824,  0.04097565135648,  0.00613424350682,  0.10478503600251,  0.06747620744683, -0.01863887810927,  0.05784820375801, -0.03193428438915,  0.03222754072173,  0.00541907748707 },
503 
504     /*12000Hz*/
505     {0.56619470757641, -1.04800335126349, -0.75464456939302,  0.29156311971249,  0.16242137742230, -0.26806001042947,  0.16744243493672,  0.00819999645858, -0.18901604199609,  0.45054734505008,  0.30931782841830, -0.33032403314006, -0.27562961986224,  0.06739368333110,  0.00647310677246, -0.04784254229033,  0.08647503780351,  0.01639907836189, -0.03788984554840,  0.01807364323573, -0.00588215443421 },
506 
507     /*11025Hz*/
508     {0.58100494960553, -0.51035327095184, -0.53174909058578, -0.31863563325245, -0.14289799034253, -0.20256413484477,  0.17520704835522,  0.14728154134330,  0.02377945217615,  0.38952639978999,  0.15558449135573, -0.23313271880868, -0.25344790059353, -0.05246019024463,  0.01628462406333, -0.02505961724053,  0.06920467763959,  0.02442357316099, -0.03721611395801,  0.01818801111503, -0.00749618797172 },
509 
510     /*8000Hz*/
511     {0.53648789255105, -0.25049871956020, -0.42163034350696, -0.43193942311114, -0.00275953611929, -0.03424681017675,  0.04267842219415, -0.04678328784242, -0.10214864179676,  0.26408300200955,  0.14590772289388,  0.15113130533216, -0.02459864859345, -0.17556493366449, -0.11202315195388, -0.18823009262115, -0.04060034127000,  0.05477720428674,  0.04788665548180,  0.04704409688120, -0.02217936801134 },
512 
513 
514     /*18900Hz*/
515     {0.38524531015142, -1.29708918404534, -0.27682212062067, 0.90399339674203, -0.09980181488805, -0.29613799017877, 0.09951486755646, -0.42326645916207, -0.08934020156622, 0.37934887402200, -0.00322369330199, -0.37919795944938, -0.00110329090689, 0.23410283284785, 0.03784509844682, -0.03892971758879, 0.01683906213303, 0.00403009552351, -0.01147039862572, 0.03640166626278, -0.01941767987192 },
516 
517     /*37800Hz*/
518     {0.08717879977844, -2.62816311472146, -0.01000374016172, 3.53734535817992, -0.06265852122368, -3.81003448678921, -0.01119328800950, 3.91291636730132, -0.00114279372960, -3.53518605896288, 0.02081333954769, 2.71356866157873, -0.01603261863207, -1.86723311846592, 0.01936763028546, 1.12075382367659, 0.00760044736442, -0.48574086886890, -0.00303979112271, 0.11330544663849, -0.00075088605788 },
519 
520     /*56000Hz*/
521     {0.03144914734085, -4.87377313090032, -0.06151729206963, 12.03922160140209, 0.08066788708145, -20.10151118381395, -0.09737939921516, 25.10388534415171, 0.08943210803999, -24.29065560815903, -0.06989984672010, 18.27158469090663, 0.04926972841044, -10.45249552560593, -0.03161257848451, 4.30319491872003, 0.01456837493506, -1.13716992070185, -0.00316015108496, 0.14510733527035, 0.00132807215875 },
522 
523     /*64000Hz*/
524     {0.02613056568174, -5.73625477092119, -0.08128786488109, 16.15249794355035, 0.14937282347325, -29.68654912464508, -0.21695711675126, 39.55706155674083, 0.25010286673402, -39.82524556246253, -0.23162283619278, 30.50605345013009, 0.17424041833052, -17.43051772821245, -0.10299599216680, 7.05154573908017, 0.04258696481981, -1.80783839720514, -0.00977952936493, 0.22127840210813, 0.00105325558889 },
525 
526     /*88200Hz*/
527     {0.02667482047416, -6.31836451657302, -0.11377479336097, 18.31351310801799, 0.23063167910965, -31.88210014815921, -0.30726477945593, 36.53792146976740, 0.33188520686529, -28.23393036467559, -0.33862680249063, 14.24725258227189, 0.31807161531340, -4.04670980012854, -0.23730796929880, 0.18865757280515, 0.12273894790371, 0.25420333563908, -0.03840017967282, -0.06012333531065, 0.00549673387936 },
528 
529     /*96000Hz*/
530     {0.00588138296683, -5.97808823642008, -0.01613559730421, 16.21362507964068, 0.02184798954216, -25.72923730652599, -0.01742490405317, 25.40470663139513, 0.00464635643780, -14.66166287771134, 0.01117772513205, 2.81597484359752, -0.02123865824368, 2.51447125969733, 0.01959354413350, -2.23575306985286, -0.01079720643523, 0.75788151036791, 0.00352183686289, -0.10078025199029, -0.00063124341421 },
531 
532     /*112000Hz*/
533     {0.00528778718259, -6.24932108456288, -0.01893240907245, 17.42344320538476, 0.03185982561867, -27.86819709054896, -0.02926260297838, 26.79087344681326, 0.00715743034072, -13.43711081485123, 0.01985743355827, -0.66023612948173, -0.03222614850941, 6.03658091814935, 0.02565681978192, -4.24926577030310, -0.01210662313473, 1.40829268709186, 0.00325436284541, -0.19480852628112, -0.00044173593001 },
534 
535     /*128000Hz*/
536     {0.00553120584305, -6.14581710839925, -0.02112620545016, 16.04785903675838, 0.03549076243117, -22.19089131407749, -0.03362498312306, 15.24756471580286, 0.01425867248183, -0.52001440400238, 0.01344686928787, -8.00488641699940, -0.03392770787836, 6.60916094768855, 0.03464136459530, -2.37856022810923, -0.02039116051549, 0.33106947986101, 0.00667420794705, 0.00459820832036, -0.00093763762995 },
537 
538     /*144000Hz*/
539     {0.00639682359450, -6.14814623523425, -0.02556437970955, 15.80002457141566, 0.04230854400938, -20.78487587686937, -0.03722462201267, 11.98848552310315, 0.01718514827295, 3.36462015062606, 0.00610592243009, -10.22419868359470, -0.03065965747365, 6.65599702146473, 0.04345745003539, -1.67141861110485, -0.03298592681309, -0.05417956536718, 0.01320937236809, 0.07374767867406, -0.00220304127757 },
540 
541     /*176400Hz*/
542     {0.00268568524529, -5.57512782763045, -0.00852379426080, 12.44291056065794, 0.00852704191347, -12.87462799681221, 0.00146116310295, 3.08554846961576, -0.00950855828762, 6.62493459880692, 0.00625449515499, -7.07662766313248, 0.00116183868722, 2.51175542736441, -0.00362461417136, 0.06731510802735, 0.00203961000134, -0.24567753819213, -0.00050664587933, 0.03961404162376, 0.00004327455427 },
543 
544     /*192000Hz*/
545     {0.01184742123123, -5.24727318348167, -0.04631092400086, 10.60821585192244, 0.06584226961238, -8.74127665810413, -0.02165588522478, -1.33906071371683, -0.05656260778952, 8.07972882096606, 0.08607493592760, -5.46179918950847, -0.03375544339786, 0.54318070652536, -0.04216579932754, 0.87450969224280, 0.06416711490648, -0.34656083539754, -0.03444708260844, 0.03034796843589, 0.00697275872241 },
546 };
547 
548 static const double ABButter[20][2*BUTTER_ORDER + 1] = {
549     /*48000Hz*/
550     {0.98621192462708, -1.97223372919527, -1.97242384925416,  0.97261396931306,  0.98621192462708 },
551 
552     /*44100Hz*/
553     {0.98500175787242, -1.96977855582618, -1.97000351574484,  0.97022847566350,  0.98500175787242 },
554 
555     /*32000Hz*/
556     {0.97938932735214, -1.95835380975398, -1.95877865470428,  0.95920349965459,  0.97938932735214 },
557 
558     /*24000Hz*/
559     {0.97531843204928, -1.95002759149878, -1.95063686409857,  0.95124613669835,  0.97531843204928 },
560 
561     /*22050Hz*/
562     {0.97316523498161, -1.94561023566527, -1.94633046996323,  0.94705070426118,  0.97316523498161 },
563 
564     /*16000Hz*/
565     {0.96454515552826, -1.92783286977036, -1.92909031105652,  0.93034775234268,  0.96454515552826 },
566 
567     /*12000Hz*/
568     {0.96009142950541, -1.91858953033784, -1.92018285901082,  0.92177618768381,  0.96009142950541 },
569 
570     /*11025Hz*/
571     {0.95856916599601, -1.91542108074780, -1.91713833199203,  0.91885558323625,  0.95856916599601 },
572 
573     /*8000Hz*/
574     {0.94597685600279, -1.88903307939452, -1.89195371200558,  0.89487434461664,  0.94597685600279 },
575 
576     /*18900Hz*/
577     {0.96535326815829, -1.92950577983524, -1.93070653631658, 0.93190729279793, 0.96535326815829 },
578 
579     /*37800Hz*/
580     {0.98252400815195, -1.96474258269041, -1.96504801630391, 0.96535344991740, 0.98252400815195 },
581 
582     /*56000Hz*/
583     {0.98816995007392, -1.97619994516973, -1.97633990014784, 0.97647985512594, 0.98816995007392 },
584 
585     /*64000Hz*/
586     {0.98964101933472, -1.97917472731009, -1.97928203866944, 0.97938935002880, 0.98964101933472 },
587 
588     /*88200Hz*/
589     {0.99247255046129, -1.98488843762335, -1.98494510092259, 0.98500176422183, 0.99247255046129 },
590 
591     /*96000Hz*/
592     {0.99308203517541, -1.98611621154089, -1.98616407035082, 0.98621192916075, 0.99308203517541 },
593 
594     /*112000Hz*/
595     {0.99406737810867, -1.98809955990514, -1.98813475621734, 0.98816995252954, 0.99406737810867 },
596 
597     /*128000Hz*/
598     {0.99480702681278, -1.98958708647324, -1.98961405362557, 0.98964102077790, 0.99480702681278 },
599 
600     /*144000Hz*/
601     {0.99538268958706, -1.99074405950505, -1.99076537917413, 0.99078669884321, 0.99538268958706 },
602 
603     /*176400Hz*/
604     {0.99622916581118, -1.99244411238133, -1.99245833162236, 0.99247255086339, 0.99622916581118 },
605 
606     /*192000Hz*/
607     {0.99653501465135, -1.99305802314321, -1.99307002930271, 0.99308203546221, 0.99653501465135 }
608 };
609 
610 
611 /* When calling these filter procedures, make sure that ip[-order] and op[-order] point to real data! */
612 
613 /* If your compiler complains that "'operation on 'output' may be undefined", you can */
614 /* either ignore the warnings or uncomment the three "y" lines (and comment out the indicated line) */
615 
616 static void
filterYule(const double * input,double * output,size_t nSamples,const double * kernel)617 filterYule (const double* input, double* output, size_t nSamples,
618             const double* kernel)
619 {
620     while (nSamples--) {
621         *output =  1e-10  /* 1e-10 is a hack to avoid slowdown because of denormals */
622             + input [0]  * kernel[0]
623             - output[-1] * kernel[1]
624             + input [-1] * kernel[2]
625             - output[-2] * kernel[3]
626             + input [-2] * kernel[4]
627             - output[-3] * kernel[5]
628             + input [-3] * kernel[6]
629             - output[-4] * kernel[7]
630             + input [-4] * kernel[8]
631             - output[-5] * kernel[9]
632             + input [-5] * kernel[10]
633             - output[-6] * kernel[11]
634             + input [-6] * kernel[12]
635             - output[-7] * kernel[13]
636             + input [-7] * kernel[14]
637             - output[-8] * kernel[15]
638             + input [-8] * kernel[16]
639             - output[-9] * kernel[17]
640             + input [-9] * kernel[18]
641             - output[-10]* kernel[19]
642             + input [-10]* kernel[20];
643         ++output;
644         ++input;
645     }
646 }
647 
648 static void
filterButter(const double * input,double * output,size_t nSamples,const double * kernel)649 filterButter (const double* input, double* output, size_t nSamples, const double* kernel)
650 {
651     while (nSamples--) {
652         *output =
653             input [0]  * kernel[0]
654             - output[-1] * kernel[1]
655             + input [-1] * kernel[2]
656             - output[-2] * kernel[3]
657             + input [-2] * kernel[4];
658         ++output;
659         ++input;
660     }
661 }
662 
663 static inline double
fsqr(const double d)664 fsqr(const double d)
665 {
666     return d * d;
667 }
668 
669 /* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */
670 gain_calc_status
ReplayGain_analyze_samples(replaygain_ReplayGain * self,const double * left_samples,const double * right_samples,size_t num_samples,int num_channels)671 ReplayGain_analyze_samples(replaygain_ReplayGain* self,
672                            const double* left_samples,
673                            const double* right_samples,
674                            size_t num_samples,
675                            int num_channels)
676 {
677     const double*  curleft;
678     const double*  curright;
679     long            batchsamples;
680     long            cursamples;
681     long            cursamplepos;
682     long            i;
683 
684     if ( num_samples == 0 )
685         return GAIN_ANALYSIS_OK;
686 
687     cursamplepos = 0;
688     batchsamples = num_samples;
689 
690     switch ( num_channels) {
691     case  1: right_samples = left_samples;
692     case  2: break;
693     default: return GAIN_ANALYSIS_ERROR;
694     }
695 
696     if ( num_samples < MAX_ORDER ) {
697         memcpy (self->linprebuf + MAX_ORDER, left_samples , num_samples * sizeof(double) );
698         memcpy ( self->rinprebuf + MAX_ORDER, right_samples, num_samples * sizeof(double) );
699     }
700     else {
701         memcpy ( self->linprebuf + MAX_ORDER, left_samples,  MAX_ORDER   * sizeof(double) );
702         memcpy ( self->rinprebuf + MAX_ORDER, right_samples, MAX_ORDER   * sizeof(double) );
703     }
704 
705     while ( batchsamples > 0 ) {
706         cursamples = batchsamples > self->sampleWindow - self->totsamp  ?  self->sampleWindow - self->totsamp  :  batchsamples;
707         if ( cursamplepos < MAX_ORDER ) {
708             curleft  = self->linpre + cursamplepos;
709             curright = self->rinpre + cursamplepos;
710             if (cursamples > MAX_ORDER - cursamplepos )
711                 cursamples = MAX_ORDER - cursamplepos;
712         }
713         else {
714             curleft  = left_samples  + cursamplepos;
715             curright = right_samples + cursamplepos;
716         }
717 
718         YULE_FILTER ( curleft , self->lstep + self->totsamp, cursamples, ABYule[self->freqindex]);
719         YULE_FILTER ( curright, self->rstep + self->totsamp, cursamples, ABYule[self->freqindex]);
720 
721         BUTTER_FILTER ( self->lstep + self->totsamp, self->lout + self->totsamp, cursamples, ABButter[self->freqindex]);
722         BUTTER_FILTER ( self->rstep + self->totsamp, self->rout + self->totsamp, cursamples, ABButter[self->freqindex]);
723 
724         curleft = self->lout + self->totsamp; /* Get the squared values */
725         curright = self->rout + self->totsamp;
726 
727         i = cursamples % 16;
728         while (i--)
729             {   self->lsum += fsqr(*curleft++);
730                 self->rsum += fsqr(*curright++);
731             }
732         i = cursamples / 16;
733         while (i--)
734             {   self->lsum += fsqr(curleft[0])
735                     + fsqr(curleft[1])
736                     + fsqr(curleft[2])
737                     + fsqr(curleft[3])
738                     + fsqr(curleft[4])
739                     + fsqr(curleft[5])
740                     + fsqr(curleft[6])
741                     + fsqr(curleft[7])
742                     + fsqr(curleft[8])
743                     + fsqr(curleft[9])
744                     + fsqr(curleft[10])
745                     + fsqr(curleft[11])
746                     + fsqr(curleft[12])
747                     + fsqr(curleft[13])
748                     + fsqr(curleft[14])
749                     + fsqr(curleft[15]);
750                 curleft += 16;
751                 self->rsum += fsqr(curright[0])
752                     + fsqr(curright[1])
753                     + fsqr(curright[2])
754                     + fsqr(curright[3])
755                     + fsqr(curright[4])
756                     + fsqr(curright[5])
757                     + fsqr(curright[6])
758                     + fsqr(curright[7])
759                     + fsqr(curright[8])
760                     + fsqr(curright[9])
761                     + fsqr(curright[10])
762                     + fsqr(curright[11])
763                     + fsqr(curright[12])
764                     + fsqr(curright[13])
765                     + fsqr(curright[14])
766                     + fsqr(curright[15]);
767                 curright += 16;
768             }
769 
770         batchsamples -= cursamples;
771         cursamplepos += cursamples;
772         self->totsamp      += cursamples;
773         if ( self->totsamp == self->sampleWindow ) {  /* Get the Root Mean Square (RMS) for this set of samples */
774             double  val  = STEPS_per_dB * 10. * log10 ( (self->lsum + self->rsum) / self->totsamp * 0.5 + 1.e-37 );
775             int     ival = (int) val;
776             if ( ival <                     0 ) ival = 0;
777             if ( ival >= (int)(sizeof(self->A)/sizeof(*(self->A))) ) ival = sizeof(self->A)/sizeof(*(self->A)) - 1;
778             self->A [ival]++;
779             self->lsum = self->rsum = 0.;
780             memmove ( self->loutbuf , self->loutbuf  + self->totsamp, MAX_ORDER * sizeof(double) );
781             memmove ( self->routbuf , self->routbuf  + self->totsamp, MAX_ORDER * sizeof(double) );
782             memmove ( self->lstepbuf, self->lstepbuf + self->totsamp, MAX_ORDER * sizeof(double) );
783             memmove ( self->rstepbuf, self->rstepbuf + self->totsamp, MAX_ORDER * sizeof(double) );
784             self->totsamp = 0;
785         }
786         if ( self->totsamp > self->sampleWindow )   /* somehow I really screwed up: Error in programming! Contact author about self->totsamp > self->sampleWindow */
787             return GAIN_ANALYSIS_ERROR;
788     }
789     if ( num_samples < MAX_ORDER ) {
790         memmove ( self->linprebuf,                           self->linprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(double) );
791         memmove ( self->rinprebuf,                           self->rinprebuf + num_samples, (MAX_ORDER-num_samples) * sizeof(double) );
792         memcpy  ( self->linprebuf + MAX_ORDER - num_samples, left_samples,          num_samples             * sizeof(double) );
793         memcpy  ( self->rinprebuf + MAX_ORDER - num_samples, right_samples,         num_samples             * sizeof(double) );
794     }
795     else {
796         memcpy  ( self->linprebuf, left_samples  + num_samples - MAX_ORDER, MAX_ORDER * sizeof(double) );
797         memcpy  ( self->rinprebuf, right_samples + num_samples - MAX_ORDER, MAX_ORDER * sizeof(double) );
798     }
799 
800     return GAIN_ANALYSIS_OK;
801 }
802 
803 
804 static double
analyzeResult(uint32_t * Array,size_t len)805 analyzeResult(uint32_t* Array, size_t len)
806 {
807     uint32_t  elems;
808     int32_t   upper;
809     size_t    i;
810 
811     elems = 0;
812     for ( i = 0; i < len; i++ )
813         elems += Array[i];
814     if ( elems == 0 )
815         return GAIN_NOT_ENOUGH_SAMPLES;
816 
817     upper = (int32_t)ceil (elems * (1. - RMS_PERCENTILE));
818     for ( i = len; i-- > 0; ) {
819         if ( (upper -= Array[i]) <= 0 )
820             break;
821     }
822 
823     return (double) ((double)PINK_REF - (double)i / (double)STEPS_per_dB);
824 }
825 
826 
827 double
ReplayGain_get_title_gain(replaygain_ReplayGain * self)828 ReplayGain_get_title_gain(replaygain_ReplayGain *self)
829 {
830     return analyzeResult(self->A, sizeof(self->A)/sizeof(*(self->A)) );
831 }
832 
833 
834 double
ReplayGain_get_album_gain(replaygain_ReplayGain * self)835 ReplayGain_get_album_gain(replaygain_ReplayGain *self)
836 {
837     return analyzeResult(self->B, sizeof(self->B)/sizeof(*(self->B)) );
838 }
839 
840 
841 PyObject*
ReplayGainReader_new(PyTypeObject * type,PyObject * args,PyObject * kwds)842 ReplayGainReader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
843     replaygain_ReplayGainReader *self;
844 
845     self = (replaygain_ReplayGainReader *)type->tp_alloc(type, 0);
846 
847     return (PyObject *)self;
848 }
849 
850 int
ReplayGainReader_init(replaygain_ReplayGainReader * self,PyObject * args,PyObject * kwds)851 ReplayGainReader_init(replaygain_ReplayGainReader *self,
852                       PyObject *args, PyObject *kwds) {
853     self->pcmreader = NULL;
854     self->channels = aa_int_new();
855     self->white_noise = NULL;
856     self->audiotools_pcm = NULL;
857 
858     double replaygain;
859     double peak;
860 
861     if (!PyArg_ParseTuple(args, "O&dd",
862                           pcmreader_converter, &(self->pcmreader),
863                           &(replaygain),
864                           &(peak)))
865         return -1;
866 
867     if ((self->white_noise = open_dither()) == NULL)
868         return -1;
869 
870     if ((self->audiotools_pcm = open_audiotools_pcm()) == NULL)
871         return -1;
872 
873     self->multiplier = powl(10.0l, replaygain / 20.0l);
874     if (self->multiplier > 1.0l)
875         self->multiplier = 1.0l / peak;
876 
877     return 0;
878 }
879 
880 void
ReplayGainReader_dealloc(replaygain_ReplayGainReader * self)881 ReplayGainReader_dealloc(replaygain_ReplayGainReader* self) {
882     if (self->pcmreader != NULL)
883         self->pcmreader->del(self->pcmreader);
884     self->channels = aa_int_new();
885     if (self->white_noise != NULL)
886         self->white_noise->close(self->white_noise);
887     Py_XDECREF(self->audiotools_pcm);
888 
889     Py_TYPE(self)->tp_free((PyObject*)self);
890 }
891 
892 static PyObject*
ReplayGainReader_sample_rate(replaygain_ReplayGainReader * self,void * closure)893 ReplayGainReader_sample_rate(replaygain_ReplayGainReader *self,
894                              void *closure) {
895     return Py_BuildValue("i", self->pcmreader->sample_rate);
896 }
897 
898 static PyObject*
ReplayGainReader_bits_per_sample(replaygain_ReplayGainReader * self,void * closure)899 ReplayGainReader_bits_per_sample(replaygain_ReplayGainReader *self,
900                                  void *closure) {
901     return Py_BuildValue("i", self->pcmreader->bits_per_sample);
902 }
903 
904 static PyObject*
ReplayGainReader_channels(replaygain_ReplayGainReader * self,void * closure)905 ReplayGainReader_channels(replaygain_ReplayGainReader *self,
906                           void *closure) {
907     return Py_BuildValue("i", self->pcmreader->channels);
908 }
909 
910 static PyObject*
ReplayGainReader_channel_mask(replaygain_ReplayGainReader * self,void * closure)911 ReplayGainReader_channel_mask(replaygain_ReplayGainReader *self,
912                               void *closure) {
913     return Py_BuildValue("i", self->pcmreader->channel_mask);
914 }
915 
916 static PyObject*
ReplayGainReader_read(replaygain_ReplayGainReader * self,PyObject * args)917 ReplayGainReader_read(replaygain_ReplayGainReader* self, PyObject *args) {
918     int pcm_frames = 0;
919     aa_int* channels = self->channels;
920     unsigned c;
921 
922     const int max_value = (1 << (self->pcmreader->bits_per_sample - 1)) - 1;
923     const int min_value = -(1 << (self->pcmreader->bits_per_sample - 1));
924     const double multiplier = self->multiplier;
925 
926     if (!PyArg_ParseTuple(args, "i", &pcm_frames))
927         return NULL;
928 
929     if (pcm_frames <= 0) {
930         PyErr_SetString(PyExc_ValueError, "pcm_frames must be positive");
931         return NULL;
932     }
933 
934     /*read FrameList object from internal PCMReader*/
935     if (self->pcmreader->read(self->pcmreader,
936                               (unsigned)pcm_frames,
937                               channels))
938         return NULL;
939 
940     /*apply our multiplier to framelist's integer samples
941       and apply dithering*/
942     for (c = 0; c < channels->len; c++) {
943         a_int* channel = channels->_[c];
944         unsigned i;
945         for (i = 0; i < channel->len; i++) {
946             channel->_[i] = (int)lround(channel->_[i] * multiplier);
947             channel->_[i] = (MIN(MAX(channel->_[i], min_value), max_value) ^
948                              self->white_noise->read(self->white_noise, 1));
949         }
950     }
951 
952     /*return integer samples as a new FrameList object*/
953     return aa_int_to_FrameList(self->audiotools_pcm,
954                                channels,
955                                self->pcmreader->bits_per_sample);
956 }
957 
958 static PyObject*
ReplayGainReader_close(replaygain_ReplayGainReader * self,PyObject * args)959 ReplayGainReader_close(replaygain_ReplayGainReader* self, PyObject *args) {
960     self->pcmreader->close(self->pcmreader);
961     Py_INCREF(Py_None);
962     return Py_None;
963 }
964