1 #ifndef REPLAYGAIN_H
2 #define REPLAYGAIN_H
3 
4 /*
5  *  ReplayGainAnalysis - analyzes input samples and give the recommended dB change
6  *  Copyright (C) 2001 David Robinson and Glen Sawyer
7  *  Modified 2010 by Brian Langenberger for use in Python Audio Tools
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2.1 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  *  concept and filter values by David Robinson (David@Robinson.org)
24  *    -- blame him if you think the idea is flawed
25  *  coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA
26  *    -- blame him if you think this runs too slowly, or the coding is otherwise flawed
27  *
28  *  For an explanation of the concepts and the basic algorithms involved, go to:
29  *    http://www.replaygain.org/
30  */
31 
32 #define GAIN_NOT_ENOUGH_SAMPLES  -24601
33 
34 #define YULE_ORDER         10
35 #define BUTTER_ORDER        2
36 #define YULE_FILTER     filterYule
37 #define BUTTER_FILTER   filterButter
38 #define RMS_PERCENTILE      0.95        /* percentile which is louder than the proposed level */
39 #define MAX_SAMP_FREQ   192000.          /* maximum allowed sample frequency [Hz] */
40 #define RMS_WINDOW_TIME     0.050       /* Time slice size [s] */
41 #define STEPS_per_dB      100.          /* Table entries per dB */
42 #define MAX_dB            120.          /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */
43 #define STEPS_per_dB_times_MAX_dB 12000
44 
45 #define MAX_ORDER 10 /* MAX(BUTTER_ORDER , YULE_ORDER) */
46 #define MAX_SAMPLES_PER_WINDOW 9600  /* MAX_SAMP_FREQ * RMS_WINDOW_TIME */
47 #define PINK_REF                64.82 /* calibration value */
48 
49 typedef enum {GAIN_ANALYSIS_ERROR, GAIN_ANALYSIS_OK} gain_calc_status;
50 
51 typedef struct {
52     PyObject_HEAD;
53 
54     double          linprebuf [MAX_ORDER * 2];
55     double*         linpre;  /* left input samples, with pre-buffer */
56     double          lstepbuf  [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
57     double*         lstep;   /* left "first step" (i.e. post first filter) samples */
58     double          loutbuf   [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
59     double*         lout;    /* left "out" (i.e. post second filter) samples */
60     double          rinprebuf [MAX_ORDER * 2];
61     double*         rinpre;  /* right input samples ... */
62     double          rstepbuf  [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
63     double*         rstep;
64     double          routbuf   [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
65     double*         rout;
66     long            sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */
67     long            totsamp;
68     double          lsum;
69     double          rsum;
70     int             freqindex;
71     int             first;
72     uint32_t  A [STEPS_per_dB_times_MAX_dB];
73     uint32_t  B [STEPS_per_dB_times_MAX_dB];
74 
75     PyObject *framelist_type;
76     unsigned sample_rate;
77     double title_peak;
78     double album_peak;
79 } replaygain_ReplayGain;
80 
81 void
82 ReplayGain_dealloc(replaygain_ReplayGain* self);
83 
84 PyObject*
85 ReplayGain_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
86 
87 int
88 ReplayGain_init(replaygain_ReplayGain *self, PyObject *args, PyObject *kwds);
89 
90 PyObject*
91 ReplayGain_sample_rate(replaygain_ReplayGain *self, void *closure);
92 
93 PyObject*
94 ReplayGain_next_title(replaygain_ReplayGain *self);
95 
96 PyObject*
97 ReplayGain_update(replaygain_ReplayGain *self, PyObject *args);
98 
99 PyObject*
100 ReplayGain_title_gain(replaygain_ReplayGain *self);
101 
102 PyObject*
103 ReplayGain_title_peak(replaygain_ReplayGain *self);
104 
105 PyObject*
106 ReplayGain_album_gain(replaygain_ReplayGain *self);
107 
108 PyObject*
109 ReplayGain_album_peak(replaygain_ReplayGain *self);
110 
111 gain_calc_status
112 ReplayGain_analyze_samples(replaygain_ReplayGain* self,
113                            const double* left_samples,
114                            const double* right_samples,
115                            size_t num_samples,
116                            int num_channels);
117 
118 double
119 ReplayGain_get_title_gain(replaygain_ReplayGain *self);
120 
121 double
122 ReplayGain_get_album_gain(replaygain_ReplayGain *self);
123 
124 
125 typedef struct {
126     PyObject_HEAD;
127 
128     pcmreader* pcmreader;
129     aa_int* channels;
130     BitstreamReader* white_noise;
131     PyObject* audiotools_pcm;
132     double multiplier;
133 } replaygain_ReplayGainReader;
134 
135 void
136 ReplayGainReader_dealloc(replaygain_ReplayGainReader* self);
137 
138 PyObject*
139 ReplayGainReader_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
140 
141 int
142 ReplayGainReader_init(replaygain_ReplayGainReader *self,
143                       PyObject *args, PyObject *kwds);
144 
145 static PyObject*
146 ReplayGainReader_sample_rate(replaygain_ReplayGainReader *self,
147                              void *closure);
148 
149 static PyObject*
150 ReplayGainReader_bits_per_sample(replaygain_ReplayGainReader *self,
151                                  void *closure);
152 
153 static PyObject*
154 ReplayGainReader_channels(replaygain_ReplayGainReader *self,
155                           void *closure);
156 
157 static PyObject*
158 ReplayGainReader_channel_mask(replaygain_ReplayGainReader *self,
159                               void *closure);
160 
161 static PyObject*
162 ReplayGainReader_read(replaygain_ReplayGainReader* self, PyObject *args);
163 
164 static PyObject*
165 ReplayGainReader_close(replaygain_ReplayGainReader* self, PyObject *args);
166 
167 #endif
168