Beispiel #1
0
const char *
pl_find_meta (playItem_t *it, const char *key) {
    pl_lock ();
    DB_metaInfo_t *m = it->meta;

    if (key && key[0] == ':') {
        // try to find an override
        while (m) {
            if (m->key[0] == '!' && !strcasecmp (key+1, m->key+1)) {
                pl_unlock ();
                return m->value;
            }
            m = m->next;
        }
    }

    m = it->meta;
    while (m) {
        if (!strcasecmp (key, m->key)) {
            pl_unlock ();
            return m->value;
        }
        m = m->next;
    }
    pl_unlock ();
    return NULL;
}
Beispiel #2
0
playItem_t *
playqueue_getnext (void) {
    pl_lock ();
    if (playqueue_count > 0) {
        playItem_t *val = playqueue[0];
        pl_item_ref (val);
        pl_unlock ();
        return val;
    }
    pl_unlock ();
    return NULL;
}
Beispiel #3
0
int
playqueue_test (playItem_t *it) {
    pl_lock ();
    for (int i = 0; i < playqueue_count; i++) {
        if (playqueue[i] == it) {
            pl_unlock ();
            return i;
        }
    }
    pl_unlock ();
    return -1;
}
Beispiel #4
0
int
pl_get_meta_raw (playItem_t *it, const char *key, char *val, int size) {
    *val = 0;
    pl_lock ();
    const char *v = pl_find_meta_raw (it, key);
    if (!v) {
        pl_unlock ();
        return 0;
    }
    strncpy (val, v, size);
    pl_unlock ();
    return 1;
}
Beispiel #5
0
const char *
pl_find_meta_raw (playItem_t *it, const char *key) {
    pl_lock ();
    DB_metaInfo_t *m = it->meta;
    while (m) {
        if (!strcasecmp (key, m->key)) {
            pl_unlock ();
            return m->value;
        }
        m = m->next;
    }
    pl_unlock ();
    return NULL;
}
Beispiel #6
0
void
playqueue_remove (playItem_t *it) {
    pl_lock ();
    for (;;) {
        int i;
        for (i = 0; i < playqueue_count; i++) {
            if (playqueue[i] == it) {
                if (i < playqueue_count-1) {
                    memmove (&playqueue[i], &playqueue[i+1], (playqueue_count-i) * sizeof (playItem_t*));
                    messagepump_push (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_PLAYQUEUE, 0);
                }
                else {
                    playqueue_send_trackinfochanged (it);
                }
                pl_item_unref (it);
                playqueue_count--;
                break;
            }
        }
        if (i == playqueue_count) {
            break;
        }
    }
    pl_unlock ();
}
Beispiel #7
0
int
pl_meta_exists (playItem_t *it, const char *key) {
    pl_lock ();
    const char *v = pl_find_meta (it, key);
    pl_unlock ();
    return v ? 1 : 0;
}
Beispiel #8
0
float
pl_find_meta_float (playItem_t *it, const char *key, float def) {
    pl_lock ();
    const char *val = pl_find_meta (it, key);
    float res = val ? atof (val) : def;
    pl_unlock ();
    return res;
}
Beispiel #9
0
int
pl_find_meta_int (playItem_t *it, const char *key, int def) {
    pl_lock ();
    const char *val = pl_find_meta (it, key);
    int res = val ? atoi (val) : def;
    pl_unlock ();
    return res;
}
Beispiel #10
0
playItem_t *
playqueue_get_item (int i) {
    pl_lock ();
    playItem_t *it = playqueue[i];
    pl_item_ref (it);
    pl_unlock ();
    return it;
}
Beispiel #11
0
void
pl_append_meta (playItem_t *it, const char *key, const char *value) {
    pl_lock ();
    const char *old = pl_find_meta_raw (it, key);

    if (old && (!strcasecmp (key, "cuesheet") || !strcasecmp (key, "log"))) {
        pl_unlock ();
        return;
    }

    size_t newlen = strlen (value);
    if (!old) {
        pl_add_meta (it, key, value);
    }
    else {
        // check for duplicate data
        const char *str = old;
        int len;
        while (str) {
            char *next = strchr (str, '\n');

            if (next) {
                len = next - str;
                next++;
            }
            else {
                len = strlen (str);
            }

            if (len == newlen && !memcmp (str, value, len)) {
                pl_unlock ();
                return;
            }

            str = next;
        }
        int sz = strlen (old) + newlen + 2;
        char out[sz];
        snprintf (out, sz, "%s\n%s", old, value);
        pl_replace_meta (it, key, out);
    }
    pl_unlock ();
}
Beispiel #12
0
void
playqueue_insert_at (int n, playItem_t *it) {
    if (playqueue_count == PLAYQUEUE_SIZE) {
        trace ("playqueue is full\n");
        return;
    }
    pl_lock ();
    if (n == playqueue_count) {
        playqueue_push(it);
        pl_unlock ();
        return;
    }
    memmove (playqueue+n+1, playqueue+n, (playqueue_count - n) * sizeof (playItem_t *));
    playqueue[n] = it;
    pl_item_ref (it);
    playqueue_count++;
    pl_unlock ();
    messagepump_push (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_PLAYQUEUE, 0);
}
Beispiel #13
0
void
playqueue_pop (void) {
    if (!playqueue_count) {
        return;
    }
    pl_lock ();
    if (playqueue_count == 1) {
        playqueue_count = 0;
        playqueue_send_trackinfochanged (playqueue[0]);
        pl_item_unref (playqueue[0]);
        pl_unlock ();
        return;
    }
    playItem_t *it = playqueue[0];
    memmove (&playqueue[0], &playqueue[1], (playqueue_count-1) * sizeof (playItem_t*));
    playqueue_count--;
    pl_item_unref (it);
    pl_unlock ();
    messagepump_push (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_PLAYQUEUE, 0);
}
Beispiel #14
0
void
playqueue_clear (void) {
    pl_lock ();
    for (int i = 0; i < playqueue_count; i++) {
        pl_item_unref (playqueue[i]);
        playqueue[i] = NULL;
    }
    playqueue_count = 0;
    pl_unlock ();
    messagepump_push (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_PLAYQUEUE, 0);
}
Beispiel #15
0
void
playqueue_remove_nth (int n) {
    pl_lock ();
    playItem_t *it = playqueue[n];
    if (n < playqueue_count-1) {
        memmove (playqueue + n, playqueue + n + 1, (playqueue_count-n) * sizeof (playItem_t*));
    }
    playqueue_count--;

    pl_item_unref (it);
    pl_unlock ();
    messagepump_push (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_PLAYQUEUE, 0);
}
Beispiel #16
0
int
playqueue_push (playItem_t *it) {
    if (playqueue_count == PLAYQUEUE_SIZE) {
        trace ("playqueue is full\n");
        return -1;
    }
    pl_lock ();
    pl_item_ref (it);
    playqueue[playqueue_count++] = it;
    pl_unlock ();
    playqueue_send_trackinfochanged (it);
    return 0;
}
Beispiel #17
0
void
plt_sort_random (playlist_t *playlist, int iter) {
    if (!playlist->head[iter] || !playlist->head[iter]->next[iter]) {
        return;
    }

    pl_lock ();

    const int playlist_count = playlist->count[iter];
    playItem_t **array = malloc (playlist_count * sizeof (playItem_t *));
    int idx = 0;
    for (playItem_t *it = playlist->head[iter]; it; it = it->next[iter], idx++) {
        array[idx] = it;
    }

    //randomize array
    for (int swap_a = 0; swap_a < playlist_count - 1; swap_a++) {
        //select random item above swap_a-1
        const int swap_b = swap_a + (rand() / (float)RAND_MAX * (playlist_count - swap_a));

        //swap a with b
        playItem_t* const swap_temp = array[swap_a];
        array[swap_a] = array[swap_b];
        array[swap_b] = swap_temp;

    }

    playItem_t *prev = NULL;
    playlist->head[iter] = 0;
    for (idx = 0; idx < playlist->count[iter]; idx++) {
        playItem_t *it = array[idx];
        it->prev[iter] = prev;
        it->next[iter] = NULL;
        if (!prev) {
            playlist->head[iter] = it;
        }
        else {
            prev->next[iter] = it;
        }
        prev = it;
    }
    playlist->tail[iter] = array[playlist->count[iter]-1];

    free (array);

    plt_modified (playlist);

    pl_unlock ();
}
Beispiel #18
0
void
pl_delete_metadata (playItem_t *it, DB_metaInfo_t *meta) {
    pl_lock ();
    DB_metaInfo_t *prev = NULL;
    DB_metaInfo_t *m = it->meta;
    while (m) {
        if (m == meta) {
            if (prev) {
                prev->next = m->next;
            }
            else {
                it->meta = m->next;
            }
            metacache_remove_string (m->key);
            metacache_remove_string (m->value);
            free (m);
            break;
        }
        prev = m;
        m = m->next;
    }
    pl_unlock ();
}
Beispiel #19
0
void
pl_delete_meta (playItem_t *it, const char *key) {
    pl_lock ();
    DB_metaInfo_t *prev = NULL;
    DB_metaInfo_t *m = it->meta;
    while (m) {
        if (!strcasecmp (key, m->key)) {
            if (prev) {
                prev->next = m->next;
            }
            else {
                it->meta = m->next;
            }
            metacache_remove_string (m->key);
            metacache_remove_string (m->value);
            free (m);
            break;
        }
        prev = m;
        m = m->next;
    }
    pl_unlock ();
}
Beispiel #20
0
// version 0: title formatting v1
// version 1: title formatting v2
void
plt_sort_internal (playlist_t *playlist, int iter, int id, const char *format, int order, int version) {
    if (order == DDB_SORT_RANDOM) {
        plt_sort_random (playlist, iter);
        return;
    }
    int ascending = order == DDB_SORT_DESCENDING ? 0 : 1;

    if (format == NULL || id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) {
        return;
    }
    pl_lock ();
    struct timeval tm1;
    gettimeofday (&tm1, NULL);
    pl_sort_ascending = ascending;
    trace ("ascending: %d\n", ascending);
    pl_sort_id = id;

    pl_sort_version = version;
    if (version == 0) {
        pl_sort_format = format;
        pl_sort_tf_bytecode = NULL;
    }
    else {
        pl_sort_format = NULL;
        pl_sort_tf_bytecode = tf_compile (format);
        pl_sort_tf_ctx._size = sizeof (pl_sort_tf_ctx);
        pl_sort_tf_ctx.it = NULL;
        pl_sort_tf_ctx.plt = (ddb_playlist_t *)playlist;
        pl_sort_tf_ctx.idx = -1;
        pl_sort_tf_ctx.id = id;
    }

    if (format && id == -1
        && ((version == 0 && !strcmp (format, "%l"))
            || (version == 1 && !strcmp (format, "%length%")))
        ) {
        pl_sort_is_duration = 1;
    }
    else {
        pl_sort_is_duration = 0;
    }
    if (format && id == -1
        && ((version == 0 && !strcmp (format, "%n"))
            || (version == 1 && (!strcmp (format, "%track number%") || !strcmp (format, "%tracknumber%"))))
        ) {
        pl_sort_is_track = 1;
    }
    else {
        pl_sort_is_track = 0;
    }

    playItem_t **array = malloc (playlist->count[iter] * sizeof (playItem_t *));
    int idx = 0;
    for (playItem_t *it = playlist->head[iter]; it; it = it->next[iter], idx++) {
        array[idx] = it;
    }
    qsort (array, playlist->count[iter], sizeof (playItem_t *), qsort_cmp_func);
    playItem_t *prev = NULL;
    playlist->head[iter] = 0;
    for (idx = 0; idx < playlist->count[iter]; idx++) {
        playItem_t *it = array[idx];
        it->prev[iter] = prev;
        it->next[iter] = NULL;
        if (!prev) {
            playlist->head[iter] = it;
        }
        else {
            prev->next[iter] = it;
        }
        prev = it;
    }

    playlist->tail[iter] = array[playlist->count[iter]-1];

    free (array);

    struct timeval tm2;
    gettimeofday (&tm2, NULL);
    int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
    trace ("sort time: %f seconds\n", ms / 1000.f);

    plt_modified (playlist);

    if (version == 0) {
        pl_sort_format = NULL;
    }

    if (version == 1) {
        tf_free (pl_sort_tf_bytecode);
        pl_sort_tf_bytecode = NULL;
        memset (&pl_sort_tf_ctx, 0, sizeof (pl_sort_tf_ctx));
    }

    pl_unlock ();
}