Mercurial > audlegacy-plugins
comparison src/madplug/tuple.c @ 2202:f76e846d53d9
updating TLEN frame returned
author | Eugene Zagidullin <e.asphyx@gmail.com> |
---|---|
date | Mon, 03 Dec 2007 01:26:57 +0300 |
parents | src/madplug/tuples.c@df520f828dcf |
children | 13b8ab116b69 |
comparison
equal
deleted
inserted
replaced
2201:df520f828dcf | 2202:f76e846d53d9 |
---|---|
1 /* | |
2 * mad plugin for audacious | |
3 * Copyright (C) 2005-2007 William Pitcock, Yoshiki Yazawa, Eugene Zagidullin | |
4 * | |
5 * Portions derived from xmms-mad: | |
6 * Copyright (C) 2001-2002 Sam Clegg - See COPYING | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; under version 2 of the License. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 */ | |
21 | |
22 #include "config.h" | |
23 | |
24 #include "plugin.h" | |
25 #include "tuple.h" | |
26 #include "input.h" | |
27 | |
28 #include <math.h> | |
29 #include <string.h> | |
30 | |
31 #include <glib.h> | |
32 #include <glib/gprintf.h> | |
33 | |
34 #include <audacious/util.h> | |
35 #include <audacious/plugin.h> | |
36 #include <audacious/id3tag.h> | |
37 | |
38 /* yaz */ | |
39 #include <langinfo.h> | |
40 | |
41 #define DEBUG | |
42 | |
43 static void | |
44 update_id3_frame(struct id3_tag *tag, const char *frame_name, const char *data, int sjis) | |
45 { | |
46 int res; | |
47 struct id3_frame *frame; | |
48 union id3_field *field; | |
49 id3_ucs4_t *ucs4; | |
50 | |
51 if (data == NULL) | |
52 return; | |
53 | |
54 // printf ("updating id3: %s: %s\n", frame_name, data); | |
55 | |
56 // | |
57 // An empty string removes the frame altogether. | |
58 // | |
59 if (strlen(data) == 0) { | |
60 while ((frame = id3_tag_findframe(tag, frame_name, 0))) { | |
61 #ifdef DEBUG | |
62 fprintf(stderr, "madplug: detachframe\n"); | |
63 #endif | |
64 id3_tag_detachframe(tag, frame); | |
65 } | |
66 return; | |
67 } | |
68 | |
69 frame = id3_tag_findframe(tag, frame_name, 0); | |
70 if (!frame) { | |
71 #ifdef DEBUG | |
72 printf("frame_new\n"); | |
73 #endif | |
74 frame = id3_frame_new(frame_name); | |
75 id3_tag_attachframe(tag, frame); | |
76 } | |
77 | |
78 // setup ucs4 string | |
79 if(sjis) { | |
80 ucs4 = id3_latin1_ucs4duplicate((id3_latin1_t *) data); | |
81 } | |
82 else { | |
83 ucs4 = id3_utf8_ucs4duplicate((id3_utf8_t *) data); | |
84 } | |
85 | |
86 // set encoding | |
87 field = id3_frame_field(frame, 0); | |
88 id3_field_settextencoding(field, sjis ? ID3_FIELD_TEXTENCODING_ISO_8859_1 : | |
89 ID3_FIELD_TEXTENCODING_UTF_8); | |
90 | |
91 // setup genre code | |
92 if (!strcmp(frame_name, ID3_FRAME_GENRE)) { | |
93 char *tmp; | |
94 int index = id3_genre_number(ucs4); | |
95 g_free(ucs4); | |
96 | |
97 if(index == -1) { // unknown genre. remove TCON frame. | |
98 #ifdef DEBUG | |
99 fprintf(stderr, "madplug: remove genre frame\n"); | |
100 #endif | |
101 id3_tag_detachframe(tag, frame); | |
102 } | |
103 else { // meaningful genre | |
104 tmp = g_strdup_printf("%d", index); | |
105 ucs4 = id3_latin1_ucs4duplicate((unsigned char *) tmp); | |
106 } | |
107 | |
108 } | |
109 | |
110 // write string | |
111 if (!strcmp(frame_name, ID3_FRAME_COMMENT)) { | |
112 field = id3_frame_field(frame, 3); | |
113 field->type = ID3_FIELD_TYPE_STRINGFULL; | |
114 res = id3_field_setfullstring(field, ucs4); | |
115 } | |
116 else { | |
117 field = id3_frame_field(frame, 1); | |
118 field->type = ID3_FIELD_TYPE_STRINGLIST; | |
119 res = id3_field_setstrings(field, 1, &ucs4); | |
120 } | |
121 | |
122 if (res != 0) | |
123 g_print("error setting id3 field: %s\n", frame_name); | |
124 } | |
125 | |
126 static void | |
127 update_id3_frame_from_tuple(struct id3_tag *id3tag, const char *field, Tuple *tuple, int fieldn, int sjis) | |
128 { | |
129 int val; | |
130 char *text, *text2; | |
131 const char *encoding = sjis ? "SJIS" : "UTF-8"; | |
132 | |
133 if(aud_tuple_get_value_type(tuple, fieldn, NULL) == TUPLE_INT) { | |
134 val = aud_tuple_get_int(tuple, fieldn, NULL); | |
135 if(val > 0) { | |
136 text2 = g_strdup_printf("%d", val); | |
137 #ifdef DEBUG | |
138 fprintf(stderr, "madplug: updating field:\"%s\"=\"%s\", enc %s\n", field, text2, encoding); | |
139 #endif | |
140 update_id3_frame(id3tag, field, text2, 0); | |
141 g_free(text2); | |
142 } else { | |
143 update_id3_frame(id3tag, field, "", 0); /* will be detached */ | |
144 } | |
145 | |
146 } else if(aud_tuple_get_value_type(tuple, fieldn, NULL) == TUPLE_STRING) { | |
147 text = (char*)aud_tuple_get_string(tuple, fieldn, NULL); | |
148 text2 = g_convert(text, strlen(text), encoding, "UTF-8", NULL, NULL, NULL); | |
149 #ifdef DEBUG | |
150 fprintf(stderr, "madplug: updating field:\"%s\"=\"%s\", enc %s\n", field, text2, encoding); | |
151 #endif | |
152 update_id3_frame(id3tag, field, text2, sjis); | |
153 g_free(text2); | |
154 } | |
155 } | |
156 | |
157 gboolean | |
158 audmad_update_song_tuple(Tuple *tuple, VFSFile *fd) | |
159 { | |
160 struct id3_file *id3file; | |
161 struct id3_tag *id3tag; | |
162 gchar *text; | |
163 struct mad_info_t songinfo; | |
164 | |
165 if ((id3file = id3_file_vfsopen(fd, ID3_FILE_MODE_READWRITE)) == NULL) return FALSE; | |
166 | |
167 id3tag = id3_file_tag(id3file); | |
168 if (!id3tag) { | |
169 #ifdef DEBUG | |
170 fprintf(stderr, "no id3tag\n. append new tag.\n"); | |
171 #endif | |
172 id3tag = id3_tag_new(); | |
173 id3_tag_clearframes(id3tag); | |
174 id3tag->options |= ID3_TAG_OPTION_APPENDEDTAG | ID3_TAG_OPTION_ID3V1; | |
175 } | |
176 | |
177 id3_tag_options(id3tag, ID3_TAG_OPTION_ID3V1, ~0); /* enables id3v1. TODO: make id3v1 optional */ | |
178 | |
179 update_id3_frame_from_tuple(id3tag, ID3_FRAME_TITLE, tuple, FIELD_TITLE, audmad_config.sjis); | |
180 update_id3_frame_from_tuple(id3tag, ID3_FRAME_ARTIST, tuple, FIELD_ARTIST, audmad_config.sjis); | |
181 update_id3_frame_from_tuple(id3tag, ID3_FRAME_ALBUM, tuple, FIELD_ALBUM, audmad_config.sjis); | |
182 update_id3_frame_from_tuple(id3tag, ID3_FRAME_YEAR, tuple, FIELD_YEAR, audmad_config.sjis); | |
183 update_id3_frame_from_tuple(id3tag, ID3_FRAME_COMMENT, tuple, FIELD_COMMENT, audmad_config.sjis); | |
184 update_id3_frame_from_tuple(id3tag, ID3_FRAME_TRACK, tuple, FIELD_TRACK_NUMBER, audmad_config.sjis); | |
185 update_id3_frame_from_tuple(id3tag, ID3_FRAME_GENRE, tuple, FIELD_GENRE, audmad_config.sjis); | |
186 | |
187 if(!id3_tag_findframe(id3tag, "TLEN", 0) && input_init(&songinfo, fd->uri, fd) && !songinfo.remote) { | |
188 #ifdef DEBUG | |
189 fprintf(stderr, "update TLEN frame\n"); | |
190 #endif | |
191 songinfo.fileinfo_request = FALSE; /* we don't need to read tuple again */ | |
192 input_get_info(&songinfo, FALSE); | |
193 text = g_strdup_printf("%ld", mad_timer_count(songinfo.duration, MAD_UNITS_MILLISECONDS)); | |
194 #ifdef DEBUG | |
195 fprintf(stderr, "TLEN: \"%s\"\n", text); | |
196 #endif | |
197 update_id3_frame(id3tag, "TLEN", text, 0); | |
198 g_free(text); | |
199 input_term(&songinfo); | |
200 } | |
201 | |
202 if (id3_file_update(id3file) != 0) return FALSE; | |
203 | |
204 id3_file_close(id3file); | |
205 return TRUE; | |
206 } | |
207 | |
208 /*#endif // !NOGUI | |
209 | |
210 void audmad_get_file_info(char *fileurl) | |
211 { | |
212 #ifndef NOGUI | |
213 gchar *title; | |
214 gchar message[128]; | |
215 static char const *const layer_str[3] = { "I", "II", "III" }; | |
216 static char const *const mode_str[4] = { | |
217 ("single channel"), ("dual channel"), "joint stereo", "stereo" | |
218 }; | |
219 gchar *tmp, *utf_filename; | |
220 gchar *realfn = NULL; | |
221 #ifdef DEBUG | |
222 { | |
223 tmp = aud_str_to_utf8(fileurl); | |
224 g_message("f: audmad_get_file_info: %s", tmp); | |
225 g_free(tmp); | |
226 tmp = NULL; | |
227 } | |
228 #endif | |
229 | |
230 if(!aud_vfs_is_remote(fileurl) && !aud_vfs_file_test(fileurl, G_FILE_TEST_EXISTS)) { | |
231 return; | |
232 } | |
233 | |
234 input_init(&info, fileurl, NULL); | |
235 | |
236 if(audmad_is_remote(fileurl)) { | |
237 info.remote = TRUE; | |
238 if(aud_vfs_is_streaming(info.infile)) | |
239 return; //file info dialog for remote streaming doesn't make sense. | |
240 } | |
241 | |
242 realfn = g_filename_from_uri(fileurl, NULL, NULL); | |
243 utf_filename = aud_str_to_utf8(realfn ? realfn : fileurl); | |
244 g_free(realfn); realfn = NULL; | |
245 create_window(); | |
246 | |
247 info.fileinfo_request = TRUE; | |
248 input_get_info(&info, info.remote ? TRUE : FALSE); | |
249 | |
250 tmp = g_path_get_basename(utf_filename); | |
251 title = g_strdup_printf(_("File Info - %s"), tmp); | |
252 g_free(tmp); tmp = NULL; | |
253 gtk_window_set_title(GTK_WINDOW(window), title); | |
254 g_free(title); | |
255 | |
256 gtk_entry_set_text(GTK_ENTRY(filename_entry), utf_filename); | |
257 gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1); | |
258 | |
259 free(utf_filename); | |
260 | |
261 id3_frame_to_entry(ID3_FRAME_ARTIST, GTK_ENTRY(artist_entry)); | |
262 id3_frame_to_entry(ID3_FRAME_TITLE, GTK_ENTRY(title_entry)); | |
263 id3_frame_to_entry(ID3_FRAME_ALBUM, GTK_ENTRY(album_entry)); | |
264 | |
265 // year | |
266 // id3_frame_to_entry (ID3_FRAME_YEAR, GTK_ENTRY (year_entry)); | |
267 // to set year entry, we have to do manually because TYER is still used equally to TDRC. | |
268 gtk_entry_set_text(GTK_ENTRY(year_entry), ""); | |
269 if (info.tag) { | |
270 gchar *text = NULL; | |
271 text = input_id3_get_string(info.tag, "TDRC"); | |
272 if (!text) | |
273 text = input_id3_get_string(info.tag, "TYER"); | |
274 if (text) { | |
275 gtk_entry_set_text(GTK_ENTRY(year_entry), text); | |
276 g_free(text); | |
277 } | |
278 } | |
279 | |
280 id3_frame_to_entry(ID3_FRAME_TRACK, GTK_ENTRY(tracknum_entry)); | |
281 id3_frame_to_entry(ID3_FRAME_COMMENT, GTK_ENTRY(comment_entry)); | |
282 snprintf(message, 127, _("Layer %s"), layer_str[info.mpeg_layer - 1]); | |
283 gtk_label_set_text(GTK_LABEL(mpeg_level), message); | |
284 if (info.vbr) { | |
285 snprintf(message, 127, _("VBR (avg. %d kbps)"), info.bitrate / 1000); | |
286 } | |
287 else { | |
288 snprintf(message, 127, "%d kbps", info.bitrate / 1000); | |
289 } | |
290 gtk_label_set_text(GTK_LABEL(mpeg_bitrate), message); | |
291 snprintf(message, 127, _("%d Hz"), info.freq); | |
292 gtk_label_set_text(GTK_LABEL(mpeg_samplerate), message); | |
293 if (info.frames != -1) { | |
294 snprintf(message, 127, _("%d frames"), info.frames); | |
295 gtk_label_set_text(GTK_LABEL(mpeg_frames), message); | |
296 } | |
297 else { | |
298 gtk_label_set_text(GTK_LABEL(mpeg_frames), ""); | |
299 } | |
300 gtk_label_set_text(GTK_LABEL(mpeg_flags), mode_str[info.mode]); | |
301 { | |
302 guint sec = mad_timer_count(info.duration, MAD_UNITS_SECONDS); | |
303 snprintf(message, 127, _("%d:%02d (%d seconds)"), sec /60 ,sec % 60, sec); | |
304 } | |
305 gtk_label_set_text(GTK_LABEL(mpeg_duration), message); | |
306 | |
307 if (info.replaygain_album_str != NULL) { | |
308 snprintf(message, 127, _("RG_album=%4s (x%4.2f)"), | |
309 info.replaygain_album_str, info.replaygain_album_scale); | |
310 gtk_label_set_text(GTK_LABEL(mpeg_replaygain), message); | |
311 } | |
312 else | |
313 gtk_label_set_text(GTK_LABEL(mpeg_replaygain), ""); | |
314 | |
315 if (info.replaygain_track_str != NULL) { | |
316 snprintf(message, 127, _("RG_track=%4s (x%4.2f)"), | |
317 info.replaygain_track_str, info.replaygain_track_scale); | |
318 gtk_label_set_text(GTK_LABEL(mpeg_replaygain2), message); | |
319 } | |
320 else | |
321 gtk_label_set_text(GTK_LABEL(mpeg_replaygain2), ""); | |
322 | |
323 if (info.replaygain_album_peak_str != NULL) { | |
324 snprintf(message, 127, _("Peak album=%4s (%+5.3fdBFS)"), | |
325 info.replaygain_album_peak_str, | |
326 20 * log10(info.replaygain_album_peak)); | |
327 gtk_label_set_text(GTK_LABEL(mpeg_replaygain3), message); | |
328 } | |
329 else | |
330 gtk_label_set_text(GTK_LABEL(mpeg_replaygain3), ""); | |
331 | |
332 if (info.replaygain_track_peak_str != NULL) { | |
333 snprintf(message, 127, _("Peak track=%4s (%+5.3fdBFS)"), | |
334 info.replaygain_track_peak_str, | |
335 20 * log10(info.replaygain_track_peak)); | |
336 gtk_label_set_text(GTK_LABEL(mpeg_replaygain4), message); | |
337 } | |
338 else | |
339 gtk_label_set_text(GTK_LABEL(mpeg_replaygain3), ""); | |
340 | |
341 if (info.mp3gain_undo_str != NULL) { | |
342 snprintf(message, 127, _("mp3gain undo=%4s (%+5.3fdB)"), | |
343 info.mp3gain_undo_str, info.mp3gain_undo); | |
344 gtk_label_set_text(GTK_LABEL(mp3gain1), message); | |
345 } | |
346 else | |
347 gtk_label_set_text(GTK_LABEL(mp3gain1), ""); | |
348 | |
349 if (info.mp3gain_minmax_str != NULL) { | |
350 snprintf(message, 127, _("mp3gain minmax=%4s (max-min=%+6.3fdB)"), | |
351 info.mp3gain_minmax_str, info.mp3gain_minmax); | |
352 gtk_label_set_text(GTK_LABEL(mp3gain2), message); | |
353 } | |
354 else | |
355 gtk_label_set_text(GTK_LABEL(mp3gain2), ""); | |
356 | |
357 gtk_label_set_text(GTK_LABEL(mpeg_fileinfo), ""); | |
358 | |
359 | |
360 // work out the index of the genre in the list | |
361 { | |
362 const id3_ucs4_t *string; | |
363 id3_ucs4_t *genre; | |
364 struct id3_frame *frame; | |
365 union id3_field *field; | |
366 frame = id3_tag_findframe(info.tag, ID3_FRAME_GENRE, 0); | |
367 if (frame) { | |
368 field = id3_frame_field(frame, 1); | |
369 string = id3_field_getstrings(field, 0); | |
370 genre = mad_parse_genre(string); | |
371 #ifdef DEBUG | |
372 if (genre) { | |
373 gchar *utf = (gchar *)id3_ucs4_utf8duplicate(genre); | |
374 g_print("genre = %s\n", utf); | |
375 g_print("genre num = %d\n", id3_genre_number(genre)); | |
376 g_free(utf); | |
377 } | |
378 #endif | |
379 if (genre) { | |
380 gtk_list_select_item(GTK_LIST | |
381 (GTK_COMBO(genre_combo)->list), | |
382 id3_genre_number(genre)+1); //shift one for "Unknown". | |
383 g_free((void *)genre); | |
384 } | |
385 } | |
386 } | |
387 | |
388 gtk_widget_set_sensitive(id3_frame, TRUE); | |
389 | |
390 #endif // !NOGUI | |
391 }*/ | |
392 |