示例#1
0
gboolean Mac_Header_Read_File_Info(gchar *filename, ET_File_Info *ETFileInfo)
{
    StreamInfoMac Info;

    if (info_mac_read(filename, &Info))
    {
        gchar *filename_utf8 = filename_to_display(filename);
        fprintf(stderr,"MAC header not found for file '%s'\n", filename_utf8);
        g_free(filename_utf8);
        return FALSE;
    }
    ETFileInfo->mpc_profile   = g_strdup(Info.CompresionName);
    ETFileInfo->version       = Info.Version;
    ETFileInfo->bitrate       = Info.Bitrate/1000.0;
    ETFileInfo->samplerate    = Info.SampleFreq;
    ETFileInfo->mode          = Info.Channels;
    ETFileInfo->size          = Info.FileSize;
    ETFileInfo->duration      = Info.Duration/1000;

    return TRUE;
}
示例#2
0
gboolean Speex_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
{
    vcedit_state *state;
    SpeexHeader  *si;
    gchar *encoder_version = NULL;
    gint channels = 0;
    glong rate = 0;
    glong bitrate = 0;
    gdouble duration = 0;
    gulong filesize;
    gchar *filename_utf8;
    GFile *gfile;
    GError *error = NULL;

    g_return_val_if_fail (filename != NULL && ETFileInfo != NULL, FALSE);

    filename_utf8 = filename_to_display(filename);

    state = vcedit_new_state();    // Allocate memory for 'state'
    gfile = g_file_new_for_path (filename);
    if (!vcedit_open (state, gfile, &error))
    {
        Log_Print (LOG_ERROR,
                   _("Error: Failed to open file: '%s' as Vorbis (%s)."),
                   filename_utf8, error->message);
        g_error_free (error);
        g_object_unref (gfile);
        g_free(filename_utf8);
        vcedit_clear(state);
        return FALSE;
    }

    // Get Speex information
    if ( (si=state->si) != NULL )
    {
        encoder_version = si->speex_version;
        channels        = si->nb_channels;        // Number of channels in bitstream.
        rate            = si->rate;               // (Hz) Sampling rate of the bitstream.
        bitrate         = si->bitrate;            // (b/s) Specifies the bitrate

        duration        = 0;//ov_time_total(&vf,-1); // (s) Total time.

        //g_print("play time: %ld s\n",(long)ov_time_total(&vf,-1));
        //g_print("serialnumber: %ld\n",(long)ov_serialnumber(&vf,-1));
        //g_print("compressed length: %ld bytes\n",(long)(ov_raw_total(&vf,-1)));
    }

    filesize = Get_File_Size(filename);

    ETFileInfo->mpc_version = g_strdup(encoder_version);
    ETFileInfo->bitrate     = bitrate/1000;
    ETFileInfo->samplerate  = rate;
    ETFileInfo->mode        = channels;
    ETFileInfo->size        = filesize;
    //if (bitrate > 0)
    //    ETFileInfo->duration = filesize*8/bitrate/1000; // FIXME : Approximation!! Needs to remove tag size!
    //else
        ETFileInfo->duration   = duration;

    vcedit_clear(state);
    g_object_unref (gfile);
    g_free(filename_utf8);
    return TRUE;
}
示例#3
0
gboolean
Ogg_Header_Read_File_Info (const gchar *filename, ET_File_Info *ETFileInfo)
{
    OggVorbis_File vf;
    vorbis_info *vi;
    gint encoder_version = 0;
    gint channels = 0;
    glong rate = 0;
    glong bitrate_nominal = 0;
    gdouble duration = 0;
    gulong filesize;
    gint res;
    ov_callbacks callbacks = { et_ogg_read_func, et_ogg_seek_func,
                               et_ogg_close_func, et_ogg_tell_func };
    EtOggState state;
    gchar *filename_utf8;

    g_return_val_if_fail (filename != NULL && ETFileInfo != NULL, FALSE);

    state.file = g_file_new_for_path (filename);
    state.error = NULL;
    state.istream = G_INPUT_STREAM (g_file_read (state.file, NULL,
                                                 &state.error));

    filename_utf8 = filename_to_display (filename);

    if (!state.istream)
    {
        /* FIXME: Pass error back to calling function. */
        Log_Print (LOG_ERROR, _("Error while opening file: '%s' (%s)"),
                   filename_utf8, state.error->message);
        g_free (filename_utf8);
        return FALSE;
    }

    if ((res = ov_open_callbacks (&state, &vf, NULL, 0, callbacks)) == 0)
    {
        if ( (vi=ov_info(&vf,0)) != NULL )
        {
            encoder_version = vi->version;         // Vorbis encoder version used to create this bitstream.
            channels        = vi->channels;        // Number of channels in bitstream.
            rate            = vi->rate;            // (Hz) Sampling rate of the bitstream.
            bitrate_nominal = vi->bitrate_nominal; // (b/s) Specifies the average bitrate for a VBR bitstream.
        }else
        {
            Log_Print(LOG_ERROR,_("Ogg Vorbis: The specified bitstream does not exist or the "
                        "file has been initialized improperly (file: '%s')."),filename_utf8);
        }

        duration        = ov_time_total(&vf,-1); // (s) Total time.
        //g_print("play time: %ld s\n",(long)ov_time_total(&vf,-1));
        //g_print("serialnumber: %ld\n",(long)ov_serialnumber(&vf,-1));
        //g_print("compressed length: %ld bytes\n",(long)(ov_raw_total(&vf,-1)));

        /***{
            // Test for displaying comments
            vorbis_comment *vc = ov_comment(&vf,-1);
            Log_Print(LOG_OK,">>> %s",filename_utf8);
            Log_Print(LOG_OK,"Nbr comments : %d",vc->comments);
            Log_Print(LOG_OK,"Vendor : %s",vc->vendor);
            char **ptr = vc->user_comments;
            while(*ptr){
              Log_Print(LOG_OK,"> %s",*ptr);
              ++ptr;
            }
        }***/
        ov_clear(&vf); // This close also the file
    }else
    {
        /* On error. */
        if (state.error)
        {
            g_debug ("Ogg Vorbis: error reading header information (%s)",
                     state.error->message);
        }

        et_ogg_close_func (&state);

        switch (res)
        {
            case OV_EREAD:
                Log_Print(LOG_ERROR,_("Ogg Vorbis: Read from media returned an error (file: '%s')."),filename_utf8);
                break;
            case OV_ENOTVORBIS:
                Log_Print(LOG_ERROR,_("Ogg Vorbis: Bitstream is not Vorbis data (file: '%s')."),filename_utf8);
                break;
            case OV_EVERSION:
                Log_Print(LOG_ERROR,_("Ogg Vorbis: Vorbis version mismatch (file: '%s')."),filename_utf8);
                break;
            case OV_EBADHEADER:
                Log_Print(LOG_ERROR,_("Ogg Vorbis: Invalid Vorbis bitstream header (file: '%s')."),filename_utf8);
                break;
            case OV_EFAULT:
                Log_Print(LOG_ERROR,_("Ogg Vorbis: Internal logic fault, indicates a bug or heap/stack corruption (file: '%s')."),filename_utf8);
                break;
            default:
                break;
        }
    }

    filesize = Get_File_Size(filename);

    ETFileInfo->version    = encoder_version;
    ETFileInfo->bitrate    = bitrate_nominal/1000;
    ETFileInfo->samplerate = rate;
    ETFileInfo->mode       = channels;
    ETFileInfo->size       = filesize;
    ETFileInfo->duration   = duration;

    g_free(filename_utf8);
    return TRUE;
}
示例#4
0
/*
 * Read tag data from a FLAC file using the level 1 flac interface,
 * Note:
 *  - if field is found but contains no info (strlen(str)==0), we don't read it
 */
gboolean Flac_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    FLAC__Metadata_SimpleIterator *iter;
    gchar *string = NULL;
    gchar *filename_utf8 = filename_to_display(filename);
    guint i;
#ifndef LEGACY_FLAC // For FLAC >= 1.1.3
    Picture *prev_pic = NULL;
#endif
    //gint j = 1;


    if (!filename || !FileTag)
        return FALSE;

    flac_error_msg = NULL;

    // Initialize the iterator for the blocks
    iter = FLAC__metadata_simple_iterator_new();
    if ( iter == NULL || !FLAC__metadata_simple_iterator_init(iter, filename, true, false) )
    {
        if ( iter == NULL )
        {
            // Error with "FLAC__metadata_simple_iterator_new"
            flac_error_msg = FLAC__Metadata_SimpleIteratorStatusString[FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR];
        } else
        {
            // Error with "FLAC__metadata_simple_iterator_init"
            FLAC__Metadata_SimpleIteratorStatus status = FLAC__metadata_simple_iterator_status(iter);
            flac_error_msg = FLAC__Metadata_SimpleIteratorStatusString[status];

            FLAC__metadata_simple_iterator_delete(iter);
        }

        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' as FLAC (%s)."),filename_utf8,flac_error_msg);
        g_free(filename_utf8);
        return FALSE;
    }


    /* libFLAC is able to detect (and skip) ID3v2 tags by itself */

    while (FLAC__metadata_simple_iterator_next(iter))
    {
        // Get block data
        FLAC__StreamMetadata *block = FLAC__metadata_simple_iterator_get_block(iter);
        //g_print("Read: %d %s -> block type: %d\n",j++,g_path_get_basename(filename),FLAC__metadata_simple_iterator_get_block_type(iter));

        // Action to do according the type
        switch ( FLAC__metadata_simple_iterator_get_block_type(iter) )
        {
        //
        // Read the VORBIS_COMMENT block (only one should exist)
        //
        case FLAC__METADATA_TYPE_VORBIS_COMMENT:
        {
            FLAC__StreamMetadata_VorbisComment       *vc;
            FLAC__StreamMetadata_VorbisComment_Entry *field;
            gint   field_num;
            gint   field_len;
            gchar *field_value;
            gchar *field_value_tmp;

            // Get comments from block
            vc = &block->data.vorbis_comment;

            /*********
             * Title *
             *********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"TITLE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->title==NULL)
                            FileTag->title = g_strdup(field_value);
                        else
                            FileTag->title = g_strconcat(FileTag->title,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /**********
             * Artist *
             **********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"ARTIST")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->artist==NULL)
                            FileTag->artist = g_strdup(field_value);
                        else
                            FileTag->artist = g_strconcat(FileTag->artist,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*********
             * Album *
             *********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"ALBUM")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->album==NULL)
                            FileTag->album = g_strdup(field_value);
                        else
                            FileTag->album = g_strconcat(FileTag->album,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /***************
             * Disc Number *
             ***************/
            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"DISCNUMBER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        FileTag->disc_number = field_value;
                    }
                }
            }

            /********
             * Year *
             ********/
            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"DATE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        FileTag->year = field_value;
                        if (g_utf8_strlen(FileTag->year, -1) > 4)
                            Log_Print(LOG_WARNING,_("The year value '%s' seems to be invalid in file '%s'. The information will be lost while saving tag."),FileTag->year,filename_utf8);
                    }
                }
            }

            /*************************
             * Track and Total Track *
             *************************/
            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"TRACKTOTAL")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (NUMBER_TRACK_FORMATED)
                        {
                            FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(field_value));
                        } else
                        {
                            FileTag->track_total = g_strdup(field_value);
                        }
                        g_free(field_value);
                    }
                }
                // Below is also filled track_total if not done here
            }

            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"TRACKNUMBER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        string = g_utf8_strchr(field_value, -1, '/');
                        if (NUMBER_TRACK_FORMATED)
                        {
                            // If track_total not filled before, try now...
                            if (string && !FileTag->track_total)
                            {
                                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string+1));
                                *string = '\0';
                            }
                            FileTag->track = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(field_value));
                        } else
                        {
                            if (string && !FileTag->track_total)
                            {
                                FileTag->track_total = g_strdup(string+1);
                                *string = '\0';
                            }
                            FileTag->track = g_strdup(field_value);
                        }
                        g_free(field_value);
                    }
                }
            }

            /*********
             * Genre *
             *********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"GENRE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->genre==NULL)
                            FileTag->genre = g_strdup(field_value);
                        else
                            FileTag->genre = g_strconcat(FileTag->genre,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /***********
             * Comment *
             ***********/
            field_num = 0;
            while ( 1 )
            {
                gint field_num1, field_num2;

                // The comment field can take two forms...
                field_num1 = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"DESCRIPTION");
                field_num2 = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"COMMENT");

                if (field_num1 >= 0 && field_num2 >= 0)
                    // Note : We set field_num to the last "comment" field to avoid to concatenate
                    // the DESCRIPTION and COMMENT field if there are both present (EasyTAG writes the both...)
                    if (field_num1 < field_num2)
                        field_num = field_num2;
                    else
                        field_num = field_num1;
                else if (field_num1 >= 0)
                    field_num = field_num1;
                else if (field_num2 >= 0)
                    field_num = field_num2;
                else
                    break;

                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->comment==NULL)
                            FileTag->comment = g_strdup(field_value);
                        else
                            FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /************
             * Composer *
             ************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"COMPOSER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->composer==NULL)
                            FileTag->composer = g_strdup(field_value);
                        else
                            FileTag->composer = g_strconcat(FileTag->composer,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*******************
             * Original artist *
             *******************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"PERFORMER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->orig_artist==NULL)
                            FileTag->orig_artist = g_strdup(field_value);
                        else
                            FileTag->orig_artist = g_strconcat(FileTag->orig_artist,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*************
             * Copyright *
             *************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"COPYRIGHT")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->copyright==NULL)
                            FileTag->copyright = g_strdup(field_value);
                        else
                            FileTag->copyright = g_strconcat(FileTag->copyright,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*******
             * URL *
             *******/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"LICENSE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->url==NULL)
                            FileTag->url = g_strdup(field_value);
                        else
                            FileTag->url = g_strconcat(FileTag->url,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /**************
             * Encoded by *
             **************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"ENCODED-BY")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->encoded_by==NULL)
                            FileTag->encoded_by = g_strdup(field_value);
                        else
                            FileTag->encoded_by = g_strconcat(FileTag->encoded_by,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /***************************
             * Save unsupported fields *
             ***************************/
            for (i=0; i<(guint)vc->num_comments; i++)
            {
                field = &vc->comments[i];
                if ( strncasecmp((gchar *)field->entry,"TITLE=",       MIN(6,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"ARTIST=",      MIN(7,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"ALBUM=",       MIN(6,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"DISCNUMBER=",  MIN(11, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"DATE=",        MIN(5,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"TRACKNUMBER=", MIN(12, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"TRACKTOTAL=",  MIN(11, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"GENRE=",       MIN(6,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"DESCRIPTION=", MIN(12, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"COMMENT=",     MIN(8,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"COMPOSER=",    MIN(9,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"PERFORMER=",   MIN(10, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"COPYRIGHT=",   MIN(10, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"LICENSE=",     MIN(8,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"ENCODED-BY=",  MIN(11, field->length)) != 0 )
                {
                    //g_print("custom %*s\n", field->length, field->entry);
                    FileTag->other = g_list_append(FileTag->other,g_strndup((const gchar *)field->entry, field->length));
                }
            }

            break;
        }


            //
            // Read the PICTURE block (severals can exist)
            //
#ifndef LEGACY_FLAC // For FLAC >= 1.1.3
        case FLAC__METADATA_TYPE_PICTURE:
        {

            /***********
             * Picture *
             ***********/
            FLAC__StreamMetadata_Picture *p;
            Picture *pic;

            // Get picture data from block
            p = &block->data.picture;

            pic = Picture_Allocate();
            if (!prev_pic)
                FileTag->picture = pic;
            else
                prev_pic->next = pic;
            prev_pic = pic;

            pic->size = p->data_length;
            pic->data = g_memdup(p->data,pic->size);
            pic->type = p->type;
            pic->description = g_strdup((gchar *)p->description);
            // Not necessary: will be calculated later
            //pic->height = p->height;
            //pic->width  = p->width;

            //g_print("Picture type : %s\n",FLAC__StreamMetadata_Picture_TypeString[p->type]);
            //g_print("Mime    type : %s\n",p->mime_type);

            break;
        }
#endif

        default:
            break;
        }

        // Free block data
        //FLAC__metadata_object_delete(block);
    }

    // Free iter
    FLAC__metadata_simple_iterator_delete(iter);


#ifdef ENABLE_MP3
    /* If no FLAC vorbis tag found : we try to get the ID3 tag if it exists
     * (but it will be deleted when rewriting the tag) */
    if ( FileTag->title       == NULL
            && FileTag->artist      == NULL
            && FileTag->album       == NULL
            && FileTag->disc_number == NULL
            && FileTag->year        == NULL
            && FileTag->track       == NULL
            && FileTag->track_total == NULL
            && FileTag->genre       == NULL
            && FileTag->comment     == NULL
            && FileTag->composer    == NULL
            && FileTag->orig_artist == NULL
            && FileTag->copyright   == NULL
            && FileTag->url         == NULL
            && FileTag->encoded_by  == NULL
            && FileTag->picture     == NULL)
    {
        gint rc = Id3tag_Read_File_Tag(filename,FileTag);

        // If an ID3 tag has been found (and no FLAC tag), we mark the file as
        // unsaved to rewrite a flac tag.
        if ( FileTag->title       != NULL
                || FileTag->artist      != NULL
                || FileTag->album       != NULL
                || FileTag->disc_number != NULL
                || FileTag->year        != NULL
                || FileTag->track       != NULL
                || FileTag->track_total != NULL
                || FileTag->genre       != NULL
                || FileTag->comment     != NULL
                || FileTag->composer    != NULL
                || FileTag->orig_artist != NULL
                || FileTag->copyright   != NULL
                || FileTag->url         != NULL
                || FileTag->encoded_by  != NULL
                || FileTag->picture     != NULL)
        {
            FileTag->saved = FALSE;
        }

        g_free(filename_utf8);
        return rc;
    }

    /* Part to get cover artist :
     * If we have read the ID3 tag previously we don't arrive here (and we have
     * the picture if it exists).
     * Else the ID3 tag wasn't read (as there was data in FLAC tag) so we try
     * to read it only to get the picture (not supported by the FLAC tag). */
    /***if (WRITE_ID3_TAGS_IN_FLAC_FILE && FileTag->picture == NULL)
    {
        File_Tag *FileTag_tmp = ET_File_Tag_Item_New();
        gint rc = Id3tag_Read_File_Tag(filename,FileTag_tmp);
        if (rc && FileTag_tmp->picture)
        {
            // Copy picture to FileTag
            FileTag->picture = Picture_Copy(FileTag_tmp->picture);
        }

        ET_Free_File_Tag_Item(FileTag_tmp);

        return rc;
    }***/
#endif

    g_free(filename_utf8);
    return TRUE;
}
示例#5
0
文件: ogg_tag.c 项目: EQ4/easytag
/*
 * Read tag data into an Ogg Vorbis file.
 * Note:
 *  - if field is found but contains no info (strlen(str)==0), we don't read it
 */
gboolean Ogg_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    FILE           *file;
    vcedit_state   *state;
    vorbis_comment *vc;
    gchar          *string = NULL;
    gchar          *string1 = NULL;
    gchar          *string2 = NULL;
    gchar          *filename_utf8 = filename_to_display(filename);
    guint           field_num, i;
    Picture        *prev_pic = NULL;


    if (!filename || !FileTag)
        return FALSE;

    ogg_error_msg = NULL;

    if ( (file=fopen(filename,"rb")) == NULL )
    {
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }

    {
    // Skip the id3v2 tag
    guchar tmp_id3[4];
    gulong id3v2size;

    // Check if there is an ID3v2 tag...
    fseek(file, 0L, SEEK_SET);
    if (fread(tmp_id3, 1, 4, file) == 4)
    {
        // Calculate ID3v2 length
        if (tmp_id3[0] == 'I' && tmp_id3[1] == 'D' && tmp_id3[2] == '3' && tmp_id3[3] < 0xFF)
        {
            // id3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size]
            fseek(file, 2, SEEK_CUR); // Size is 6-9 position
            if (fread(tmp_id3, 1, 4, file) == 4)
            {
                id3v2size = 10 + ( (long)(tmp_id3[3])        | ((long)(tmp_id3[2]) << 7)
                                | ((long)(tmp_id3[1]) << 14) | ((long)(tmp_id3[0]) << 21) );
                fseek(file, id3v2size, SEEK_SET);
                Log_Print(LOG_ERROR,_("Warning : The Ogg Vorbis file '%s' contains an ID3v2 tag."),filename_utf8);
            }else
            {
                fseek(file, 0L, SEEK_SET);
            }
        }else
        {
            fseek(file, 0L, SEEK_SET);
        }
    }else
    {
        fseek(file, 0L, SEEK_SET);
    }
    }

    state = vcedit_new_state();    // Allocate memory for 'state'
    if ( vcedit_open(state,file) < 0 )
    {
        Log_Print(LOG_ERROR,_("ERROR: Failed to open file: '%s' as vorbis (%s)."),filename_utf8,vcedit_error(state));
        ogg_error_msg = vcedit_error(state);
        fclose(file);
        g_free(filename_utf8);
        vcedit_clear(state);
        return FALSE;
    }


    /* Get data from tag */
    vc = vcedit_comments(state);
    /*{
        gint i; 
        for (i=0;i<vc->comments;i++) 
            g_print("%s -> Ogg vc:'%s'\n",g_path_get_basename(filename),vc->user_comments[i]);
    }*/

    /*********
     * Title *
     *********/
    /* Note : don't forget to add any new field to 'Save unsupported fields' */
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"TITLE",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->title==NULL)
                FileTag->title = g_strdup(string);
            else
                FileTag->title = g_strconcat(FileTag->title,MULTIFIELD_SEPARATOR,string,NULL);
            // If strlen = 0, then no allocated data!
        }

        g_free(string);
    }

    /**********
     * Artist *
     **********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ARTIST",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->artist==NULL)
                FileTag->artist = g_strdup(string);
            else
                FileTag->artist = g_strconcat(FileTag->artist,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /****************
     * Album Artist *
     ****************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ALBUMARTIST",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->album_artist==NULL)
                FileTag->album_artist = g_strdup(string);
            else
                FileTag->album_artist = g_strconcat(FileTag->album_artist,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*********
     * Album *
     *********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ALBUM",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->album==NULL)
                FileTag->album = g_strdup(string);
            else
                FileTag->album = g_strconcat(FileTag->album,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*******************************
     * Disc Number (Part of a Set) *
     *******************************/
    if ( (string = vorbis_comment_query(vc,"DISCNUMBER",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        FileTag->disc_number = g_strdup(string);
    }

    /********
     * Year *
     ********/
    if ( (string = vorbis_comment_query(vc,"DATE",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        FileTag->year = g_strdup(string);
        if (g_utf8_strlen(FileTag->year, -1) > 4)
            Log_Print(LOG_WARNING,_("The year value '%s' seems to be invalid in file '%s'. The information will be lost while saving tag."),FileTag->year,filename_utf8);
    }

    /*************************
     * Track and Total Track *
     *************************/
    if ( (string = vorbis_comment_query(vc,"TRACKNUMBER",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        if (NUMBER_TRACK_FORMATED)
        {
            // Ckeck if TRACKTOTAL used, else takes it in TRACKNUMBER
            if ( (string1 = vorbis_comment_query(vc,"TRACKTOTAL",0)) != NULL && g_utf8_strlen(string1, -1) > 0 )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1));
            }else
            if ( (string1 = g_utf8_strchr(string, -1, '/')) )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1+1));
                *string1 = '\0';
            }
            FileTag->track = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string));
        }else
        {
            // Ckeck if TRACKTOTAL used, else takes it in TRACKNUMBER
            if ( (string1 = vorbis_comment_query(vc,"TRACKTOTAL",0)) != NULL && g_utf8_strlen(string1, -1) > 0 )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1));
            }else
            if ( (string1 = g_utf8_strchr(string, -1, '/')) )
            {
                FileTag->track_total = g_strdup(string1+1);
                *string1 = '\0';
            }
            FileTag->track = g_strdup(string);
        }
    }

    /*********
     * Genre *
     *********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"GENRE",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->genre==NULL)
                FileTag->genre = g_strdup(string);
            else
                FileTag->genre = g_strconcat(FileTag->genre,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /***********
     * Comment *
     ***********/
    field_num = 0;
    string1 = NULL; // Cause it may be not updated into the 'while' condition
    while ( ((string2 = vorbis_comment_query(vc,"DESCRIPTION",field_num)) != NULL )   // New specifications
         || ((string  = vorbis_comment_query(vc,"COMMENT",    field_num)) != NULL )   // Old : Winamp format (for EasyTAG 1.99.11 and older)
         || ((string1 = vorbis_comment_query(vc,"",           field_num)) != NULL ) ) // Old : Xmms format   (for EasyTAG 1.99.11 and older)
    {
        string  = Try_To_Validate_Utf8_String(string);
        string1 = Try_To_Validate_Utf8_String(string1);
        string2 = Try_To_Validate_Utf8_String(string2);

        if ( string2 && g_utf8_strlen(string2, -1) > 0 ) // Contains comment to new specifications format and we prefer this format (field name defined)
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string2);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string2,NULL);

            // Frees allocated data
            if (string && g_utf8_strlen(string, -1) > 0)
                g_free(string);
            if (string1 && g_utf8_strlen(string1, -1) > 0)
                g_free(string1);
        }else if ( string && g_utf8_strlen(string, -1) > 0 ) // Contains comment to Winamp format and we prefer this format (field name defined)
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string,NULL);

            // Frees allocated data
            if (string1 && g_utf8_strlen(string1, -1) > 0)
                g_free(string1);
        }else if ( string1 && g_utf8_strlen(string1, -1) > 0 ) // Contains comment to Xmms format only
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string1);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string1,NULL);
        }

        g_free(string);
        g_free(string1);
        g_free(string2);

        string  = NULL;
        string1 = NULL;
        field_num++;
    }

    /************
     * Composer *
     ************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COMPOSER",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->composer==NULL)
                FileTag->composer = g_strdup(string);
            else
                FileTag->composer = g_strconcat(FileTag->composer,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*******************
     * Original artist *
     *******************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"PERFORMER",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->orig_artist==NULL)
                FileTag->orig_artist = g_strdup(string);
            else
                FileTag->orig_artist = g_strconcat(FileTag->orig_artist,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*************
     * Copyright *
     *************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COPYRIGHT",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->copyright==NULL)
                FileTag->copyright = g_strdup(string);
            else
                FileTag->copyright = g_strconcat(FileTag->copyright,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*******
     * URL *
     *******/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"LICENSE",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->url==NULL)
                FileTag->url = g_strdup(string);
            else
                FileTag->url = g_strconcat(FileTag->url,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /**************
     * Encoded by *
     **************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ENCODED-BY",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->encoded_by==NULL)
                FileTag->encoded_by = g_strdup(string);
            else
                FileTag->encoded_by = g_strconcat(FileTag->encoded_by,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }


    /**************
     * Picture    *
     **************/
    /* Non officials tags used for picture information:
     *  - COVERART            : contains the picture data
     *  - COVERARTTYPE        : cover front, ...
     *  - COVERARTDESCRIPTION : information set by user
     *  - COVERARTMIME        : image/jpeg or image/png (written only)
     */
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COVERART",field_num++)) != NULL )
    {
        gchar *data;
        gint size;
        Picture *pic;
            
        pic = Picture_Allocate();
        if (!prev_pic)
            FileTag->picture = pic;
        else
            prev_pic->next = pic;
        prev_pic = pic;

        pic->data = NULL;
        
        // Decode picture data
        data = g_strdup(string);
        size = base64_decode(string, data);
        if ( data && (pic->data = g_memdup(data, size)) )
            pic->size = size;
        g_free(data);

        if ( (string = vorbis_comment_query(vc,"COVERARTTYPE",field_num-1)) != NULL )
        {
            pic->type = atoi(string);
        }

        if ( (string = vorbis_comment_query(vc,"COVERARTDESCRIPTION",field_num-1)) != NULL )
        {
            pic->description = g_strdup(string);
        }

        //if ((string = vorbis_comment_query(vc,"COVERTARTMIME",field_num-1)) != NULL )
        //{
        //    pic->description = g_strdup(string);
        //}

    }


    /***************************
     * Save unsupported fields *
     ***************************/
    for (i=0;i<(guint)vc->comments;i++)
    {
        if ( strncasecmp(vc->user_comments[i],"TITLE=",            6) != 0
          && strncasecmp(vc->user_comments[i],"ARTIST=",           7) != 0
          && strncasecmp(vc->user_comments[i],"ALBUMARTIST=",     12) != 0
          && strncasecmp(vc->user_comments[i],"ALBUM=",            6) != 0
          && strncasecmp(vc->user_comments[i],"DISCNUMBER=",      11) != 0
          && strncasecmp(vc->user_comments[i],"DATE=",             5) != 0
          && strncasecmp(vc->user_comments[i],"TRACKNUMBER=",     12) != 0
          && strncasecmp(vc->user_comments[i],"TRACKTOTAL=",      11) != 0
          && strncasecmp(vc->user_comments[i],"GENRE=",            6) != 0
          && strncasecmp(vc->user_comments[i],"DESCRIPTION=",     12) != 0
          && strncasecmp(vc->user_comments[i],"COMMENT=",          8) != 0
          && strncasecmp(vc->user_comments[i],"=",                 1) != 0
          && strncasecmp(vc->user_comments[i],"COMPOSER=",         9) != 0
          && strncasecmp(vc->user_comments[i],"PERFORMER=",       10) != 0
          && strncasecmp(vc->user_comments[i],"COPYRIGHT=",       10) != 0
          && strncasecmp(vc->user_comments[i],"LICENSE=",          8) != 0
          && strncasecmp(vc->user_comments[i],"ENCODED-BY=",      11) != 0
          && strncasecmp(vc->user_comments[i],"COVERART=",         9) != 0
          && strncasecmp(vc->user_comments[i],"COVERARTTYPE=",       13) != 0
          && strncasecmp(vc->user_comments[i],"COVERARTMIME=",       13) != 0
          && strncasecmp(vc->user_comments[i],"COVERARTDESCRIPTION=",20) != 0
           )
        {
            FileTag->other = g_list_append(FileTag->other,
                                           Try_To_Validate_Utf8_String(vc->user_comments[i]));
        }
    }

    vcedit_clear(state);
    fclose(file);
    g_free(filename_utf8);

    return TRUE;
}
示例#6
0
文件: mpeg_header.c 项目: EQ4/easytag
/*
 * Read infos into header of first frame
 */
gboolean Mpeg_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
{
#if (!USE_ID3LIB_4_HEADER)
    FILE *file;
    gulong filesize;


    if (!filename || !ETFileInfo)
        return FALSE;

    /* Get size of file */
    filesize         = Get_File_Size(filename);
    ETFileInfo->size = filesize;


    /*
     * This part was taken from XMMS
     */
    if ((file = fopen(filename, "rb")) != NULL)
    {
        guint32 head;
        unsigned char tmp[4];
        struct frame frm;
        gboolean id3_found = FALSE;

        if (fread(tmp, 1, 4, file) != 4)
        {
            fclose(file);
            return FALSE;
        }

        // Skip data of the ID3v2.x tag (It may contain data similar to mpeg frame 
        // as, for example, in the id3 APIC frame) (patch from Artur Polaczynski)
        if (tmp[0] == 'I' && tmp[1] == 'D' && tmp[2] == '3' && tmp[3] < 0xFF)
        {
            // ID3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size]
            long id3v2size;
            fseek(file, 2, SEEK_CUR); // Size is 6-9 position
            if (fread(tmp, 1, 4, file) != 4) // Read bytes of tag size
            {
                fclose(file);
                return FALSE;
            }
            id3v2size = 10 + ( (long)(tmp[3]) | ((long)(tmp[2]) << 7) | ((long)(tmp[1]) << 14) | ((long)(tmp[0]) << 21) );
            fseek(file, id3v2size, SEEK_SET);
            if (fread(tmp, 1, 4, file) != 4) // Read mpeg header
            {
                fclose(file);
                return FALSE;
            }
        }

        head = ((guint32) tmp[0] << 24) | ((guint32) tmp[1] << 16) | ((guint32) tmp[2] << 8) | (guint32) tmp[3];
        while (!mpg123_head_check(head))
        {
            head <<= 8;
            if (fread(tmp, 1, 1, file) != 1)
            {
                fclose(file);
                return FALSE;
            }
            head |= tmp[0];
        }
        if (mpg123_decode_header(&frm, head))
        {
            guchar *buf;
            gdouble tpf;
            gint pos;
            XHEADDATA xing_header;
            guint32 num_frames;

            buf = g_malloc(frm.framesize + 4);
            fseek(file, -4, SEEK_CUR);
            fread(buf, 1, frm.framesize + 4, file);
            xing_header.toc = NULL;
            tpf = mpg123_compute_tpf(&frm);
            // MPEG and Layer version
            ETFileInfo->mpeg25 = frm.mpeg25;
            if (!ETFileInfo->mpeg25)
                ETFileInfo->version = frm.lsf+1;
            ETFileInfo->layer = frm.lay;
            //if (ETFileInfo->mpeg25) g_print("mpeg_level: MPEG 2.5, layer %d\n",ETFileInfo->layer);
            //else                    g_print("mpeg_level: MPEG %d, layer %d\n",ETFileInfo->version,ETFileInfo->layer);

            pos = ftell(file);
            fseek(file, 0, SEEK_END);
            // Variable bitrate? + bitrate
            if ( (ETFileInfo->variable_bitrate=mpg123_get_xing_header(&xing_header,buf)) )
            {
                num_frames = xing_header.frames;
                ETFileInfo->bitrate = (gint) ((xing_header.bytes * 8) / (tpf * xing_header.frames * 1000));
                //g_print("Bitrate: Variable,\navg. bitrate: %d kb/s\n",ETFileInfo->bitrate);
            } else
            {
                num_frames = ((ftell(file) - pos - (id3_found ? 128 : 0)) / mpg123_compute_bpf(&frm)) + 1;
                ETFileInfo->bitrate = tabsel_123[frm.lsf][frm.lay - 1][frm.bitrate_index];
                //g_print("Bitrate: %d kb/s\n",ETFileInfo->bitrate);
            }
            // Samplerate
            ETFileInfo->samplerate = mpg123_freqs[frm.sampling_frequency];
            // Mode
            ETFileInfo->mode = frm.mode;
            //g_print("Samplerate: %ld Hz\n", mpg123_freqs[frm.sampling_frequency]);
            //g_print("%s\nError protection: %s\nCopyright: %s\nOriginal: %s\nEmphasis: %s\n", channel_mode_name(frm.mode), bool_label[frm.error_protection], bool_label[frm.copyright], bool_label[frm.original], emphasis[frm.emphasis]);
            //g_print("%d frames\nFilesize: %lu B\n", num_frames, ftell(file));
            g_free(buf);
        }

        // Duration
        ETFileInfo->duration = mpg123_get_song_time(file)/1000;
        //g_print("time %s\n",Convert_Duration(ETFileInfo->duration));

        fclose(file);
    }else
    {
        gchar *filename_utf8 = filename_to_display(filename);
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }

#else
    // Needs to uncomment some #include at the beginning

    /*
     * With id3lib, the header frame couldn't be read if the file contains an ID3v2 tag with an APIC frame
     */
    gulong filesize;
    ID3Tag *id3_tag = NULL;    /* Tag defined by the id3lib */
    const Mp3_Headerinfo* headerInfo = NULL;


    if (!filename || !ETFileInfo)
        return FALSE;

    /* Get size of file */
    filesize         = Get_File_Size(filename);
    ETFileInfo->size = filesize;

    /* Get data from tag */
    if ( (id3_tag = ID3Tag_New()) == NULL )
        return FALSE;

    /* Link the file to the tag (uses ID3TT_ID3V2 to get header if APIC is present in Tag) */
    ID3Tag_LinkWithFlags(id3_tag,filename,ID3TT_ID3V2);

    /*ID3_STRUCT(Mp3_Headerinfo)
    {
      Mpeg_Layers layer;
      Mpeg_Version version;
      MP3_BitRates bitrate;
      Mp3_ChannelMode channelmode;
      Mp3_ModeExt modeext;
      Mp3_Emphasis emphasis;
      Mp3_Crc crc;
      uint32 vbr_bitrate;           // avg bitrate from xing header
      uint32 frequency;             // samplerate
      uint32 framesize;
      uint32 frames;                // nr of frames
      uint32 time;                  // nr of seconds in song
      bool privatebit;
      bool copyrighted;
      bool original;
    };*/

    if ( (headerInfo = ID3Tag_GetMp3HeaderInfo(id3_tag)) )
    {
        switch (headerInfo->version)
        {
            case MPEGVERSION_1:
                ETFileInfo->version = 1;
                ETFileInfo->mpeg25 = FALSE;
                break;
            case MPEGVERSION_2:
                ETFileInfo->version = 2;
                ETFileInfo->mpeg25 = FALSE;
                break;
            case MPEGVERSION_2_5:
                ETFileInfo->mpeg25 = TRUE;
                ETFileInfo->mpeg25 = FALSE;
                break;
            default:
                break;
        }

        switch (headerInfo->layer)
        {
            case MPEGLAYER_I:
                ETFileInfo->layer = 1;
                break;
            case MPEGLAYER_II:
                ETFileInfo->layer = 2;
                break;
            case MPEGLAYER_III:
                ETFileInfo->layer = 3;
                break;
            default:
                break;
        }

        // Samplerate
        ETFileInfo->samplerate = headerInfo->frequency;

        // Mode -> Seems to be detected but incorrect?!
        switch (headerInfo->modeext)
        {
            case MP3CHANNELMODE_STEREO:
                ETFileInfo->mode = 0;
                break;
            case MP3CHANNELMODE_JOINT_STEREO:
                ETFileInfo->mode = 1;
                break;
            case MP3CHANNELMODE_DUAL_CHANNEL:
                ETFileInfo->mode = 2;
                break;
            case MP3CHANNELMODE_SINGLE_CHANNEL:
                ETFileInfo->mode = 3;
                break;
            default:
                break;
        }

        // Bitrate
        if (headerInfo->vbr_bitrate <= 0)
        {
            ETFileInfo->variable_bitrate = FALSE;
            ETFileInfo->bitrate = headerInfo->bitrate/1000;
        }else
        {
            ETFileInfo->variable_bitrate = TRUE;
            ETFileInfo->bitrate = headerInfo->vbr_bitrate/1000;
        }

        // Duration
        ETFileInfo->duration = headerInfo->time;
    }

    /* Free allocated data */
    ID3Tag_Delete(id3_tag);

#endif

    return TRUE;
}
示例#7
0
文件: mp4_tag.c 项目: EQ4/easytag
/*
 * Mp4_Tag_Read_File_Tag:
 *
 * Read tag data into an Mp4 file.
 *
 * Note:
 *  - for string fields, //if field is found but contains no info (strlen(str)==0), we don't read it
 *  - for track numbers, if they are zero, then we don't read it
 */
gboolean Mp4tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    FILE   *file;
    TagLib_File *mp4file;
    TagLib_Tag *tag;
    guint track;

    if (!filename || !FileTag)
        return FALSE;

    if ( (file=fopen(filename,"r"))==NULL )
    {
        gchar *filename_utf8 = filename_to_display(filename);
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }
    fclose(file); // We close it cause mp4 opens/closes file itself

    /* Get data from tag */
    mp4file = taglib_file_new_type(filename,TagLib_File_MP4);
    if (mp4file == NULL)
    {
        gchar *filename_utf8 = filename_to_display(filename);
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,_("MP4 format invalid"));
        g_free(filename_utf8);
        return FALSE;
    }

    /* TODO Add error detection */
    tag = taglib_file_tag(mp4file);

    /*********
     * Title *
     *********/
    FileTag->title = g_strdup(taglib_tag_title(tag));

    /**********
     * Artist *
     **********/
    FileTag->artist = g_strdup(taglib_tag_artist(tag));

    /*********
     * Album *
     *********/
    FileTag->album = g_strdup(taglib_tag_album(tag));

    /****************
     * Album Artist *
     ****************/
    /* TODO: No album artist or disc number support in the TagLib C API! */

    /********
     * Year *
     ********/
    FileTag->year = g_strdup_printf("%u", taglib_tag_year(tag));

    /*************************
     * Track and Total Track *
     *************************/
    track = taglib_tag_track(tag);

    if (track != 0)
        FileTag->track = NUMBER_TRACK_FORMATED ? g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,(gint)track) : g_strdup_printf("%d",(gint)track);
    /* TODO: No total track support in the TagLib C API! */

    /*********
     * Genre *
     *********/
    FileTag->genre = g_strdup(taglib_tag_genre(tag));

    /***********
     * Comment *
     ***********/
    FileTag->comment = g_strdup(taglib_tag_comment(tag));

    /**********************
     * Composer or Writer *
     **********************/
    /* TODO: No composer support in the TagLib C API! */

    /*****************
     * Encoding Tool *
     *****************/
    /* TODO: No encode_by support in the TagLib C API! */

    /***********
     * Picture *
     ***********/
    /* TODO: No encode_by support in the TagLib C API! */

    /* Free allocated data */
    taglib_tag_free_strings();
    taglib_file_free(mp4file);

    return TRUE;
}