comparison src/madplug/replaygain.c @ 611:3f7a52adfe0e trunk

[svn] merge recent changes from yaz's branch. - stable shoutcast playback. - tag handling improvement. - view track detail on streaming won't crash. (disabled.) - filepopup for streaming is partially supported. filepopup displays track name and stream name, but not updated automatically.
author yaz
date Tue, 06 Feb 2007 12:11:42 -0800
parents 862190d39e00
children 6bc134eec1f3
comparison
equal deleted inserted replaced
610:862190d39e00 611:3f7a52adfe0e
56 return pow(10, res / 20); 56 return pow(10, res / 20);
57 } 57 }
58 58
59 // Reads APE v2.0 tag ending at current pos in fp 59 // Reads APE v2.0 tag ending at current pos in fp
60 60
61 static int ReadAPE2Tag(VFSFile * fp, struct mad_info_t *file) 61 static int ReadAPE2Tag(VFSFile * fp, struct mad_info_t *file_info)
62 { 62 {
63 unsigned long vsize; 63 unsigned long vsize;
64 unsigned long isize; 64 unsigned long isize;
65 unsigned long flags; 65 unsigned long flags;
66 char *buff; 66 char *buff;
108 108
109 if (isize > 0 && vsize > 0) { 109 if (isize > 0 && vsize > 0) {
110 gdouble *scale = NULL; 110 gdouble *scale = NULL;
111 gchar **str = NULL; 111 gchar **str = NULL;
112 if (uncase_strcmp(p, "REPLAYGAIN_ALBUM_GAIN") == 0) { 112 if (uncase_strcmp(p, "REPLAYGAIN_ALBUM_GAIN") == 0) {
113 scale = &file->replaygain_album_scale; 113 scale = &file_info->replaygain_album_scale;
114 str = &file->replaygain_album_str; 114 str = &file_info->replaygain_album_str;
115 } 115 }
116 if (uncase_strcmp(p, "REPLAYGAIN_TRACK_GAIN") == 0) { 116 if (uncase_strcmp(p, "REPLAYGAIN_TRACK_GAIN") == 0) {
117 scale = &file->replaygain_track_scale; 117 scale = &file_info->replaygain_track_scale;
118 str = &file->replaygain_track_str; 118 str = &file_info->replaygain_track_str;
119 } 119 }
120 if (str != NULL) { 120 if (str != NULL) {
121 assert(scale != NULL); 121 assert(scale != NULL);
122 *scale = strgain2double(p + isize + 1, vsize); 122 *scale = strgain2double(p + isize + 1, vsize);
123 *str = g_strndup(p + isize + 1, vsize); 123 *str = g_strndup(p + isize + 1, vsize);
124 } 124 }
125 //* case of peak info tags : */ 125 //* case of peak info tags : */
126 str = NULL; 126 str = NULL;
127 if (uncase_strcmp(p, "REPLAYGAIN_TRACK_PEAK") == 0) { 127 if (uncase_strcmp(p, "REPLAYGAIN_TRACK_PEAK") == 0) {
128 scale = &file->replaygain_track_peak; 128 scale = &file_info->replaygain_track_peak;
129 str = &file->replaygain_track_peak_str; 129 str = &file_info->replaygain_track_peak_str;
130 } 130 }
131 if (uncase_strcmp(p, "REPLAYGAIN_ALBUM_PEAK") == 0) { 131 if (uncase_strcmp(p, "REPLAYGAIN_ALBUM_PEAK") == 0) {
132 scale = &file->replaygain_album_peak; 132 scale = &file_info->replaygain_album_peak;
133 str = &file->replaygain_album_peak_str; 133 str = &file_info->replaygain_album_peak_str;
134 } 134 }
135 if (str != NULL) { 135 if (str != NULL) {
136 *scale = g_strtod(p + isize + 1, NULL); 136 *scale = g_strtod(p + isize + 1, NULL);
137 *str = g_strndup(p + isize + 1, vsize); 137 *str = g_strndup(p + isize + 1, vsize);
138 } 138 }
141 the gain tag translates to scale = 2^(gain/4), 141 the gain tag translates to scale = 2^(gain/4),
142 i.e., in dB : 20*log(2)/log(10)*gain/4 142 i.e., in dB : 20*log(2)/log(10)*gain/4
143 -> 1.501*gain dB 143 -> 1.501*gain dB
144 */ 144 */
145 if (uncase_strcmp(p, "MP3GAIN_UNDO") == 0) { 145 if (uncase_strcmp(p, "MP3GAIN_UNDO") == 0) {
146 str = &file->mp3gain_undo_str; 146 str = &file_info->mp3gain_undo_str;
147 scale = &file->mp3gain_undo; 147 scale = &file_info->mp3gain_undo;
148 assert(4 < vsize); /* this tag is +left,+right */ 148 assert(4 < vsize); /* this tag is +left,+right */
149 *str = g_strndup(p + isize + 1, vsize); 149 *str = g_strndup(p + isize + 1, vsize);
150 *scale = 1.50515 * atoi(*str); 150 *scale = 1.50515 * atoi(*str);
151 } 151 }
152 if (uncase_strcmp(p, "MP3GAIN_MINMAX") == 0) { 152 if (uncase_strcmp(p, "MP3GAIN_MINMAX") == 0) {
153 str = &file->mp3gain_minmax_str; 153 str = &file_info->mp3gain_minmax_str;
154 scale = &file->mp3gain_minmax; 154 scale = &file_info->mp3gain_minmax;
155 *str = g_strndup(p + isize + 1, vsize); 155 *str = g_strndup(p + isize + 1, vsize);
156 assert(4 < vsize); /* this tag is min,max */ 156 assert(4 < vsize); /* this tag is min,max */
157 *scale = 1.50515 * (atoi((*str) + 4) - atoi(*str)); 157 *scale = 1.50515 * (atoi((*str) + 4) - atoi(*str));
158 } 158 }
159 } 159 }
192 if (last_match == -1) 192 if (last_match == -1)
193 return 1; 193 return 1;
194 return last_match + 1 - 8 + sizeof(struct APETagFooterStruct) - N; 194 return last_match + 1 - 8 + sizeof(struct APETagFooterStruct) - N;
195 } 195 }
196 196
197 void input_read_replaygain(struct mad_info_t *file) 197 void input_read_replaygain(struct mad_info_t *file_info)
198 { 198 {
199 file->has_replaygain = FALSE; 199 file_info->has_replaygain = FALSE;
200 file->replaygain_album_scale = -1; 200 file_info->replaygain_album_scale = -1;
201 file->replaygain_track_scale = -1; 201 file_info->replaygain_track_scale = -1;
202 file->mp3gain_undo = -77; 202 file_info->mp3gain_undo = -77;
203 file->mp3gain_minmax = -77; 203 file_info->mp3gain_minmax = -77;
204 204
205 205
206 VFSFile *fp; 206 VFSFile *fp;
207 207
208 if ((fp = vfs_fopen(file->filename, "rb")) == NULL) 208 if ((fp = vfs_fopen(file_info->filename, "rb")) == NULL)
209 return; 209 return;
210 210
211 if (vfs_fseek(fp, 0L, SEEK_END) != 0) { 211 if (vfs_fseek(fp, 0L, SEEK_END) != 0) {
212 vfs_fclose(fp); 212 vfs_fclose(fp);
213 return; 213 return;
217 int try = 0; 217 int try = 0;
218 while (res != 0 && try < 10) { 218 while (res != 0 && try < 10) {
219 // try skipping an id3 tag 219 // try skipping an id3 tag
220 vfs_fseek(fp, pos, SEEK_SET); 220 vfs_fseek(fp, pos, SEEK_SET);
221 vfs_fseek(fp, try * -128, SEEK_CUR); 221 vfs_fseek(fp, try * -128, SEEK_CUR);
222 res = ReadAPE2Tag(fp, file); 222 res = ReadAPE2Tag(fp, file_info);
223 ++try; 223 ++try;
224 } 224 }
225 if (res != 0) { 225 if (res != 0) {
226 // try brute search (don't want to parse all possible kinds of tags..) 226 // try brute search (don't want to parse all possible kinds of tags..)
227 vfs_fseek(fp, pos, SEEK_SET); 227 vfs_fseek(fp, pos, SEEK_SET);
228 int offs = find_offset(fp); 228 int offs = find_offset(fp);
229 if (offs <= 0) { // found ! 229 if (offs <= 0) { // found !
230 vfs_fseek(fp, pos, SEEK_SET); 230 vfs_fseek(fp, pos, SEEK_SET);
231 vfs_fseek(fp, offs, SEEK_CUR); 231 vfs_fseek(fp, offs, SEEK_CUR);
232 res = ReadAPE2Tag(fp, file); 232 res = ReadAPE2Tag(fp, file_info);
233 if (res != 0) { 233 if (res != 0) {
234 g_message 234 g_message
235 ("hmpf, was supposed to find a tag.. offs=%d, res=%d", 235 ("hmpf, was supposed to find a tag.. offs=%d, res=%d",
236 offs, res); 236 offs, res);
237 } 237 }
238 } 238 }
239 } 239 }
240 #ifdef DEBUG 240 #ifdef DEBUG
241 //#if 1
242 if (res == 0) { // got APE tags, show the result 241 if (res == 0) { // got APE tags, show the result
243 printf("RG album scale= %g, RG track scale = %g, in %s \n", 242 printf("RG album scale= %g, RG track scale = %g, in %s \n",
244 file->replaygain_album_scale, 243 file_info->replaygain_album_scale,
245 file->replaygain_track_scale, file->filename); 244 file_info->replaygain_track_scale, file_info->filename);
246 } 245 }
247 #endif 246 #endif
248 247
249 if (file->replaygain_album_scale != -1 248 if (file_info->replaygain_album_scale != -1
250 || file->replaygain_track_scale != -1) 249 || file_info->replaygain_track_scale != -1)
251 file->has_replaygain = TRUE; 250 file_info->has_replaygain = TRUE;
252 251
253 vfs_fclose(fp); 252 vfs_fclose(fp);
254 } 253 }