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

📄 playlist.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
        return (*e1 & PLAYLIST_SEEK_MASK) - (*e2 & PLAYLIST_SEEK_MASK);    else if (flags1 == PLAYLIST_INSERT_TYPE_PREPEND ||        flags2 == PLAYLIST_INSERT_TYPE_APPEND)        return -1;    else if (flags1 == PLAYLIST_INSERT_TYPE_APPEND ||        flags2 == PLAYLIST_INSERT_TYPE_PREPEND)        return 1;    else if (flags1 && flags2)        return (*e1 & PLAYLIST_SEEK_MASK) - (*e2 & PLAYLIST_SEEK_MASK);    else        return *e1 - *e2;}/* * gets pathname for track at seek index */static int get_filename(struct playlist_info* playlist, int seek,                        bool control_file, char *buf, int buf_length){    int fd;    int max = -1;    char tmp_buf[MAX_PATH+1];    char dir_buf[MAX_PATH+1];    if (buf_length > MAX_PATH+1)        buf_length = MAX_PATH+1;    if (playlist->in_ram && !control_file)    {        strncpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf));        tmp_buf[MAX_PATH] = '\0';        max = strlen(tmp_buf) + 1;    }    else    {        if (control_file)            fd = playlist->control_fd;        else        {            if(-1 == playlist->fd)                playlist->fd = open(playlist->filename, O_RDONLY);                        fd = playlist->fd;        }                if(-1 != fd)        {            if (control_file)                mutex_lock(&playlist->control_mutex);                        lseek(fd, seek, SEEK_SET);            max = read(fd, tmp_buf, buf_length);                        if (control_file)                mutex_unlock(&playlist->control_mutex);                    }        if (max < 0)        {            if (control_file)                splash(HZ*2, true,                    str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));            else                splash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));            return max;        }    }    strncpy(dir_buf, playlist->filename, playlist->dirlen-1);    dir_buf[playlist->dirlen-1] = 0;    return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf));}/* * Returns absolute path of track */static int format_track_path(char *dest, char *src, int buf_length, int max,                             char *dir){    int i = 0;    int j;    char *temp_ptr;    /* Zero-terminate the file name */    while((src[i] != '\n') &&          (src[i] != '\r') &&          (i < max))        i++;    /* Now work back killing white space */    while((src[i-1] == ' ') ||           (src[i-1] == '\t'))        i--;    src[i]=0;          /* replace backslashes with forward slashes */    for ( j=0; j<i; j++ )        if ( src[j] == '\\' )            src[j] = '/';    if('/' == src[0])    {        strncpy(dest, src, buf_length);    }    else    {        /* handle dos style drive letter */        if (':' == src[1])            strncpy(dest, &src[2], buf_length);        else if ('.' == src[0] && '.' == src[1] && '/' == src[2])        {            /* handle relative paths */            i=3;            while(src[i] == '.' &&                  src[i] == '.' &&                  src[i] == '/')                i += 3;            for (j=0; j<i/3; j++) {                temp_ptr = strrchr(dir, '/');                if (temp_ptr)                    *temp_ptr = '\0';                else                    break;            }            snprintf(dest, buf_length, "%s/%s", dir, &src[i]);        }        else if ( '.' == src[0] && '/' == src[1] ) {            snprintf(dest, buf_length, "%s/%s", dir, &src[2]);        }        else {            snprintf(dest, buf_length, "%s/%s", dir, src);        }    }    return 0;}/* * Display splash message showing progress of playlist/directory insertion or * save. */static void display_playlist_count(int count, char *fmt){    lcd_clear_display();#ifdef HAVE_LCD_BITMAP    if(global_settings.statusbar)        lcd_setmargins(0, STATUSBAR_HEIGHT);    else        lcd_setmargins(0, 0);#endif    splash(0, true, fmt, count,#ifdef HAVE_PLAYER_KEYPAD           str(LANG_STOP_ABORT)#else           str(LANG_OFF_ABORT)#endif        );}/* * Display buffer full message */static void display_buffer_full(void){    lcd_clear_display();    lcd_puts(0,0,str(LANG_PLAYINDICES_PLAYLIST));    lcd_puts(0,1,str(LANG_PLAYINDICES_BUFFER));    lcd_update();    sleep(HZ*2);    lcd_clear_display();}/* * Flush any pending control commands to disk.  Called when playlist is being * modified.  Returns 0 on success and -1 on failure. */static int flush_pending_control(struct playlist_info* playlist){    int result = 0;            if (playlist->shuffle_flush && global_settings.resume_seed >= 0)    {        /* pending shuffle */        mutex_lock(&playlist->control_mutex);                if (lseek(playlist->control_fd, 0, SEEK_END) >= 0)        {            if (global_settings.resume_seed == 0)                result = fprintf(playlist->control_fd, "U:%d\n",                    playlist->first_index);            else                result = fprintf(playlist->control_fd, "S:%d:%d\n",                    global_settings.resume_seed, playlist->first_index);            if (result > 0)            {                fsync(playlist->control_fd);                playlist->shuffle_flush = false;                global_settings.resume_seed = -1;                settings_save();                result = 0;            }            else                result = -1;        }        else            result = -1;                mutex_unlock(&playlist->control_mutex);                if (result < 0)        {            splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR));            return result;        }    }    return result;}/* * Rotate indices such that first_index is index 0 */static int rotate_index(struct playlist_info* playlist, int index){    index -= playlist->first_index;    if (index < 0)        index += playlist->amount;    return index;}/* * Initialize playlist entries at startup */void playlist_init(void){    struct playlist_info* playlist = &current_playlist;    playlist->current = true;    snprintf(playlist->control_filename, sizeof(playlist->control_filename),        "%s", PLAYLIST_CONTROL_FILE);    playlist->fd = -1;    playlist->control_fd = -1;    playlist->max_playlist_size = global_settings.max_files_in_playlist;    playlist->indices = buffer_alloc(playlist->max_playlist_size * sizeof(int));    playlist->buffer_size =        AVERAGE_FILENAME_LENGTH * global_settings.max_files_in_dir;    playlist->buffer = buffer_alloc(playlist->buffer_size);    mutex_init(&playlist->control_mutex);    empty_playlist(playlist, true);}/* * Create new playlist */int playlist_create(char *dir, char *file){    struct playlist_info* playlist = &current_playlist;    new_playlist(playlist, dir, file);    if (file)        /* load the playlist file */        add_indices_to_playlist(playlist, NULL, 0);    return 0;}#define PLAYLIST_COMMAND_SIZE (MAX_PATH+12)/* * Restore the playlist state based on control file commands.  Called to * resume playback after shutdown. */int playlist_resume(void){    struct playlist_info* playlist = &current_playlist;    char *buffer;    int buflen;    int nread;    int total_read = 0;    bool first = true;    bool sorted = true;    enum {        resume_playlist,        resume_add,        resume_queue,        resume_delete,        resume_shuffle,        resume_unshuffle,        resume_reset,        resume_comment    };    /* use mp3 buffer for maximum load speed */    buflen = (mp3end - mp3buf);    buffer = mp3buf;    empty_playlist(playlist, true);    playlist->control_fd = open(playlist->control_filename, O_RDWR);    if (playlist->control_fd < 0)    {        splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));        return -1;    }    playlist->control_created = true;    /* read a small amount first to get the header */    nread = read(playlist->control_fd, buffer,        PLAYLIST_COMMAND_SIZE<buflen?PLAYLIST_COMMAND_SIZE:buflen);    if(nread <= 0)    {        splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));        return -1;    }    while (1)    {        int result = 0;        int count;        int current_command = resume_comment;        int last_newline = 0;        int str_count = -1;        bool newline = true;        bool exit_loop = false;        char *p = buffer;        char *str1 = NULL;        char *str2 = NULL;        char *str3 = NULL;        for(count=0; count<nread && !exit_loop; count++,p++)        {            /* Are we on a new line? */            if((*p == '\n') || (*p == '\r'))            {                *p = '\0';                /* save last_newline in case we need to load more data */                last_newline = count;                switch (current_command)                {                    case resume_playlist:                    {                        /* str1=version str2=dir str3=file */                        int version;                                                if (!str1)                        {                            result = -1;                            exit_loop = true;                            break;                        }                                                if (!str2)                            str2 = "";                                                if (!str3)                            str3 = "";                                                version = atoi(str1);                                                if (version != PLAYLIST_CONTROL_FILE_VERSION)                            return -1;                                                update_playlist_filename(playlist, str2, str3);                                                if (str3[0] != '\0')                        {                            /* NOTE: add_indices_to_playlist() overwrites the                               mp3buf so we need to reload control file                               data */                            add_indices_to_playlist(playlist, NULL, 0);                        }                        else if (str2[0] != '\0')                        {                            playlist->in_ram = true;                            resume_directory(str2);                        }                                                /* load the rest of the data */                        first = false;                        exit_loop = true;                        break;                    }                    case resume_add:                    case resume_queue:                    {                        /* str1=position str2=last_position str3=file */                        int position, last_position;                        bool queue;                                                if (!str1 || !str2 || !str3)                        {                            result = -1;                            exit_loop = true;                            break;                        }                                                position = atoi(str1);                        last_position = atoi(str2);                                                queue = (current_command == resume_add)?false:true;                                                /* seek position is based on str3's position in                           buffer */                        if (add_track_to_playlist(playlist, str3, position,                                queue, total_read+(str3-buffer)) < 0)                            return -1;                                                playlist->last_insert_pos = last_position;                        break;                    }                    case resume_delete:                    {                        /* str1=position */                        int position;                                                if (!str1)                        {                            result = -1;                            exit_loop = true;                            break;                        }                                                position = atoi(str1);                                                if (remove_track_from_playlist(playlist, position,                                false) < 0)                            return -1;                        break;                    }

⌨️ 快捷键说明

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