Mercurial > audlegacy
comparison src/audacious/volumecontrol.c @ 3545:7a2b667bab4b trunk
Add volumecontrol flow implementation.
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Tue, 18 Sep 2007 10:41:40 -0500 |
parents | |
children | a140fadd741d |
comparison
equal
deleted
inserted
replaced
3544:e235357029ba | 3545:7a2b667bab4b |
---|---|
1 /* | |
2 * Audacious | |
3 * Copyright (c) 2007 William Pitcock | |
4 * | |
5 * volumecontrol.c: High quality volume PCM padding flow. | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; under version 3 of the License. | |
10 * | |
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 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program. If not, see <http://www.gnu.org/licenses>. | |
18 * | |
19 * The Audacious team does not consider modular code linking to | |
20 * Audacious or using our public API to be a derived work. | |
21 */ | |
22 | |
23 #include "output.h" | |
24 #include "iir.h" | |
25 #include "main.h" | |
26 #include "input.h" | |
27 #include "playback.h" | |
28 | |
29 #include "playlist.h" | |
30 #include "configdb.h" | |
31 | |
32 #include "effect.h" | |
33 #include "xconvert.h" | |
34 | |
35 #include "volumecontrol.h" | |
36 | |
37 #include <math.h> | |
38 | |
39 typedef struct { | |
40 gint left; | |
41 gint right; | |
42 } volumecontrol_req_t; | |
43 | |
44 static volumecontrol_req_t vc_state_ = { 100, 100 }; | |
45 | |
46 #define STEREO_ADJUST(type, type2, endian) \ | |
47 do { \ | |
48 type *ptr = data; \ | |
49 for (i = 0; i < length; i += 4) \ | |
50 { \ | |
51 *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) * \ | |
52 lvol / 256); \ | |
53 ptr++; \ | |
54 *ptr = type2##_TO_##endian(type2##_FROM_##endian(*ptr) * \ | |
55 rvol / 256); \ | |
56 ptr++; \ | |
57 } \ | |
58 } while (0) | |
59 | |
60 #define MONO_ADJUST(type, type2, endian) \ | |
61 do { \ | |
62 type *ptr = data; \ | |
63 for (i = 0; i < length; i += 2) \ | |
64 { \ | |
65 *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) * \ | |
66 vol / 256); \ | |
67 ptr++; \ | |
68 } \ | |
69 } while (0) | |
70 | |
71 #define VOLUME_ADJUST(type, type2, endian) \ | |
72 do { \ | |
73 if (channels == 2) \ | |
74 STEREO_ADJUST(type, type2, endian); \ | |
75 else \ | |
76 MONO_ADJUST(type, type2, endian); \ | |
77 } while (0) | |
78 | |
79 #define STEREO_ADJUST8(type) \ | |
80 do { \ | |
81 type *ptr = data; \ | |
82 for (i = 0; i < length; i += 2) \ | |
83 { \ | |
84 *ptr = *ptr * lvol / 256; \ | |
85 ptr++; \ | |
86 *ptr = *ptr * rvol / 256; \ | |
87 ptr++; \ | |
88 } \ | |
89 } while (0) | |
90 | |
91 #define MONO_ADJUST8(type) \ | |
92 do { \ | |
93 type *ptr = data; \ | |
94 for (i = 0; i < length; i++) \ | |
95 { \ | |
96 *ptr = *ptr * vol / 256; \ | |
97 ptr++; \ | |
98 } \ | |
99 } while (0) | |
100 | |
101 #define VOLUME_ADJUST8(type) \ | |
102 do { \ | |
103 if (channels == 2) \ | |
104 STEREO_ADJUST8(type); \ | |
105 else \ | |
106 MONO_ADJUST8(type); \ | |
107 } while (0) | |
108 | |
109 void volumecontrol_pad_audio(gpointer data, gint length, AFormat fmt, | |
110 gint channels) | |
111 { | |
112 gint i, vol, lvol, rvol; | |
113 | |
114 if (vc_state_.left == 100 && vc_state_.right == 100) | |
115 return; | |
116 | |
117 if (channels == 1 && (vc_state_.left == 100 || vc_state_.right == 100)) | |
118 return; | |
119 | |
120 lvol = pow(10, (vc_state_.left - 100) / 40.0) * 256; | |
121 rvol = pow(10, (vc_state_.right - 100) / 40.0) * 256; | |
122 vol = MAX(lvol, rvol); | |
123 | |
124 switch (fmt) | |
125 { | |
126 case FMT_S16_LE: | |
127 VOLUME_ADJUST(gint16, GINT16, LE); | |
128 break; | |
129 case FMT_U16_LE: | |
130 VOLUME_ADJUST(guint16, GUINT16, LE); | |
131 break; | |
132 case FMT_S16_BE: | |
133 VOLUME_ADJUST(gint16, GINT16, LE); | |
134 break; | |
135 case FMT_U16_BE: | |
136 VOLUME_ADJUST(guint16, GUINT16, LE); | |
137 break; | |
138 case FMT_S8: | |
139 VOLUME_ADJUST8(gint8); | |
140 break; | |
141 case FMT_U8: | |
142 VOLUME_ADJUST8(guint8); | |
143 break; | |
144 default: | |
145 g_warning("unhandled format %d.", fmt); | |
146 break; | |
147 } | |
148 } | |
149 | |
150 void | |
151 volumecontrol_get_volume_state(gint *l, gint *r) | |
152 { | |
153 *l = vc_state_.left; | |
154 *r = vc_state_.right; | |
155 } | |
156 | |
157 void | |
158 volumecontrol_set_volume_state(gint l, gint r) | |
159 { | |
160 vc_state_.left = l; | |
161 vc_state_.right = r; | |
162 } |