/* ----------------------------------------------------------------------- */ static char* create_bookmark() { int resume_index = 0; char *file; if (!bookmark_is_bookmarkable_state()) return NULL; /* something didn't happen correctly, do nothing */ /* grab the currently playing track */ struct mp3entry *id3 = audio_current_track(); if(!id3) return NULL; /* Get some basic resume information */ /* queue_resume and queue_resume_index are not used and can be ignored.*/ playlist_get_resume_info(&resume_index); /* Get the currently playing file minus the path */ /* This is used when displaying the available bookmarks */ file = strrchr(id3->path,'/'); if(NULL == file) return NULL; /* create the bookmark */ snprintf(global_bookmark, sizeof(global_bookmark), /* new optional bookmark token descriptors should be inserted just before the "%s;%s" in this line... */ #if CONFIG_CODEC == SWCODEC && defined(HAVE_PITCHCONTROL) ">%d;%d;%ld;%d;%ld;%d;%d;%ld;%ld;%s;%s", #else ">%d;%d;%ld;%d;%ld;%d;%d;%s;%s", #endif /* ... their flags should go here ... */ #if CONFIG_CODEC == SWCODEC && defined(HAVE_PITCHCONTROL) BM_PITCH | BM_SPEED, #else 0, #endif resume_index, id3->offset, playlist_get_seed(NULL), id3->elapsed, global_settings.repeat_mode, global_settings.playlist_shuffle, /* ...and their values should go here */ #if CONFIG_CODEC == SWCODEC && defined(HAVE_PITCHCONTROL) (long)sound_get_pitch(), (long)dsp_get_timestretch(), #endif /* more mandatory tokens */ playlist_get_name(NULL, global_temp_buffer, sizeof(global_temp_buffer)), file+1); /* checking to see if the bookmark is valid */ if (parse_bookmark(global_bookmark, false)) return global_bookmark; else return NULL; }
static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line) { char* dest = ((char*) bookmarks) + bookmarks->buffer_size - 1; int read_count = 0; int file = open(bookmarks->filename, O_RDONLY); if (file < 0) { return -1; } if ((first_line != 0) && ((size_t) filesize(file) < bookmarks->buffer_size - sizeof(*bookmarks) - (sizeof(char*) * bookmarks->total_count))) { /* Entire file fits in buffer */ first_line = 0; } bookmarks->start = first_line; bookmarks->count = 0; bookmarks->reload = false; int tmpcount = 0; while(read_line(file, global_read_buffer, sizeof(global_read_buffer)) > 0) { read_count++; if (read_count >= first_line) { dest -= strlen(global_read_buffer) + 1; if (dest < ((char*) bookmarks) + sizeof(*bookmarks) + (sizeof(char*) * (bookmarks->count + 1))) { break; } if (bookmarks->filterby == 0 || (bookmarks->filterby && parse_bookmark(global_read_buffer, true) && strcmp(global_filename, bookmarks->filterby) == 0)) { strcpy(dest, global_read_buffer); bookmarks->items[bookmarks->count] = dest; bookmarks->count++; } tmpcount++; } } close(file); return bookmarks->start + tmpcount; }
/* ------------------------------------------------------------------------*/ static void say_bookmark(const char* bookmark, int bookmark_id, bool show_playlist_name) { if (!parse_bookmark(bookmark, true)) { talk_id(LANG_BOOKMARK_INVALID, false); return; } talk_number(bookmark_id + 1, false); #if CONFIG_CODEC == SWCODEC bool is_dir = (global_temp_buffer[0] && global_temp_buffer[strlen(global_temp_buffer)-1] == '/'); /* HWCODEC cannot enqueue voice file entries and .talk thumbnails together, because there is no guarantee that the same mp3 parameters are used. */ if(show_playlist_name) { /* It's useful to know which playlist this is */ if(is_dir) talk_dir_or_spell(global_temp_buffer, TALK_IDARRAY(VOICE_DIR), true); else talk_file_or_spell(NULL, global_temp_buffer, TALK_IDARRAY(LANG_PLAYLIST), true); } #else (void)show_playlist_name; #endif if(bm.shuffle) talk_id(LANG_SHUFFLE, true); talk_id(VOICE_BOOKMARK_SELECT_INDEX_TEXT, true); talk_number(bm.resume_index + 1, true); talk_id(LANG_TIME, true); talk_value(bm.resume_time / 1000, UNIT_TIME, true); #if CONFIG_CODEC == SWCODEC /* Track filename */ if(is_dir) talk_file_or_spell(global_temp_buffer, global_filename, TALK_IDARRAY(VOICE_FILE), true); else { /* Unfortunately if this is a playlist, we do not know in which directory the file is and therefore cannot find the track's .talk file. */ talk_id(VOICE_FILE, true); talk_spell(global_filename, true); } #endif }
static int get_bookmark_count(const char* bookmark_file_name, const char *filterby, int *filtered_count) { int read_count = 0; int tmp_filtered = 0; int file = open(bookmark_file_name, O_RDONLY); if(file < 0) return -1; while(read_line(file, global_read_buffer, sizeof(global_read_buffer)) > 0) { read_count++; if (filterby && parse_bookmark(global_read_buffer, true) && strcmp(global_filename, filterby) == 0) tmp_filtered++; } if (!filterby) tmp_filtered = read_count; *filtered_count = tmp_filtered; close(file); return read_count; }
/* ------------------------------------------------------------------------*/ static bool play_bookmark(const char* bookmark) { #if CONFIG_CODEC == SWCODEC && defined(HAVE_PITCHCONTROL) /* preset pitch and speed to 100% in case bookmark doesn't have info */ bm.pitch = sound_get_pitch(); bm.speed = dsp_get_timestretch(); #endif if (parse_bookmark(bookmark, true, true)) { global_settings.repeat_mode = bm.repeat_mode; global_settings.playlist_shuffle = bm.shuffle; #if CONFIG_CODEC == SWCODEC && defined(HAVE_PITCHCONTROL) sound_set_pitch(bm.pitch); dsp_set_timestretch(bm.speed); #endif if (!warn_on_pl_erase()) return false; return bookmark_play(global_temp_buffer, bm.resume_index, bm.resume_time, bm.resume_offset, bm.resume_seed, global_filename); } return false; }
static const char* get_bookmark_info(int list_index, void* data, char *buffer, size_t buffer_len) { struct bookmark_list* bookmarks = (struct bookmark_list*) data; int index = list_index / 2; if (bookmarks->show_dont_resume) { if (index == 0) { return list_index % 2 == 0 ? (char*) str(LANG_BOOKMARK_DONT_RESUME) : " "; } index--; } if (bookmarks->reload || (index >= bookmarks->start + bookmarks->count) || (index < bookmarks->start)) { int read_index = index; /* Using count as a guide on how far to move could possibly fail * sometimes. Use byte count if that is a problem? */ if (read_index != 0) { /* Move count * 3 / 4 items in the direction the user is moving, * but don't go too close to the end. */ int offset = bookmarks->count; int max = bookmarks->total_count - (bookmarks->count / 2); if (read_index < bookmarks->start) { offset *= 3; } read_index = index - offset / 4; if (read_index > max) { read_index = max; } if (read_index < 0) { read_index = 0; } } if (buffer_bookmarks(bookmarks, read_index) <= index) { return ""; } } if (!parse_bookmark(bookmarks->items[index - bookmarks->start], true, true)) { return list_index % 2 == 0 ? (char*) str(LANG_BOOKMARK_INVALID) : " "; } if (list_index % 2 == 0) { char *name; char *format; int len = strlen(global_temp_buffer); if (bookmarks->show_playlist_name && len > 0) { name = global_temp_buffer; len--; if (name[len] != '/') { strrsplt(name, '.'); } else if (len > 1) { name[len] = '\0'; } if (len > 1) { name = strrsplt(name, '/'); } format = "%s : %s"; } else { name = global_filename; format = "%s"; } strrsplt(global_filename, '.'); snprintf(buffer, buffer_len, format, name, global_filename); return buffer; } else { char time_buf[32]; format_time(time_buf, sizeof(time_buf), bm.resume_time); snprintf(buffer, buffer_len, "%s, %d%s", time_buf, bm.resume_index + 1, bm.shuffle ? (char*) str(LANG_BOOKMARK_SHUFFLE) : ""); return buffer; } }
/* ------------------------------------------------------------------------*/ static bool add_bookmark(const char* bookmark_file_name, const char* bookmark, bool most_recent) { int temp_bookmark_file = 0; int bookmark_file = 0; int bookmark_count = 0; char *pl_start = NULL, *bm_pl_start; char *pl_end = NULL, *bm_pl_end; int pl_len = 0, bm_pl_len; char *track = NULL, *bm_track; bool comp_playlist = false; bool comp_track = false; bool equal; /* Opening up a temp bookmark file */ snprintf(global_temp_buffer, sizeof(global_temp_buffer), "%s.tmp", bookmark_file_name); temp_bookmark_file = open(global_temp_buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (temp_bookmark_file < 0) return false; /* can't open the temp file */ if (most_recent && ((global_settings.usemrb == BOOKMARK_ONE_PER_PLAYLIST) || (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK))) { if (get_playlist_and_track(bookmark, &pl_start, &pl_end, &track)) { comp_playlist = true; pl_len = pl_end - pl_start; if (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK) comp_track = true; } } /* Writing the new bookmark to the begining of the temp file */ write(temp_bookmark_file, bookmark, strlen(bookmark)); write(temp_bookmark_file, "\n", 1); bookmark_count++; /* Reading in the previous bookmarks and writing them to the temp file */ bookmark_file = open(bookmark_file_name, O_RDONLY); if (bookmark_file >= 0) { while (read_line(bookmark_file, global_read_buffer, sizeof(global_read_buffer)) > 0) { /* The MRB has a max of MAX_BOOKMARKS in it */ /* This keeps it from getting too large */ if (most_recent && (bookmark_count >= MAX_BOOKMARKS)) break; if (!parse_bookmark(global_read_buffer, false, false)) break; equal = false; if (comp_playlist) { if (get_playlist_and_track(global_read_buffer, &bm_pl_start, &bm_pl_end, &bm_track)) { bm_pl_len = bm_pl_end - bm_pl_start; equal = (pl_len == bm_pl_len) && !strncmp(pl_start, bm_pl_start, pl_len); if (equal && comp_track) equal = !strcmp(track, bm_track); } } if (!equal) { bookmark_count++; write(temp_bookmark_file, global_read_buffer, strlen(global_read_buffer)); write(temp_bookmark_file, "\n", 1); } } close(bookmark_file); } close(temp_bookmark_file); remove(bookmark_file_name); rename(global_temp_buffer, bookmark_file_name); return true; }
/* ------------------------------------------------------------------------*/ static bool add_bookmark(const char* bookmark_file_name, const char* bookmark, bool most_recent) { int temp_bookmark_file = 0; int bookmark_file = 0; int bookmark_count = 0; char* playlist = NULL; char* cp; char* tmp; int len = 0; bool unique = false; /* Opening up a temp bookmark file */ snprintf(global_temp_buffer, sizeof(global_temp_buffer), "%s.tmp", bookmark_file_name); temp_bookmark_file = open(global_temp_buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (temp_bookmark_file < 0) return false; /* can't open the temp file */ if (most_recent && (global_settings.usemrb == BOOKMARK_UNIQUE_ONLY)) { playlist = strchr(bookmark,'/'); cp = strrchr(bookmark,';'); len = cp - playlist; unique = true; } /* Writing the new bookmark to the begining of the temp file */ write(temp_bookmark_file, bookmark, strlen(bookmark)); write(temp_bookmark_file, "\n", 1); bookmark_count++; /* Reading in the previous bookmarks and writing them to the temp file */ bookmark_file = open(bookmark_file_name, O_RDONLY); if (bookmark_file >= 0) { while (read_line(bookmark_file, global_read_buffer, sizeof(global_read_buffer)) > 0) { /* The MRB has a max of MAX_BOOKMARKS in it */ /* This keeps it from getting too large */ if (most_recent && (bookmark_count >= MAX_BOOKMARKS)) break; cp = strchr(global_read_buffer,'/'); tmp = strrchr(global_read_buffer,';'); if (parse_bookmark(global_read_buffer, false) && (!unique || len != tmp -cp || strncmp(playlist,cp,len))) { bookmark_count++; write(temp_bookmark_file, global_read_buffer, strlen(global_read_buffer)); write(temp_bookmark_file, "\n", 1); } } close(bookmark_file); } close(temp_bookmark_file); remove(bookmark_file_name); rename(global_temp_buffer, bookmark_file_name); return true; }