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