1 /* the Music Player Daemon (MPD)
2 * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
3 * (c)2004 replayGain code by AliasMrJones
4 * This project's homepage is: http://www.musicpd.org
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "replayGain.h"
30 /* Added 4/14/2004 by AliasMrJones */
31 int replayGainState = REPLAYGAIN_OFF;
33 static float replayGainPreamp = 1.0;
35 void initReplayGainState(void)
37 ConfigParam *param = getConfigParam(CONF_REPLAYGAIN);
42 if (strcmp(param->value, "track") == 0) {
43 replayGainState = REPLAYGAIN_TRACK;
44 } else if (strcmp(param->value, "album") == 0) {
45 replayGainState = REPLAYGAIN_ALBUM;
47 FATAL("replaygain value \"%s\" at line %i is invalid\n",
48 param->value, param->line);
51 param = getConfigParam(CONF_REPLAYGAIN_PREAMP);
55 float f = strtod(param->value, &test);
58 FATAL("Replaygain preamp \"%s\" is not a number at "
59 "line %i\n", param->value, param->line);
62 if (f < -15 || f > 15) {
63 FATAL("Replaygain preamp \"%s\" is not between -15 and"
64 "15 at line %i\n", param->value, param->line);
67 replayGainPreamp = pow(10, f / 20.0);
71 static float computeReplayGainScale(float gain, float peak)
77 scale = pow(10.0, gain / 20.0);
78 scale *= replayGainPreamp;
82 if (scale * peak > 1.0) {
88 ReplayGainInfo *newReplayGainInfo(void)
90 ReplayGainInfo *ret = xmalloc(sizeof(ReplayGainInfo));
98 /* set to -1 so that we know in doReplayGain to compute the scale */
104 void freeReplayGainInfo(ReplayGainInfo * info)
109 void doReplayGain(ReplayGainInfo * info, char *buffer, int bufferSize,
110 AudioFormat * format)
112 mpd_sint16 *buffer16;
117 if (replayGainState == REPLAYGAIN_OFF || !info)
120 if (info->scale < 0) {
121 switch (replayGainState) {
122 case REPLAYGAIN_TRACK:
123 DEBUG("computing ReplayGain track scale with gain %f, "
124 "peak %f\n", info->trackGain, info->trackPeak);
125 info->scale = computeReplayGainScale(info->trackGain,
129 DEBUG("computing ReplayGain album scale with gain %f, "
130 "peak %f\n", info->albumGain, info->albumPeak);
131 info->scale = computeReplayGainScale(info->albumGain,
137 if (info->scale <= 1.01 && info->scale >= 0.99)
140 buffer16 = (mpd_sint16 *) buffer;
141 buffer8 = (mpd_sint8 *) buffer;
145 switch (format->bits) {
147 while (bufferSize > 0) {
150 *buffer16 = temp32 > 32767 ? 32767 :
151 (temp32 < -32768 ? -32768 : temp32);
157 while (bufferSize > 0) {
160 *buffer8 = temp32 > 127 ? 127 :
161 (temp32 < -128 ? -128 : temp32);
167 ERROR("%i bits not supported by doReplaygain!\n", format->bits);