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

📄 playlist.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
                    case resume_shuffle:                    {                        /* str1=seed str2=first_index */                        int seed;                                                if (!str1 || !str2)                        {                            result = -1;                            exit_loop = true;                            break;                        }                                                if (!sorted)                        {                            /* Always sort list before shuffling */                            sort_playlist(playlist, false, false);                        }                        seed = atoi(str1);                        playlist->first_index = atoi(str2);                                                if (randomise_playlist(playlist, seed, false,                                false) < 0)                            return -1;                        sorted = false;                        break;                    }                    case resume_unshuffle:                    {                        /* str1=first_index */                        if (!str1)                        {                            result = -1;                            exit_loop = true;                            break;                        }                                                playlist->first_index = atoi(str1);                                                if (sort_playlist(playlist, false, false) < 0)                            return -1;                        sorted = true;                        break;                    }                    case resume_reset:                    {                        playlist->last_insert_pos = -1;                        break;                    }                    case resume_comment:                    default:                        break;                }                newline = true;                /* to ignore any extra newlines */                current_command = resume_comment;            }             else if(newline)             {                newline = false;                /* first non-comment line must always specify playlist */                if (first && *p != 'P' && *p != '#')                {                    result = -1;                    exit_loop = true;                    break;                }                switch (*p)                {                    case 'P':                        /* playlist can only be specified once */                        if (!first)                        {                            result = -1;                            exit_loop = true;                            break;                        }                        current_command = resume_playlist;                        break;                    case 'A':                        current_command = resume_add;                        break;                    case 'Q':                        current_command = resume_queue;                        break;                    case 'D':                        current_command = resume_delete;                        break;                    case 'S':                        current_command = resume_shuffle;                        break;                    case 'U':                        current_command = resume_unshuffle;                        break;                    case 'R':                        current_command = resume_reset;                        break;                    case '#':                        current_command = resume_comment;                        break;                    default:                        result = -1;                        exit_loop = true;                        break;                }                str_count = -1;                str1 = NULL;                str2 = NULL;                str3 = NULL;            }            else if(current_command != resume_comment)            {                /* all control file strings are separated with a colon.                   Replace the colon with 0 to get proper strings that can be                   used by commands above */                if (*p == ':')                {                    *p = '\0';                    str_count++;                    if ((count+1) < nread)                    {                        switch (str_count)                        {                        case 0:                            str1 = p+1;                            break;                        case 1:                            str2 = p+1;                            break;                        case 2:                            str3 = p+1;                            break;                        default:                            /* allow last string to contain colons */                            *p = ':';                            break;                        }                    }                }            }        }        if (result < 0)        {            splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_INVALID));            return result;        }        if (!newline || (exit_loop && count<nread))        {            /* We didn't end on a newline or we exited loop prematurely.               Either way, re-read the remainder.               NOTE: because of this, control file must always end with a                     newline */            count = last_newline;            lseek(playlist->control_fd, total_read+count, SEEK_SET);        }        total_read += count;        if (first)            /* still looking for header */            nread = read(playlist->control_fd, buffer,                PLAYLIST_COMMAND_SIZE<buflen?PLAYLIST_COMMAND_SIZE:buflen);        else            nread = read(playlist->control_fd, buffer, buflen);        /* Terminate on EOF */        if(nread <= 0)        {            if (global_settings.resume_seed >= 0)            {                /* Apply shuffle command saved in settings */                if (global_settings.resume_seed == 0)                    sort_playlist(playlist, false, true);                else                {                    if (!sorted)                        sort_playlist(playlist, false, false);                    randomise_playlist(playlist, global_settings.resume_seed,                        false, true);                }                playlist->first_index = global_settings.resume_first_index;            }            break;        }    }    return 0;}/*  * Add track to in_ram playlist.  Used when playing directories. */int playlist_add(char *filename){    struct playlist_info* playlist = &current_playlist;    int len = strlen(filename);        if((len+1 > playlist->buffer_size - playlist->buffer_end_pos) ||        (playlist->amount >= playlist->max_playlist_size))    {        display_buffer_full();        return -1;    }    playlist->indices[playlist->amount++] = playlist->buffer_end_pos;    strcpy(&playlist->buffer[playlist->buffer_end_pos], filename);    playlist->buffer_end_pos += len;    playlist->buffer[playlist->buffer_end_pos++] = '\0';    return 0;}/* shuffle newly created playlist using random seed. */int playlist_shuffle(int random_seed, int start_index){    struct playlist_info* playlist = &current_playlist;    unsigned int seek_pos = 0;    bool start_current = false;    if (start_index >= 0 && global_settings.play_selected)    {        /* store the seek position before the shuffle */        seek_pos = playlist->indices[start_index];                playlist->index = global_settings.resume_first_index =            playlist->first_index = start_index;        start_current = true;    }    splash(0, true, str(LANG_PLAYLIST_SHUFFLE));        randomise_playlist(playlist, random_seed, start_current, true);    /* Flush shuffle command to disk */    flush_pending_control(playlist);    return playlist->index;}/* start playing current playlist at specified index/offset */int playlist_start(int start_index, int offset){    struct playlist_info* playlist = &current_playlist;    playlist->index = start_index;    mpeg_play(offset);    return 0;}/* Returns false if 'steps' is out of bounds, else true */bool playlist_check(int steps){    struct playlist_info* playlist = &current_playlist;    int index = get_next_index(playlist, steps);    return (index >= 0);}/* get trackname of track that is "steps" away from current playing track.   NULL is used to identify end of playlist */char* playlist_peek(int steps){    struct playlist_info* playlist = &current_playlist;    int seek;    int fd;    char *temp_ptr;    int index;    bool control_file;    index = get_next_index(playlist, steps);    if (index < 0)        return NULL;    control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;    seek = playlist->indices[index] & PLAYLIST_SEEK_MASK;    if (get_filename(playlist, seek, control_file, now_playing,            MAX_PATH+1) < 0)        return NULL;    temp_ptr = now_playing;    if (!playlist->in_ram || control_file)    {        /* remove bogus dirs from beginning of path           (workaround for buggy playlist creation tools) */        while (temp_ptr)        {            fd = open(temp_ptr, O_RDONLY);            if (fd >= 0)            {                close(fd);                break;            }                        temp_ptr = strchr(temp_ptr+1, '/');        }                if (!temp_ptr)        {            /* Even though this is an invalid file, we still need to pass a               file name to the caller because NULL is used to indicate end               of playlist */            return now_playing;        }    }    return temp_ptr;}/* * Update indices as track has changed */int playlist_next(int steps){    struct playlist_info* playlist = &current_playlist;    int index;    if (steps > 0 && global_settings.repeat_mode != REPEAT_ONE)    {        int i, j;        /* We need to delete all the queued songs */        for (i=0, j=steps; i<j; i++)        {            index = get_next_index(playlist, i);                        if (playlist->indices[index] & PLAYLIST_QUEUE_MASK)            {                remove_track_from_playlist(playlist, index, true);                steps--; /* one less track */            }        }    }    index = get_next_index(playlist, steps);    playlist->index = index;    if (playlist->last_insert_pos >= 0 && steps > 0)    {        /* check to see if we've gone beyond the last inserted track */        int cur = rotate_index(playlist, index);        int last_pos = rotate_index(playlist, playlist->last_insert_pos);        if (cur > last_pos)        {            /* reset last inserted track */            playlist->last_insert_pos = -1;            if (playlist->control_fd >= 0)            {                int result = -1;                mutex_lock(&playlist->control_mutex);                            if (lseek(playlist->control_fd, 0, SEEK_END) >= 0)                {                    if (fprintf(playlist->control_fd, "R\n") > 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 index;}/* Get resume info for current playing song.  If return value is -1 then   settings shouldn't be saved. */int playlist_get_resume_info(int *resume_index){    struct playlist_info* playlist = &current_playlist;    *resume_index = playlist->index;    return 0;}/* Returns index of current playing track for display purposes.  This value   should not be used for resume purposes as it doesn't represent the actual   index into the playlist */int playlist_get_display_index(void){    struct playlist_info* playlist = &current_playlist;    /* first_index should always be index 0 for display purposes */    int index = rotate_index(playlist, playlist->index);    return (index+1);}/* returns number of tracks in current playlist */int playlist_amount(void){    return playlist_amount_ex(NULL);}/* * Create a new playlist  If playlist is not NULL then we're loading a * playlist off disk for viewing/editing.  The index_buffer is used to store * playlist indices (required for and only used if !current playlist).  The * temp_buffer (if not NULL) is used as a scratchpad when loading indices. */int playlist_create_ex(struct playlist_info* playlist, char* dir, char* file,                       void* index_buffer, int index_buffer_size,                       void* temp_buffer, int temp_buffer_size){    if (!playlist)        playlist = &current_playlist;    else    {        /* Initialize playlist structure */        int r = rand() % 10;        playlist->current = false;        /* Use random name for control file */        snprintf(playlist->control_filename, sizeof(playlist->control_filename),            "%s.%d", PLAYLIST_CONTROL_FILE, r);

⌨️ 快捷键说明

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