~ubuntu-branches/ubuntu/utopic/rhythmbox/utopic-proposed

« back to all changes in this revision

Viewing changes to metadata/monkey-media/stream-info-impl/mp3-stream-info-impl.c

Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  monkey-sound
2
 
 *
3
 
 *  arch-tag: Implementation of MP3 metadata loading
4
 
 *
5
 
 *  Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
6
 
 *                     Marco Pesenti Gritti <marco@it.gnome.org>
7
 
 *                     Bastien Nocera <hadess@hadess.net>
8
 
 *                     Seth Nickell <snickell@stanford.edu>
9
 
 *
10
 
 *  This program is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU General Public License as published by
12
 
 *  the Free Software Foundation; either version 2 of the License, or
13
 
 *  (at your option) any later version.
14
 
 *
15
 
 *  This program is distributed in the hope that it will be useful,
16
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 *  GNU General Public License for more details.
19
 
 *
20
 
 *  You should have received a copy of the GNU General Public License
21
 
 *  along with this program; if not, write to the Free Software
22
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
 
 *
24
 
 */
25
 
 
26
 
#include <libgnomevfs/gnome-vfs.h>
27
 
#include <string.h>
28
 
#include <stdlib.h>
29
 
 
30
 
#include <id3tag.h>
31
 
 
32
 
#include "rb-string-helpers.h"
33
 
 
34
 
#include "id3-vfs/id3-vfs.h"
35
 
 
36
 
#include "monkey-media-stream-info.h"
37
 
#include "monkey-media-private.h"
38
 
 
39
 
#include "mp3-stream-info-impl.h"
40
 
 
41
 
static void MP3_stream_info_impl_class_init (MP3StreamInfoImplClass *klass);
42
 
static void MP3_stream_info_impl_init (MP3StreamInfoImpl *ma);
43
 
static void MP3_stream_info_impl_finalize (GObject *object);
44
 
static void MP3_stream_info_impl_open_stream (MonkeyMediaStreamInfo *info);
45
 
static gboolean MP3_stream_info_impl_get_bitrate_info (MP3StreamInfoImpl *impl);
46
 
static gboolean MP3_stream_info_impl_get_value (MonkeyMediaStreamInfo *info,
47
 
                                                MonkeyMediaStreamInfoField field,
48
 
                                                int index,
49
 
                                                GValue *value);
50
 
static gboolean MP3_stream_info_impl_set_value (MonkeyMediaStreamInfo *info,
51
 
                                                MonkeyMediaStreamInfoField field,
52
 
                                                int index,
53
 
                                                const GValue *value);
54
 
static char *MP3_stream_info_impl_id3_tag_get_utf8 (struct id3_tag *tag,
55
 
                                                    const char *field_name);
56
 
static int MP3_stream_info_impl_get_n_values (MonkeyMediaStreamInfo *info,
57
 
                                              MonkeyMediaStreamInfoField field);
58
 
 
59
 
struct MP3BitrateInfo
60
 
{
61
 
        int bitrate;
62
 
        int samplerate;
63
 
        int time;
64
 
        int channels;
65
 
        int version;
66
 
        int vbr;
67
 
};
68
 
 
69
 
struct MP3StreamInfoImplPrivate
70
 
{
71
 
        struct id3_tag *tag;
72
 
        struct id3_vfs_file *file;
73
 
        struct MP3BitrateInfo *info_num;
74
 
};
75
 
 
76
 
 
77
 
/* libid3tag doesn't define those, and we need them */
78
 
#define MM_ID3_FRAME_DISC "TPOS"
79
 
#define MM_ID3_FRAME_LEN  "TLEN"
80
 
 
81
 
static GObjectClass *parent_class = NULL;
82
 
 
83
 
GType
84
 
MP3_stream_info_impl_get_type (void)
85
 
{
86
 
        static GType MP3_stream_info_impl_type = 0;
87
 
 
88
 
        if (MP3_stream_info_impl_type == 0)
89
 
        {
90
 
                static const GTypeInfo our_info =
91
 
                {
92
 
                        sizeof (MP3StreamInfoImplClass),
93
 
                        NULL,
94
 
                        NULL,
95
 
                        (GClassInitFunc) MP3_stream_info_impl_class_init,
96
 
                        NULL,
97
 
                        NULL,
98
 
                        sizeof (MP3StreamInfoImpl),
99
 
                        0,
100
 
                        (GInstanceInitFunc) MP3_stream_info_impl_init
101
 
                };
102
 
 
103
 
                MP3_stream_info_impl_type = g_type_register_static (MONKEY_MEDIA_TYPE_STREAM_INFO,
104
 
                                                                       "MP3StreamInfoImpl",
105
 
                                                                       &our_info, 0);
106
 
        }
107
 
 
108
 
        return MP3_stream_info_impl_type;
109
 
}
110
 
 
111
 
static void
112
 
MP3_stream_info_impl_class_init (MP3StreamInfoImplClass *klass)
113
 
{
114
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
115
 
        MonkeyMediaStreamInfoClass *info_class = MONKEY_MEDIA_STREAM_INFO_CLASS (klass);
116
 
 
117
 
        parent_class = g_type_class_peek_parent (klass);
118
 
 
119
 
        object_class->finalize = MP3_stream_info_impl_finalize;
120
 
 
121
 
        info_class->open_stream  = MP3_stream_info_impl_open_stream;
122
 
        info_class->get_n_values = MP3_stream_info_impl_get_n_values;
123
 
        info_class->get_value    = MP3_stream_info_impl_get_value;
124
 
        info_class->set_value    = MP3_stream_info_impl_set_value;
125
 
}
126
 
 
127
 
static void
128
 
MP3_stream_info_impl_init (MP3StreamInfoImpl *impl)
129
 
{
130
 
        impl->priv = g_new0 (MP3StreamInfoImplPrivate, 1);
131
 
}
132
 
 
133
 
static void
134
 
MP3_stream_info_impl_finalize (GObject *object)
135
 
{
136
 
        MP3StreamInfoImpl *impl;
137
 
 
138
 
        g_return_if_fail (object != NULL);
139
 
        g_return_if_fail (IS_MP3_STREAM_INFO_IMPL (object));
140
 
 
141
 
        impl = MP3_STREAM_INFO_IMPL (object);
142
 
 
143
 
        g_return_if_fail (impl->priv != NULL);
144
 
 
145
 
        if (impl->priv->file != NULL)
146
 
                id3_vfs_close (impl->priv->file);
147
 
 
148
 
        g_free (impl->priv->info_num);
149
 
        g_free (impl->priv);
150
 
 
151
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
152
 
}
153
 
 
154
 
static void
155
 
MP3_stream_info_impl_open_stream (MonkeyMediaStreamInfo *info)
156
 
{
157
 
        MP3StreamInfoImpl *impl = MP3_STREAM_INFO_IMPL (info);
158
 
        char *uri;
159
 
        GError *error;
160
 
 
161
 
        g_object_get (G_OBJECT (info),
162
 
                      "error", &error,
163
 
                      "location", &uri,
164
 
                      NULL);
165
 
 
166
 
        impl->priv->file = id3_vfs_open (uri, ID3_FILE_MODE_READONLY);
167
 
        g_free (uri);
168
 
        if (impl->priv->file == NULL)
169
 
        {
170
 
                error = g_error_new (MONKEY_MEDIA_STREAM_INFO_ERROR,
171
 
                                     MONKEY_MEDIA_STREAM_INFO_ERROR_OPEN_FAILED,
172
 
                                     _("Failed to open file for reading"));
173
 
                g_object_set (G_OBJECT (info), "error", error, NULL);
174
 
                return;
175
 
        }
176
 
 
177
 
        impl->priv->tag = id3_vfs_tag (impl->priv->file);
178
 
 
179
 
        if (MP3_stream_info_impl_get_bitrate_info (impl) == FALSE)
180
 
        {
181
 
                error = g_error_new (MONKEY_MEDIA_STREAM_INFO_ERROR,
182
 
                                     MONKEY_MEDIA_STREAM_INFO_ERROR_OPEN_FAILED,
183
 
                                     _("Failed to gather information about the file"));
184
 
                g_object_set (G_OBJECT (info), "error", error, NULL);
185
 
                return;
186
 
        }
187
 
}
188
 
 
189
 
static void
190
 
MP3_stream_info_impl_get_length_from_tag (MP3StreamInfoImpl *impl)
191
 
{
192
 
        struct id3_frame const *frame;
193
 
 
194
 
        /* The following is based on information from the
195
 
         * ID3 tag version 2.4.0 Native Frames informal standard.
196
 
         */
197
 
        frame = id3_tag_findframe(impl->priv->tag, MM_ID3_FRAME_LEN, 0);
198
 
 
199
 
        if (frame == NULL)
200
 
                return;
201
 
 
202
 
        {
203
 
                union id3_field const *field;
204
 
                unsigned int nstrings;
205
 
                id3_latin1_t *latin1;
206
 
 
207
 
                field = id3_frame_field (frame, 1);
208
 
                nstrings = id3_field_getnstrings (field);
209
 
                if (nstrings <= 0)
210
 
                        return;
211
 
 
212
 
                latin1 = id3_ucs4_latin1duplicate
213
 
                        (id3_field_getstrings(field, 0));
214
 
 
215
 
                if (latin1 == NULL)
216
 
                        return;
217
 
 
218
 
                /* "The 'Length' frame contains the length of the
219
 
                 * audio file in milliseconds, represented as a
220
 
                 * numeric string."
221
 
                 */
222
 
                if (atol(latin1) > 0)
223
 
                        /* monkey-media needs a duration in seconds */
224
 
                        impl->priv->info_num->time = atol(latin1)/1000;
225
 
                g_free (latin1);
226
 
        }
227
 
}
228
 
 
229
 
static gboolean
230
 
MP3_stream_info_impl_get_bitrate_info (MP3StreamInfoImpl *impl)
231
 
{
232
 
        if (impl->priv->info_num == NULL)
233
 
        {
234
 
                struct MP3BitrateInfo *info;
235
 
 
236
 
                info = g_new0 (struct MP3BitrateInfo, 1);
237
 
                if (id3_vfs_bitrate (impl->priv->file,
238
 
                                &info->bitrate,
239
 
                                &info->samplerate,
240
 
                                &info->time,
241
 
                                &info->version,
242
 
                                &info->vbr,
243
 
                                &info->channels) == 0)
244
 
                {
245
 
                        impl->priv->info_num = info;
246
 
                        return FALSE;
247
 
                }
248
 
 
249
 
                impl->priv->info_num = info;
250
 
 
251
 
                MP3_stream_info_impl_get_length_from_tag (impl);
252
 
        }
253
 
 
254
 
        return TRUE;
255
 
}
256
 
 
257
 
/* This tries to read and parse a tag whose value is "xx/yy" and returns
258
 
 * the xx part as an int
259
 
 */
260
 
static int
261
 
get_current_number_from_tag (MP3StreamInfoImpl *impl, const gchar *tag) 
262
 
{       
263
 
        char **parts;
264
 
        int num = -1;
265
 
        gchar *tmp;
266
 
 
267
 
        tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, tag);
268
 
        if (tmp == NULL)
269
 
        {
270
 
                g_free (tmp);
271
 
                return -1;
272
 
        }
273
 
        
274
 
        parts = g_strsplit (tmp, "/", -1);
275
 
        
276
 
        if (parts[0] != NULL)
277
 
                num = atoi (parts[0]);
278
 
        
279
 
        g_strfreev (parts);
280
 
        g_free (tmp);
281
 
 
282
 
        return num;
283
 
}
284
 
 
285
 
/* This tries to read and parse a tag whose value is "xx/yy" and returns
286
 
 * the yy part as an int
287
 
 */
288
 
static int
289
 
get_total_number_from_tag (MP3StreamInfoImpl *impl, const gchar *tag) 
290
 
{       
291
 
        char **parts;
292
 
        int num = -1;
293
 
        gchar *tmp;
294
 
        
295
 
        tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, tag);
296
 
        if (tmp == NULL)
297
 
        {
298
 
                g_free (tmp);
299
 
                return -1;
300
 
        }
301
 
        
302
 
        parts = g_strsplit (tmp, "/", -1);
303
 
 
304
 
        if (parts[0] != NULL && parts[1] != NULL)
305
 
                num = atoi (parts[1]);
306
 
        
307
 
        g_strfreev (parts);
308
 
        g_free (tmp);
309
 
 
310
 
        return num;
311
 
}
312
 
 
313
 
static int
314
 
MP3_stream_info_impl_get_n_values (MonkeyMediaStreamInfo *info,
315
 
                                   MonkeyMediaStreamInfoField field)
316
 
{
317
 
        MP3StreamInfoImpl *impl;
318
 
        char *tmp;
319
 
        gboolean ret = FALSE;
320
 
        
321
 
        g_return_val_if_fail (IS_MP3_STREAM_INFO_IMPL (info), 0);
322
 
 
323
 
        impl = MP3_STREAM_INFO_IMPL (info);
324
 
 
325
 
        switch (field)
326
 
        {
327
 
        /* tags */
328
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_TITLE:
329
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_TITLE);
330
 
                ret = (tmp != NULL);
331
 
                g_free (tmp);
332
 
                return ret;
333
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ARTIST:
334
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_ARTIST);
335
 
                ret = (tmp != NULL);
336
 
                g_free (tmp);
337
 
                return ret;
338
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ALBUM:
339
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_ALBUM);
340
 
                ret = (tmp != NULL);
341
 
                g_free (tmp);
342
 
                return ret;
343
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DATE:
344
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_YEAR);
345
 
                ret = (tmp != NULL);
346
 
                g_free (tmp);
347
 
                return ret;
348
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_GENRE:
349
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_GENRE);
350
 
                ret = (tmp != NULL);
351
 
                g_free (tmp);
352
 
                return ret;
353
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_COMMENT:
354
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_COMMENT);
355
 
                ret = (tmp != NULL);
356
 
                g_free (tmp);
357
 
                return ret;
358
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_TRACK_NUMBER:
359
 
                {       
360
 
                        int num;
361
 
                        num = get_current_number_from_tag (impl, ID3_FRAME_TRACK);
362
 
                        return (num == -1?0:1);
363
 
                }
364
 
                break;
365
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_MAX_TRACK_NUMBER:
366
 
                {
367
 
                        int num;
368
 
                        num = get_total_number_from_tag (impl, ID3_FRAME_TRACK);
369
 
                        return (num == -1?0:1);
370
 
                }
371
 
                break;
372
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DISC_NUMBER:
373
 
                {       
374
 
                        int num;
375
 
                        num = get_current_number_from_tag (impl, MM_ID3_FRAME_DISC);
376
 
                        return (num == -1?0:1);
377
 
                }
378
 
                break;
379
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_MAX_DISC_NUMBER:
380
 
                {
381
 
                        int num;
382
 
                        num = get_total_number_from_tag (impl, MM_ID3_FRAME_DISC);
383
 
                        return (num == -1?0:1);
384
 
                }
385
 
                break;
386
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_LOCATION:
387
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DESCRIPTION:
388
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_VERSION:
389
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ISRC:
390
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ORGANIZATION:
391
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_COPYRIGHT:
392
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_CONTACT:
393
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_LICENSE:
394
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_PERFORMER:
395
 
                return 0;
396
 
 
397
 
        /* generic bits */
398
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_FILE_SIZE:
399
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DURATION:
400
 
                return 1;
401
 
 
402
 
        /* audio bits */
403
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_AUDIO:
404
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CODEC_INFO:
405
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_BIT_RATE:
406
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_AVERAGE_BIT_RATE:
407
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VARIABLE_BIT_RATE:
408
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_QUALITY:
409
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SAMPLE_RATE:
410
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CHANNELS:
411
 
                return 1;
412
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SERIAL_NUMBER:
413
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VENDOR:
414
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_GAIN:
415
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_GAIN:
416
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_PEAK:
417
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_PEAK:
418
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRM_ID:
419
 
                return 0;
420
 
 
421
 
        /* video bits */
422
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_VIDEO:
423
 
                return 1;
424
 
 
425
 
        /* default */
426
 
        default:
427
 
                return 0;
428
 
        }
429
 
}
430
 
 
431
 
static gboolean
432
 
MP3_stream_info_impl_get_value (MonkeyMediaStreamInfo *info,
433
 
                                MonkeyMediaStreamInfoField field,
434
 
                                int index,
435
 
                                GValue *value)
436
 
{
437
 
        MP3StreamInfoImpl *impl;
438
 
        char *tmp;
439
 
        
440
 
        g_return_val_if_fail (IS_MP3_STREAM_INFO_IMPL (info), FALSE);
441
 
        g_return_val_if_fail (value != NULL, FALSE);
442
 
 
443
 
        impl = MP3_STREAM_INFO_IMPL (info);
444
 
        
445
 
        if (MP3_stream_info_impl_get_n_values (info, field) <= 0)
446
 
                return FALSE;
447
 
 
448
 
        switch (field)
449
 
        {
450
 
        /* tags */
451
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_TITLE:
452
 
                g_value_init (value, G_TYPE_STRING);
453
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_TITLE);
454
 
                g_value_set_string (value, tmp);
455
 
                g_free (tmp);
456
 
                break;
457
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ARTIST:
458
 
                g_value_init (value, G_TYPE_STRING);
459
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_ARTIST);
460
 
                g_value_set_string (value, tmp);
461
 
                g_free (tmp);
462
 
                break;
463
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ALBUM:
464
 
                g_value_init (value, G_TYPE_STRING);
465
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_ALBUM);
466
 
                g_value_set_string (value, tmp);
467
 
                g_free (tmp);
468
 
                break;
469
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DATE:
470
 
                g_value_init (value, G_TYPE_STRING);
471
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_YEAR);
472
 
                g_value_set_string (value, tmp);
473
 
                g_free (tmp);
474
 
                break;
475
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_GENRE:
476
 
                g_value_init (value, G_TYPE_STRING);
477
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_GENRE);
478
 
                g_value_set_string (value, tmp);
479
 
                g_free (tmp);
480
 
                break;
481
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_COMMENT:
482
 
                g_value_init (value, G_TYPE_STRING);
483
 
                tmp = MP3_stream_info_impl_id3_tag_get_utf8 (impl->priv->tag, ID3_FRAME_COMMENT);
484
 
                g_value_set_string (value, tmp);
485
 
                g_free (tmp);
486
 
                break;
487
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_TRACK_NUMBER:
488
 
                {       
489
 
                        int num;
490
 
                        num = get_current_number_from_tag (impl, ID3_FRAME_TRACK);
491
 
                        g_value_init (value, G_TYPE_INT);
492
 
                        g_value_set_int (value, num);                   
493
 
                }
494
 
                break;
495
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_MAX_TRACK_NUMBER:
496
 
                {
497
 
                        int num;
498
 
                        num = get_total_number_from_tag (impl, ID3_FRAME_TRACK);
499
 
                        g_value_init (value, G_TYPE_INT);
500
 
                        g_value_set_int (value, num);                   
501
 
                }
502
 
                break;
503
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DISC_NUMBER:
504
 
                {       
505
 
                        int num;
506
 
                        num = get_current_number_from_tag (impl, MM_ID3_FRAME_DISC);
507
 
                        g_value_init (value, G_TYPE_INT);
508
 
                        g_value_set_int (value, num);
509
 
                }
510
 
                break;
511
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_MAX_DISC_NUMBER:
512
 
                {
513
 
                        int num;
514
 
                        num = get_total_number_from_tag (impl, MM_ID3_FRAME_DISC);
515
 
                        g_value_init (value, G_TYPE_INT);
516
 
                        g_value_set_int (value, num);
517
 
                }
518
 
                break;
519
 
 
520
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_LOCATION:
521
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DESCRIPTION:
522
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_VERSION:
523
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ISRC:
524
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_ORGANIZATION:
525
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_COPYRIGHT:
526
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_CONTACT:
527
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_LICENSE:
528
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_PERFORMER:
529
 
                g_value_init (value, G_TYPE_STRING);
530
 
                g_value_set_string (value, "");
531
 
                break;
532
 
 
533
 
        /* generic bits */
534
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_FILE_SIZE:
535
 
                {
536
 
                        GnomeVFSFileInfo *i;
537
 
                        GnomeVFSResult res;
538
 
                        char *uri;
539
 
 
540
 
                        g_object_get (G_OBJECT (info), "location", &uri, NULL);
541
 
 
542
 
                        g_value_init (value, G_TYPE_LONG);
543
 
                        
544
 
                        i = gnome_vfs_file_info_new ();
545
 
                        res = gnome_vfs_get_file_info (uri, i,
546
 
                                                       GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
547
 
                        if (res == GNOME_VFS_OK)
548
 
                                g_value_set_long (value, i->size);
549
 
                        else
550
 
                                g_value_set_long (value, 0);
551
 
 
552
 
                        gnome_vfs_file_info_unref (i);
553
 
                }
554
 
                break;
555
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_DURATION:
556
 
                g_value_init (value, G_TYPE_LONG);
557
 
 
558
 
                if (impl->priv->info_num->vbr == 0)
559
 
                {
560
 
                        GnomeVFSFileSize size;
561
 
                        GValue val = { 0, };
562
 
 
563
 
                        MP3_stream_info_impl_get_value (info,
564
 
                                                        MONKEY_MEDIA_STREAM_INFO_FIELD_FILE_SIZE,
565
 
                                                        0,
566
 
                                                        &val);
567
 
                        size = g_value_get_long (&val);
568
 
                        g_value_unset (&val);
569
 
 
570
 
                        if (impl->priv->info_num->bitrate > 0)
571
 
                                g_value_set_long (value, ((double) size / 1000.0f) / ((double) impl->priv->info_num->bitrate / 8.0f / 1000.0f));
572
 
                        else
573
 
                                g_value_set_long (value, 0);
574
 
                } else {
575
 
                        g_value_set_long (value, impl->priv->info_num->time);
576
 
                }
577
 
                break;
578
 
 
579
 
        /* audio bits */
580
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_AUDIO:
581
 
                g_value_init (value, G_TYPE_BOOLEAN);
582
 
                g_value_set_boolean (value, TRUE);
583
 
                break;
584
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CODEC_INFO:
585
 
                g_value_init (value, G_TYPE_STRING);
586
 
                if (impl->priv->info_num->version != 3)
587
 
                {
588
 
                        tmp = g_strdup_printf (_("MPEG %d Layer III"), impl->priv->info_num->version);
589
 
                } else {
590
 
                        tmp = g_strdup (_("MPEG 2.5 Layer III"));
591
 
                }
592
 
                g_value_set_string (value, tmp);
593
 
                g_free (tmp);
594
 
                break;
595
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_BIT_RATE:
596
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_AVERAGE_BIT_RATE:
597
 
                g_value_init (value, G_TYPE_INT);
598
 
                g_value_set_int (value, impl->priv->info_num->bitrate / 1000);
599
 
                break;
600
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRM_ID:
601
 
                /* FIXME */
602
 
                g_value_init (value, G_TYPE_STRING);
603
 
                g_value_set_string (value, NULL);
604
 
                break;
605
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VARIABLE_BIT_RATE:
606
 
                g_value_init (value, G_TYPE_BOOLEAN);
607
 
                g_value_set_boolean (value, impl->priv->info_num->vbr);
608
 
                break;
609
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SAMPLE_RATE:
610
 
                g_value_init (value, G_TYPE_LONG);
611
 
                g_value_set_long (value, impl->priv->info_num->samplerate);
612
 
                break;
613
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_CHANNELS:
614
 
                g_value_init (value, G_TYPE_INT);
615
 
                g_value_set_int (value, impl->priv->info_num->channels);
616
 
                break;
617
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_SERIAL_NUMBER:
618
 
                g_value_init (value, G_TYPE_LONG);
619
 
                g_value_set_long (value, 0);
620
 
                break;
621
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_VENDOR:
622
 
                g_value_init (value, G_TYPE_STRING);
623
 
                g_value_set_string (value, "");
624
 
                break;
625
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_GAIN:
626
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_GAIN:
627
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_ALBUM_PEAK:
628
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_AUDIO_TRACK_PEAK:
629
 
                g_value_init (value, G_TYPE_DOUBLE);
630
 
                g_value_set_double (value, 0.0);
631
 
                break;
632
 
 
633
 
        /* video bits */
634
 
        case MONKEY_MEDIA_STREAM_INFO_FIELD_HAS_VIDEO:
635
 
                g_value_init (value, G_TYPE_BOOLEAN);
636
 
                g_value_set_boolean (value, FALSE);
637
 
                break;
638
 
 
639
 
        /* default */
640
 
        default:
641
 
                g_warning ("Invalid field!");
642
 
                g_value_init (value, G_TYPE_NONE);
643
 
                break;
644
 
        }
645
 
 
646
 
        return TRUE;
647
 
}
648
 
 
649
 
static gboolean
650
 
MP3_stream_info_impl_set_value (MonkeyMediaStreamInfo *info,
651
 
                                MonkeyMediaStreamInfoField field,
652
 
                                int index,
653
 
                                const GValue *value)
654
 
{
655
 
        /* FIXME */
656
 
        return FALSE;
657
 
}
658
 
 
659
 
static char *
660
 
MP3_stream_info_impl_id3_tag_get_utf8 (struct id3_tag *tag, const char *field_name)
661
 
{
662
 
        unsigned int nstrings, j; 
663
 
        const struct id3_frame *frame;
664
 
        const union id3_field *field;
665
 
        const id3_ucs4_t *ucs4 = NULL;
666
 
        id3_utf8_t *utf8 = NULL;
667
 
 
668
 
        frame = id3_tag_findframe (tag, field_name, 0);
669
 
        if (frame == 0)
670
 
                return NULL;
671
 
 
672
 
        field = id3_frame_field(frame, 1);
673
 
        nstrings = id3_field_getnstrings (field);
674
 
        for (j = 0; j < nstrings; j++)
675
 
        {
676
 
                id3_utf8_t *tmp = NULL;
677
 
 
678
 
                ucs4 = id3_field_getstrings (field, j);
679
 
 
680
 
                if (strcmp (field_name, ID3_FRAME_GENRE) == 0)
681
 
                        ucs4 = id3_genre_name (ucs4);
682
 
 
683
 
                tmp = id3_ucs4_utf8duplicate (ucs4);
684
 
                if (strcmp (tmp, "") != 0)
685
 
                        utf8 = tmp;
686
 
                else
687
 
                        g_free (tmp);
688
 
        }
689
 
 
690
 
        if (utf8 && !g_utf8_validate (utf8, -1, NULL)) {
691
 
                g_warning ("Invalid UTF-8 in %s field in mp3 file\n", field_name);
692
 
                /* Should rb_unicodify really be used to convert ucs4 data to utf8? */
693
 
                utf8 = rb_unicodify ((char *) ucs4);
694
 
        }
695
 
 
696
 
        return utf8;
697
 
}