⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playlist.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
            flags = PLAYLIST_INSERT_TYPE_APPEND;            break;    }        if (queue)        flags |= PLAYLIST_QUEUED;    /* shift indices so that track can be added */    for (i=playlist->amount; i>insert_position; i--)        playlist->indices[i] = playlist->indices[i-1];    /* update stored indices if needed */    if (playlist->amount > 0 && insert_position <= playlist->index)        playlist->index++;    if (playlist->amount > 0 && insert_position <= playlist->first_index &&        position != PLAYLIST_PREPEND)    {        playlist->first_index++;        if (seek_pos < 0 && playlist->current)        {            global_settings.resume_first_index = playlist->first_index;            settings_save();        }    }    if (insert_position < playlist->last_insert_pos ||        (insert_position == playlist->last_insert_pos && position < 0))        playlist->last_insert_pos++;    if (seek_pos < 0 && playlist->control_fd >= 0)    {        int result = -1;        if (flush_pending_control(playlist) < 0)            return -1;        mutex_lock(&playlist->control_mutex);        if (lseek(playlist->control_fd, 0, SEEK_END) >= 0)        {            if (fprintf(playlist->control_fd, "%c:%d:%d:", (queue?'Q':'A'),                    position, playlist->last_insert_pos) > 0)            {                /* save the position in file where track name is written */                seek_pos = lseek(playlist->control_fd, 0, SEEK_CUR);                if (fprintf(playlist->control_fd, "%s\n", filename) > 0)                    result = 0;            }        }        mutex_unlock(&playlist->control_mutex);        if (result < 0)        {            splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR));            return result;        }    }    playlist->indices[insert_position] = flags | seek_pos;    playlist->amount++;    playlist->num_inserted_tracks++;    return insert_position;}/* * Insert directory into playlist.  May be called recursively. */static int add_directory_to_playlist(struct playlist_info* playlist,                                     char *dirname, int *position, bool queue,                                     int *count, bool recurse){    char buf[MAX_PATH+1];    char *count_str;    int result = 0;    int num_files = 0;    bool buffer_full = false;    int i;    int dirfilter = SHOW_ALL;    struct entry *files;    /* use the tree browser dircache to load files */    files = load_and_sort_directory(dirname, &dirfilter, &num_files,        &buffer_full);    if(!files)    {        splash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR));        return 0;    }    /* we've overwritten the dircache so tree browser will need to be       reloaded */    reload_directory();    if (queue)        count_str = str(LANG_PLAYLIST_QUEUE_COUNT);    else        count_str = str(LANG_PLAYLIST_INSERT_COUNT);    for (i=0; i<num_files; i++)    {        /* user abort */#if defined(HAVE_PLAYER_KEYPAD) || defined(HAVE_NEO_KEYPAD)        if (button_get(false) == BUTTON_STOP)#else        if (button_get(false) == BUTTON_OFF)#endif        {            result = -1;            break;        }        if (files[i].attr & ATTR_DIRECTORY)        {            if (recurse)            {                /* recursively add directories */                snprintf(buf, sizeof(buf), "%s/%s", dirname, files[i].name);                result = add_directory_to_playlist(playlist, buf, position,                    queue, count, recurse);                if (result < 0)                    break;                /* we now need to reload our current directory */                files = load_and_sort_directory(dirname, &dirfilter, &num_files,                    &buffer_full);                if (!files)                {                    result = -1;                    break;                }            }            else                continue;        }        else if ((files[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)        {            int insert_pos;            snprintf(buf, sizeof(buf), "%s/%s", dirname, files[i].name);                        insert_pos = add_track_to_playlist(playlist, buf, *position,                queue, -1);            if (insert_pos < 0)            {                result = -1;                break;            }            (*count)++;            /* Make sure tracks are inserted in correct order if user requests               INSERT_FIRST */            if (*position == PLAYLIST_INSERT_FIRST || *position >= 0)                *position = insert_pos + 1;            if ((*count%PLAYLIST_DISPLAY_COUNT) == 0)            {                display_playlist_count(*count, count_str);                if (*count == PLAYLIST_DISPLAY_COUNT)                    mpeg_flush_and_reload_tracks();            }                        /* let the other threads work */            yield();        }    }    return result;}/* * remove track at specified position */static int remove_track_from_playlist(struct playlist_info* playlist,                                      int position, bool write){    int i;    bool inserted;    if (playlist->amount <= 0)        return -1;    inserted = playlist->indices[position] & PLAYLIST_INSERT_TYPE_MASK;    /* shift indices now that track has been removed */    for (i=position; i<playlist->amount; i++)        playlist->indices[i] = playlist->indices[i+1];    playlist->amount--;    if (inserted)        playlist->num_inserted_tracks--;    else        playlist->deleted = true;    /* update stored indices if needed */    if (position < playlist->index)        playlist->index--;    if (position < playlist->first_index)    {        playlist->first_index--;        if (write)        {            global_settings.resume_first_index = playlist->first_index;            settings_save();        }    }    if (position <= playlist->last_insert_pos)        playlist->last_insert_pos--;    if (write && playlist->control_fd >= 0)    {        int result = -1;        if (flush_pending_control(playlist) < 0)            return -1;        mutex_lock(&playlist->control_mutex);        if (lseek(playlist->control_fd, 0, SEEK_END) >= 0)        {            if (fprintf(playlist->control_fd, "D:%d\n", position) > 0)            {                fsync(playlist->control_fd);                result = 0;            }        }        mutex_unlock(&playlist->control_mutex);        if (result < 0)        {            splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR));            return result;        }    }    return 0;}/* * randomly rearrange the array of indices for the playlist.  If start_current * is true then update the index to the new index of the current playing track */static int randomise_playlist(struct playlist_info* playlist,                              unsigned int seed, bool start_current,                              bool write){    int count;    int candidate;    int store;    unsigned int current = playlist->indices[playlist->index];        /* seed 0 is used to identify sorted playlist for resume purposes */    if (seed == 0)        seed = 1;    /* seed with the given seed */    srand(seed);    /* randomise entire indices list */    for(count = playlist->amount - 1; count >= 0; count--)    {        /* the rand is from 0 to RAND_MAX, so adjust to our value range */        candidate = rand() % (count + 1);        /* now swap the values at the 'count' and 'candidate' positions */        store = playlist->indices[candidate];        playlist->indices[candidate] = playlist->indices[count];        playlist->indices[count] = store;    }    if (start_current)        find_and_set_playlist_index(playlist, current);    /* indices have been moved so last insert position is no longer valid */    playlist->last_insert_pos = -1;    playlist->seed = seed;    if (playlist->num_inserted_tracks > 0 || playlist->deleted)        playlist->shuffle_modified = true;    if (write)    {        /* Don't write to disk immediately.  Instead, save in settings and           only flush if playlist is modified (insertion/deletion) */        playlist->shuffle_flush = true;        global_settings.resume_seed = seed;        settings_save();    }    return 0;}/* * Sort the array of indices for the playlist. If start_current is true then * set the index to the new index of the current song. */static int sort_playlist(struct playlist_info* playlist, bool start_current,                         bool write){    unsigned int current = playlist->indices[playlist->index];    if (playlist->amount > 0)        qsort(playlist->indices, playlist->amount, sizeof(playlist->indices[0]),            compare);    if (start_current)        find_and_set_playlist_index(playlist, current);    /* indices have been moved so last insert position is no longer valid */    playlist->last_insert_pos = -1;    if (!playlist->num_inserted_tracks && !playlist->deleted)        playlist->shuffle_modified = false;    if (write && playlist->control_fd >= 0)    {        /* Don't write to disk immediately.  Instead, save in settings and           only flush if playlist is modified (insertion/deletion) */        playlist->shuffle_flush = true;        global_settings.resume_seed = 0;        settings_save();    }    return 0;}/* * returns the index of the track that is "steps" away from current playing * track. */static int get_next_index(struct playlist_info* playlist, int steps){    int current_index = playlist->index;    int next_index    = -1;    if (playlist->amount <= 0)        return -1;    switch (global_settings.repeat_mode)    {        case REPEAT_OFF:        {            current_index = rotate_index(playlist, current_index);                        next_index = current_index+steps;            if ((next_index < 0) || (next_index >= playlist->amount))                next_index = -1;            else                next_index = (next_index+playlist->first_index) %                    playlist->amount;            break;        }        case REPEAT_ONE:            next_index = current_index;            break;        case REPEAT_ALL:        default:        {            next_index = (current_index+steps) % playlist->amount;            while (next_index < 0)                next_index += playlist->amount;            if (steps >= playlist->amount)            {                int i, index;                index = next_index;                next_index = -1;                /* second time around so skip the queued files */                for (i=0; i<playlist->amount; i++)                {                    if (playlist->indices[index] & PLAYLIST_QUEUE_MASK)                        index = (index+1) % playlist->amount;                    else                    {                        next_index = index;                        break;                    }                }            }            break;        }    }    return next_index;}/* * Search for the seek track and set appropriate indices.  Used after shuffle * to make sure the current index is still pointing to correct track. */static void find_and_set_playlist_index(struct playlist_info* playlist,                                        unsigned int seek){    int i;        /* Set the index to the current song */    for (i=0; i<playlist->amount; i++)    {        if (playlist->indices[i] == seek)        {            playlist->index = playlist->first_index = i;            if (playlist->current)            {                global_settings.resume_first_index = i;                settings_save();            }            break;        }    }}/* * used to sort track indices.  Sort order is as follows: * 1. Prepended tracks (in prepend order) * 2. Playlist/directory tracks (in playlist order) * 3. Inserted/Appended tracks (in insert order) */static int compare(const void* p1, const void* p2){    unsigned int* e1 = (unsigned int*) p1;    unsigned int* e2 = (unsigned int*) p2;    unsigned int flags1 = *e1 & PLAYLIST_INSERT_TYPE_MASK;    unsigned int flags2 = *e2 & PLAYLIST_INSERT_TYPE_MASK;    if (flags1 == flags2)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -