~ubuntu-branches/ubuntu/trusty/mpd/trusty

« back to all changes in this revision

Viewing changes to src/replay_gain.c

  • Committer: Bazaar Package Importer
  • Author(s): Angel Abad
  • Date: 2011-02-02 12:26:30 UTC
  • mfrom: (1.5.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20110202122630-bdyx8w4k94doz4fs
Tags: 0.16.1-1ubuntu1
* Merge from debian unstable. Remaining changes:
  - debian/control:
    + Don't build-depend on libmikmod2-dev (Debian bug #510675).
    + Move avahi-daemon from Suggests field to Recommends field.
  - debian/mpd.init.d:
    + Read mpd user from mpd.conf.
  - debian/control, debian/rules:
    + Add libmp3lame-dev to the build dependencies and enable lame.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2003-2009 The Music Player Daemon Project
3
 
 * http://www.musicpd.org
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program 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
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License along
16
 
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 
 */
19
 
/*
20
 
 * (c)2004 replayGain code by AliasMrJones
21
 
 */
22
 
 
23
 
#include "replay_gain.h"
24
 
#include "conf.h"
25
 
#include "audio_format.h"
26
 
#include "pcm_volume.h"
27
 
 
28
 
#include <glib.h>
29
 
#include <stdlib.h>
30
 
#include <string.h>
31
 
#include <math.h>
32
 
 
33
 
static const char *const replay_gain_mode_names[] = {
34
 
        [REPLAY_GAIN_ALBUM] = "album",
35
 
        [REPLAY_GAIN_TRACK] = "track",
36
 
};
37
 
 
38
 
enum replay_gain_mode replay_gain_mode = REPLAY_GAIN_OFF;
39
 
 
40
 
static float replay_gain_preamp = 1.0;
41
 
 
42
 
void replay_gain_global_init(void)
43
 
{
44
 
        const struct config_param *param = config_get_param(CONF_REPLAYGAIN);
45
 
 
46
 
        if (!param)
47
 
                return;
48
 
 
49
 
        if (strcmp(param->value, "track") == 0) {
50
 
                replay_gain_mode = REPLAY_GAIN_TRACK;
51
 
        } else if (strcmp(param->value, "album") == 0) {
52
 
                replay_gain_mode = REPLAY_GAIN_ALBUM;
53
 
        } else {
54
 
                g_error("replaygain value \"%s\" at line %i is invalid\n",
55
 
                        param->value, param->line);
56
 
        }
57
 
 
58
 
        param = config_get_param(CONF_REPLAYGAIN_PREAMP);
59
 
 
60
 
        if (param) {
61
 
                char *test;
62
 
                float f = strtod(param->value, &test);
63
 
 
64
 
                if (*test != '\0') {
65
 
                        g_error("Replaygain preamp \"%s\" is not a number at "
66
 
                                "line %i\n", param->value, param->line);
67
 
                }
68
 
 
69
 
                if (f < -15 || f > 15) {
70
 
                        g_error("Replaygain preamp \"%s\" is not between -15 and"
71
 
                                "15 at line %i\n", param->value, param->line);
72
 
                }
73
 
 
74
 
                replay_gain_preamp = pow(10, f / 20.0);
75
 
        }
76
 
}
77
 
 
78
 
static float calc_replay_gain_scale(float gain, float peak)
79
 
{
80
 
        float scale;
81
 
 
82
 
        if (gain == 0.0)
83
 
                return (1);
84
 
        scale = pow(10.0, gain / 20.0);
85
 
        scale *= replay_gain_preamp;
86
 
        if (scale > 15.0)
87
 
                scale = 15.0;
88
 
 
89
 
        if (scale * peak > 1.0) {
90
 
                scale = 1.0 / peak;
91
 
        }
92
 
        return (scale);
93
 
}
94
 
 
95
 
struct replay_gain_info *replay_gain_info_new(void)
96
 
{
97
 
        struct replay_gain_info *ret = g_new(struct replay_gain_info, 1);
98
 
 
99
 
        for (unsigned i = 0; i < G_N_ELEMENTS(ret->tuples); ++i) {
100
 
                ret->tuples[i].gain = 0.0;
101
 
                ret->tuples[i].peak = 0.0;
102
 
        }
103
 
 
104
 
        /* set to -1 so that we know in replay_gain_apply to compute the scale */
105
 
        ret->scale = -1.0;
106
 
 
107
 
        return ret;
108
 
}
109
 
 
110
 
void replay_gain_info_free(struct replay_gain_info *info)
111
 
{
112
 
        g_free(info);
113
 
}
114
 
 
115
 
void
116
 
replay_gain_apply(struct replay_gain_info *info, char *buffer, int size,
117
 
                  const struct audio_format *format)
118
 
{
119
 
        if (replay_gain_mode == REPLAY_GAIN_OFF || !info)
120
 
                return;
121
 
 
122
 
        if (info->scale < 0) {
123
 
                const struct replay_gain_tuple *tuple =
124
 
                        &info->tuples[replay_gain_mode];
125
 
 
126
 
                g_debug("computing ReplayGain %s scale with gain %f, peak %f\n",
127
 
                        replay_gain_mode_names[replay_gain_mode],
128
 
                        tuple->gain, tuple->peak);
129
 
 
130
 
                info->scale = calc_replay_gain_scale(tuple->gain, tuple->peak);
131
 
        }
132
 
 
133
 
        pcm_volume(buffer, size, format, pcm_float_to_volume(info->scale));
134
 
}