1 /*
2  *  ReplayGainAnalysis - analyzes input samples and give the recommended dB change
3  *  Copyright (C) 2001 David Robinson and Glen Sawyer
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  concept and filter values by David Robinson (David@Robinson.org)
20  *    -- blame him if you think the idea is flawed
21  *  coding by Glen Sawyer (glensawyer@hotmail.com) 442 N 700 E, Provo, UT 84606 USA
22  *    -- blame him if you think this runs too slowly, or the coding is otherwise flawed
23  *  minor cosmetic tweaks to integrate with FLAC by Josh Coalson
24  *
25  *  For an explanation of the concepts and the basic algorithms involved, go to:
26  *    http://www.replaygain.org/
27 
28  */
29 
30 
31 #ifndef REPLAYGAIN_H_
32 #define REPLAYGAIN_H_
33 
34 #include <stddef.h>
35 
36 #define GAIN_NOT_ENOUGH_SAMPLES  -24601
37 
38 #define YULE_ORDER         10
39 #define BUTTER_ORDER        2
40 #define RMS_PERCENTILE      0.95        /* percentile which is louder than the proposed level */
41 #define MAX_SAMP_FREQ   48000.          /* maximum allowed sample frequency [Hz] */
42 #define RMS_WINDOW_TIME     0.050       /* Time slice size [s] */
43 #define STEPS_per_dB      100.          /* Table entries per dB */
44 #define MAX_dB            120.          /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */
45 
46 #define MAX_ORDER               (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER)
47 
48 /* [JEC] the following was originally #defined as:
49  *   (size_t) (MAX_SAMP_FREQ * RMS_WINDOW_TIME)
50  * but that seemed to fail to take into account the ceil() part of the
51  * sampleWindow calculation in ResetSampleFrequency(), and was causing
52  * buffer overflows for 48kHz analysis, hence the +1.
53  */
54 #ifndef __sun
55  #define MAX_SAMPLES_PER_WINDOW  (size_t) (MAX_SAMP_FREQ * RMS_WINDOW_TIME + 1.)   /* max. Samples per Time slice */
56 #else
57  /* [JEC] Solaris Forte compiler doesn't like float calc in array indices */
58  #define MAX_SAMPLES_PER_WINDOW  (size_t) (2401)
59 #endif
60 #define PINK_REF                64.82 /* 298640883795 */                          /* calibration value */
61 
62 typedef unsigned short  Uint16_t;
63 typedef signed short    Int16_t;
64 typedef unsigned int    Uint32_t;
65 typedef signed int      Int32_t;
66 
67 class ReplayGain {
68   public:
69     ReplayGain ();
70     virtual ~ReplayGain();
71 
72     bool initialise(long samplefreq, size_t channels);
73     bool process(const float* left_samples, const float* right_samples, size_t blockSize);
74     float end();
75 
76   private:
77     void filterYule (const float* input, float* output, size_t nSamples);
78     void filterButter (const float* input, float* output, size_t nSamples);
79     bool ResetSampleFrequency ( long samplefreq );
80     float analyzeResult ( unsigned int* Array, size_t len );
81 
82     int             num_channels;
83     float           linprebuf [MAX_ORDER * 2];
84     float*          linpre;                                          // left input samples, with pre-buffer
85     float           lstepbuf  [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
86     float*          lstep;                                           // left "first step" (i.e. post first filter) samples
87     float           loutbuf   [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
88     float*          lout;                                            // left "out" (i.e. post second filter) samples
89     float           rinprebuf [MAX_ORDER * 2];
90     float*          rinpre;                                          // right input samples ...
91     float           rstepbuf  [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
92     float*          rstep;
93     float           routbuf   [MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
94     float*          rout;
95     unsigned int            sampleWindow;                                    // number of samples required to reach number of milliseconds required for RMS window
96     unsigned long            totsamp;
97     double          lsum;
98     double          rsum;
99     int             freqindex;
100 #ifndef __sun
101     Uint32_t  A [(size_t)(STEPS_per_dB * MAX_dB)];
102     /*static Uint32_t  B [(size_t)(STEPS_per_dB * MAX_dB)];*/
103 #else
104     /* [JEC] Solaris Forte compiler doesn't like float calc in array indices */
105     Uint32_t  A [12000];
106     /*static Uint32_t  B [12000];*/
107 #endif
108 };
109 
110 #endif /* REPLAYGAIN_H_ */
111