📄 playlist.c
字号:
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 = ¤t_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 = ¤t_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 = ¤t_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 + -