Exemple #1
0
static void decode_rva (Tuple * tuple, const guchar * data, gint size)
{
    const gchar * domain;
    gint channel, adjustment, adjustment_unit, peak, peak_unit;

    if (memchr (data, 0, size) == NULL)
        return;

    domain = (const gchar *) data;

    TAGDBG ("RVA domain: %s\n", domain);

    size -= strlen (domain) + 1;
    data += strlen (domain) + 1;

    while (size > 0)
    {
        if (! decode_rva_block (& data, & size, & channel, & adjustment,
         & adjustment_unit, & peak, & peak_unit))
            break;

        if (channel != 1) /* specific channel? */
            continue;

        if (tuple_get_value_type (tuple, FIELD_GAIN_GAIN_UNIT, NULL) ==
         TUPLE_INT)
            adjustment = adjustment * (gint64) tuple_get_int (tuple,
             FIELD_GAIN_GAIN_UNIT, NULL) / adjustment_unit;
        else
            tuple_associate_int (tuple, FIELD_GAIN_GAIN_UNIT, NULL,
             adjustment_unit);

        if (peak_unit)
        {
            if (tuple_get_value_type (tuple, FIELD_GAIN_PEAK_UNIT, NULL) ==
             TUPLE_INT)
                peak = peak * (gint64) tuple_get_int (tuple,
                 FIELD_GAIN_PEAK_UNIT, NULL) / peak_unit;
            else
                tuple_associate_int (tuple, FIELD_GAIN_PEAK_UNIT, NULL,
                 peak_unit);
        }

        if (! strcasecmp (domain, "album"))
        {
            tuple_associate_int (tuple, FIELD_GAIN_ALBUM_GAIN, NULL, adjustment);

            if (peak_unit)
                tuple_associate_int (tuple, FIELD_GAIN_ALBUM_PEAK, NULL, peak);
        }
        else if (! strcasecmp (domain, "track"))
        {
            tuple_associate_int (tuple, FIELD_GAIN_TRACK_GAIN, NULL, adjustment);

            if (peak_unit)
                tuple_associate_int (tuple, FIELD_GAIN_TRACK_PEAK, NULL, peak);
        }
    }
}
Exemple #2
0
static int tuple_compare_int (const Tuple * a, const Tuple * b, int field)
{
    if (tuple_get_value_type (a, field, NULL) != TUPLE_INT)
        return (tuple_get_value_type (b, field, NULL) != TUPLE_INT) ? 0 : -1;
    if (tuple_get_value_type (b, field, NULL) != TUPLE_INT)
        return 1;

    int int_a = tuple_get_int (a, field, NULL);
    int int_b = tuple_get_int (b, field, NULL);

    return (int_a < int_b) ? -1 : (int_a > int_b);
}
Exemple #3
0
static void insert_vorbis_comment (FLAC__StreamMetadata * meta,
 const char * name, const Tuple * tuple, int field)
{
    TupleValueType type = tuple_field_get_type (field);
    if (tuple_get_value_type (tuple, field, NULL) != type)
        return;

    char * temp;

    switch (type)
    {
    case TUPLE_INT:;
        int ival = tuple_get_int (tuple, field, NULL);
        temp = g_strdup_printf ("%s=%d", name, ival);
        break;
    case TUPLE_STRING:;
        char * sval = tuple_get_str (tuple, field, NULL);
        temp = g_strdup_printf ("%s=%s", name, sval);
        str_unref (sval);
    default:
        return;
    }

    FLAC__StreamMetadata_VorbisComment_Entry comment;
    comment.length = strlen (temp);
    comment.entry = (unsigned char *) temp;

    FLAC__metadata_object_vorbiscomment_insert_comment (meta,
     meta->data.vorbis_comment.num_comments, comment, TRUE);

    g_free (temp);
}
/* builtin-keyword: ${(empty)?}. returns TRUE if <arg> is empty. */
static gboolean
tuple_formatter_expression_empty(Tuple *tuple, const gchar *expression)
{
    gboolean ret = TRUE;
    const gchar *iter;
    TupleValueType type = tuple_get_value_type(tuple, -1, expression);

    if (type == TUPLE_UNKNOWN)
        return TRUE;

    if (type == TUPLE_INT)
        return (tuple_get_int(tuple, -1, expression) == 0);

    iter = tuple_get_string(tuple, -1, expression);
    if (!iter)
        return TRUE;

    while (ret && *iter != '\0')
    {
        if (*iter == ' ')
            iter++;
        else
            ret = FALSE;
    }

    return ret;
}
Exemple #5
0
static bool_t audpl_save (const char * path, VFSFile * file,
 const char * title, Index * filenames, Index * tuples)
{
    if (! write_key (file, "title", title))
        return FALSE;

    int count = index_count (filenames);

    for (int i = 0; i < count; i ++)
    {
        if (! write_key (file, "uri", index_get (filenames, i)))
            return FALSE;

        const Tuple * tuple = tuples ? index_get (tuples, i) : NULL;

        if (tuple)
        {
            int keys = 0;

            for (int f = 0; f < TUPLE_FIELDS; f ++)
            {
                if (f == FIELD_FILE_PATH || f == FIELD_FILE_NAME || f == FIELD_FILE_EXT)
                    continue;

                TupleValueType type = tuple_get_value_type (tuple, f, NULL);

                if (type == TUPLE_STRING)
                {
                    char * str = tuple_get_str (tuple, f, NULL);

                    if (! write_key (file, tuple_field_get_name (f), str))
                    {
                        str_unref (str);
                        return FALSE;
                    }

                    str_unref (str);
                    keys ++;
                }
                else if (type == TUPLE_INT)
                {
                    char buf[32];
                    snprintf (buf, sizeof buf, "%d", tuple_get_int (tuple, f, NULL));

                    if (! write_key (file, tuple_field_get_name (f), buf))
                        return FALSE;

                    keys ++;
                }
            }

            /* distinguish between an empty tuple and no tuple at all */
            if (! keys && ! write_key (file, "empty", "1"))
                return FALSE;
        }
    }

    return TRUE;
}
Exemple #6
0
static void set_gain_info(Tuple *tuple, int field, int unit_field, const char *text)
{
    int value, unit;

    parse_gain_text(text, &value, &unit);

    if (tuple_get_value_type(tuple, unit_field, NULL) == TUPLE_INT)
        value = value * (int64_t) tuple_get_int(tuple, unit_field, NULL) / unit;
    else
        tuple_set_int(tuple, unit_field, NULL, unit);

    tuple_set_int(tuple, field, NULL, value);
}
Exemple #7
0
static void add_frameFromTupleInt (const Tuple * tuple, int field, int
 id3_field, GHashTable * dict)
{
    if (tuple_get_value_type (tuple, field) != TUPLE_INT)
    {
        remove_frame (id3_field, dict);
        return;
    }

    char scratch[16];
    str_itoa (tuple_get_int (tuple, field), scratch, sizeof scratch);
    add_text_frame (id3_field, scratch, dict);
}
Exemple #8
0
static void add_frameFromTupleInt (const Tuple * tuple, gint field, gint
 id3_field, mowgli_dictionary_t * dict)
{
    if (tuple_get_value_type (tuple, field, NULL) != TUPLE_INT)
    {
        remove_frame (id3_field, dict);
        return;
    }

    gchar scratch[16];
    snprintf (scratch, sizeof scratch, "%d", tuple_get_int (tuple, field, NULL));
    add_text_frame (id3_field, scratch, dict);
}
Exemple #9
0
static void set_entry_int_from_field (GtkWidget * widget, const Tuple * tuple,
 int fieldn, bool_t editable)
{
    char scratch[32];

    if (tuple_get_value_type (tuple, fieldn, NULL) == TUPLE_INT)
        snprintf (scratch, sizeof scratch, "%d", tuple_get_int (tuple, fieldn,
         NULL));
    else
        scratch[0] = 0;

    gtk_entry_set_text ((GtkEntry *) widget, scratch);
    gtk_editable_set_editable ((GtkEditable *) widget, editable);
}
Exemple #10
0
static void infowin_show (gint list, gint entry, const gchar * filename,
 const Tuple * tuple, PluginHandle * decoder, gboolean updating_enabled)
{
    gchar * tmp;

    if (infowin == NULL)
        create_infowin ();
    else
        clear_infowin ();

    current_file = g_strdup (filename);
    current_decoder = decoder;
    can_write = updating_enabled;

    set_entry_str_from_field (entry_title, tuple, FIELD_TITLE, updating_enabled);
    set_entry_str_from_field (entry_artist, tuple, FIELD_ARTIST,
     updating_enabled);
    set_entry_str_from_field (entry_album, tuple, FIELD_ALBUM, updating_enabled);
    set_entry_str_from_field (entry_comment, tuple, FIELD_COMMENT,
     updating_enabled);
    set_entry_str_from_field (gtk_bin_get_child ((GtkBin *) entry_genre), tuple,
     FIELD_GENRE, updating_enabled);

    tmp = uri_to_display (filename);
    gtk_label_set_text ((GtkLabel *) location_text, tmp);
    g_free (tmp);

    set_entry_int_from_field (entry_year, tuple, FIELD_YEAR, updating_enabled);
    set_entry_int_from_field (entry_track, tuple, FIELD_TRACK_NUMBER,
     updating_enabled);

    infowin_label_set_text (label_format_name, tuple_get_string (tuple,
     FIELD_CODEC, NULL));
    infowin_label_set_text (label_quality, tuple_get_string (tuple,
     FIELD_QUALITY, NULL));

    if (tuple_get_value_type (tuple, FIELD_BITRATE, NULL) == TUPLE_INT)
    {
        tmp = g_strdup_printf (_("%d kb/s"), tuple_get_int (tuple,
         FIELD_BITRATE, NULL));
        infowin_label_set_text (label_bitrate, tmp);
        g_free (tmp);
    }
    else
        infowin_label_set_text (label_bitrate, NULL);

    infowin_entry_set_image (image_artwork, list, entry);

    gtk_window_present ((GtkWindow *) infowin);
}
/* processes an expression and optional argument pair. */
gchar *
tuple_formatter_process_expr(Tuple *tuple, const gchar *expression,
    const gchar *argument)
{
    TupleFormatterExpression *expr = NULL;
    GList *iter;

    g_return_val_if_fail(tuple != NULL, NULL);
    g_return_val_if_fail(expression != NULL, NULL);

    for (iter = tuple_formatter_expr_list; iter != NULL; iter = iter->next)
    {
        TupleFormatterExpression *tmp = (TupleFormatterExpression *) iter->data;

        if (g_str_has_prefix(expression, tmp->name) == TRUE)
        {
            expr = tmp;
            expression += strlen(tmp->name);
        }
    }

    /* ${artist} */
    if (expr == NULL && argument == NULL)
    {
        TupleValueType type = tuple_get_value_type(tuple, -1, expression);

        switch(type)
        {
        case TUPLE_STRING:
             return g_strdup(tuple_get_string(tuple, -1, expression));
             break;
        case TUPLE_INT:
             return g_strdup_printf("%d", tuple_get_int(tuple, -1, expression));
             break;
        case TUPLE_UNKNOWN:
        default:
             return NULL;
        }
    }
    else if (expr != NULL)
    {
        if (expr->func(tuple, expression) == TRUE && argument != NULL)
            return tuple_formatter_process_construct(tuple, argument);
    }

    return NULL;
}
Exemple #12
0
static GValue *tuple_value_to_gvalue(const Tuple * tuple, const gchar * key)
{
    GValue *val;
    TupleValueType type = tuple_get_value_type((Tuple *) tuple, -1, key);

    if (type == TUPLE_STRING)
    {
        val = g_new0(GValue, 1);
        g_value_init(val, G_TYPE_STRING);
        g_value_take_string(val, g_strdup(tuple_get_string((Tuple *) tuple, -1, key)));
        return val;
    }
    else if (type == TUPLE_INT)
    {
        val = g_new0(GValue, 1);
        g_value_init(val, G_TYPE_INT);
        g_value_set_int(val, tuple_get_int((Tuple *) tuple, -1, key));
        return val;
    }
    return NULL;
}
Exemple #13
0
static char * strdup_tuple_field (const Tuple * tuple, int field)
{
    char * sval, * dup;
    int ival;

    switch (tuple_get_value_type (tuple, field, NULL))
    {
    case TUPLE_INT:
        ival = tuple_get_int (tuple, field, NULL);
        dup = g_strdup_printf ("%d", ival);
        break;
    case TUPLE_STRING:
        sval = tuple_get_str (tuple, field, NULL);
        dup = g_strdup (sval);
        str_unref (sval);
        break;
    default:
        dup = NULL;
        break;
    }

    return dup;
}
Exemple #14
0
static gboolean xspf_playlist_save (const gchar * filename, VFSFile * file,
 const gchar * title, Index * filenames, Index * tuples)
{
    gint entries = index_count (filenames);
    xmlDocPtr doc;
    xmlNodePtr rootnode, tracklist;
    gint count;

    doc = xmlNewDoc((xmlChar *)"1.0");
    doc->charset = XML_CHAR_ENCODING_UTF8;
    doc->encoding = xmlStrdup((xmlChar *)"UTF-8");

    rootnode = xmlNewNode(NULL, (xmlChar *)XSPF_ROOT_NODE_NAME);
    xmlSetProp(rootnode, (xmlChar *)"version", (xmlChar *)"1");
    xmlSetProp(rootnode, (xmlChar *)"xmlns", (xmlChar *)XSPF_XMLNS);

    /* common */
    xmlDocSetRootElement(doc, rootnode);

    if (title)
        xspf_add_node (rootnode, TUPLE_STRING, FALSE, "title", title, 0);

    tracklist = xmlNewNode(NULL, (xmlChar *)"trackList");
    xmlAddChild(rootnode, tracklist);

    for (count = 0; count < entries; count ++)
    {
        const gchar * filename = index_get (filenames, count);
        const Tuple * tuple = index_get (tuples, count);
        xmlNodePtr track, location;
        gchar *scratch = NULL;
        gint scratchi = 0;

        track = xmlNewNode(NULL, (xmlChar *)"track");
        location = xmlNewNode(NULL, (xmlChar *)"location");

        xmlAddChild(location, xmlNewText((xmlChar *)filename));
        xmlAddChild(track, location);
        xmlAddChild(tracklist, track);

        if (tuple != NULL)
        {
            gint i;
            for (i = 0; i < xspf_nentries; i++) {
                const xspf_entry_t *xs = &xspf_entries[i];
                gboolean isOK = (tuple_get_value_type (tuple, xs->tupleField,
                 NULL) == xs->type);

                switch (xs->type) {
                    case TUPLE_STRING:
                        scratch = tuple_get_str (tuple, xs->tupleField, NULL);
                        if (! scratch)
                            isOK = FALSE;
                        str_unref(scratch);
                        break;
                    case TUPLE_INT:
                        scratchi = tuple_get_int (tuple, xs->tupleField, NULL);
                        break;
                    default:
                        break;
                }

                if (isOK)
                    xspf_add_node(track, xs->type, xs->isMeta, xs->xspfName, scratch, scratchi);
            }
        }
    }

    xmlSaveCtxt * save = xmlSaveToIO (write_cb, close_cb, file, NULL,
     XML_SAVE_FORMAT);
    if (! save)
        goto ERR;

    if (xmlSaveDoc (save, doc) < 0 || xmlSaveClose (save) < 0)
        goto ERR;

    xmlFreeDoc(doc);
    return TRUE;

ERR:
    xmlFreeDoc (doc);
    return FALSE;
}
Exemple #15
0
static bool_t playlist_load_cue (const char * cue_filename, VFSFile * file,
 char * * title, Index * filenames, Index * tuples)
{
    void * buffer = NULL;
    vfs_file_read_all (file, & buffer, NULL);
    if (! buffer)
        return FALSE;

    * title = NULL;

    Cd * cd = cue_parse_string (buffer);
    g_free (buffer);
    if (cd == NULL)
        return FALSE;

    int tracks = cd_get_ntrack (cd);
    if (tracks == 0)
        return FALSE;

    Track * current = cd_get_track (cd, 1);
    if (current == NULL)
        return FALSE;

    char * track_filename = track_get_filename (current);
    if (track_filename == NULL)
        return FALSE;

    char * filename = uri_construct (track_filename, cue_filename);

    Tuple * base_tuple = NULL;
    bool_t base_tuple_scanned = FALSE;

    for (int track = 1; track <= tracks; track ++)
    {
        if (current == NULL || filename == NULL)
            return FALSE;

        if (base_tuple == NULL && ! base_tuple_scanned)
        {
            base_tuple_scanned = TRUE;
            PluginHandle * decoder = aud_file_find_decoder (filename, FALSE);
            if (decoder != NULL)
                base_tuple = aud_file_read_tuple (filename, decoder);
        }

        Track * next = (track + 1 <= tracks) ? cd_get_track (cd, track + 1) : NULL;
        char * next_filename = (next != NULL) ? uri_construct
         (track_get_filename (next), cue_filename) : NULL;
        bool_t last_track = (next_filename == NULL || strcmp (next_filename, filename));

        Tuple * tuple = (base_tuple != NULL) ? tuple_copy (base_tuple) :
         tuple_new_from_filename (filename);
        tuple_set_int (tuple, FIELD_TRACK_NUMBER, track);

        int begin = (int64_t) track_get_start (current) * 1000 / 75;
        tuple_set_int (tuple, FIELD_SEGMENT_START, begin);

        if (last_track)
        {
            if (base_tuple != NULL && tuple_get_value_type (base_tuple,
             FIELD_LENGTH) == TUPLE_INT)
                tuple_set_int (tuple, FIELD_LENGTH, tuple_get_int
                 (base_tuple, FIELD_LENGTH) - begin);
        }
        else
        {
            int length = (int64_t) track_get_length (current) * 1000 / 75;
            tuple_set_int (tuple, FIELD_LENGTH, length);
            tuple_set_int (tuple, FIELD_SEGMENT_END, begin + length);
        }

        for (int i = 0; i < ARRAY_LEN (pti_map); i ++)
            tuple_attach_cdtext (tuple, current, pti_map[i].tuple_type, pti_map[i].pti);

        index_insert (filenames, -1, str_get (filename));
        index_insert (tuples, -1, tuple);

        current = next;
        str_unref (filename);
        filename = next_filename;

        if (last_track && base_tuple != NULL)
        {
            tuple_unref (base_tuple);
            base_tuple = NULL;
            base_tuple_scanned = FALSE;
        }
    }

    return TRUE;
}
/* builtin-keyword: ${==arg1,arg2}, returns TRUE if <arg1> and <arg2> match.
   <arg1> and <arg2> can also be raw text, which should be enclosed in "double quotes". */
static gboolean
tuple_formatter_expression_match(Tuple *tuple, const gchar *expression)
{
    gchar **args = g_strsplit(expression, ",", 2);
    gchar *arg1 = NULL, *arg2 = NULL;
    gint ret;

    if (args[0][0] == '\"') /* check if arg1 is "raw text" */
    {
        if ( strlen(args[0]) > 1 )
        {
            args[0][strlen(args[0]) - 1] = '\0';
            arg1 = g_strdup(&(args[0][1]));
            args[0][strlen(args[0]) - 1] = '\"';
        }
        else /* bad formatted arg */
            return FALSE;
    }
    else if (tuple_get_value_type(tuple, -1, args[0]) == TUPLE_UNKNOWN)
    {
        g_strfreev(args);
        return FALSE;
    }

    if (args[1][0] == '\"') /* check if arg2 is "raw text" */
    {
        if ( strlen(args[1]) > 1 )
        {
            args[1][strlen(args[1]) - 1] = '\0';
            arg2 = g_strdup(&(args[1][1]));
            args[1][strlen(args[1]) - 1] = '\"';
        }
        else /* bad formatted arg */
            return FALSE;
    }
    else if (tuple_get_value_type(tuple, -1, args[1]) == TUPLE_UNKNOWN)
    {
        g_strfreev(args);
        return FALSE;
    }

    if (!arg1) /* if arg1 is not "raw text", get the tuple value */
    {
        if (tuple_get_value_type(tuple, -1, args[0]) == TUPLE_STRING)
            arg1 = g_strdup(tuple_get_string(tuple, -1, args[0]));
        else
            arg1 = g_strdup_printf("%d", tuple_get_int(tuple, -1, args[0]));
    }

    if (!arg2) /* if arg2 is not "raw text", get the tuple value */
    {
        if (tuple_get_value_type(tuple, -1, args[1]) == TUPLE_STRING)
            arg2 = g_strdup(tuple_get_string(tuple, -1, args[1]));
        else
            arg2 = g_strdup_printf("%d", tuple_get_int(tuple, -1, args[1]));
    }

    ret = g_ascii_strcasecmp(arg1, arg2);
    g_free(arg1);
    g_free(arg2);
    g_strfreev(args);

    return ret ? FALSE : TRUE;
}