From 55064f7b7d09375c53582f1743bb52164aec8fd2 Mon Sep 17 00:00:00 2001 From: Jeffrey Goode Date: Sat, 10 Apr 2010 21:17:09 +0000 Subject: [PATCH] New bookmarks contain pitch and speed info. Old bookmarks still work, behavior unchanged. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25576 a1c6a512-1295-4272-9138-f99709370657 --- apps/bookmark.c | 72 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/apps/bookmark.c b/apps/bookmark.c index 1b82966be8..eed4219ae7 100644 --- a/apps/bookmark.c +++ b/apps/bookmark.c @@ -42,6 +42,7 @@ #include "plugin.h" #include "file.h" #include "filefuncs.h" +#include "dsp.h" #define MAX_BOOKMARKS 10 #define MAX_BOOKMARK_SIZE 350 @@ -61,8 +62,9 @@ struct bookmark_list char* items[]; }; -/* bookmark flags */ -#define F_BMFILES 0x01 +/* flags for optional bookmark tokens */ +#define BM_PITCH 0x01 +#define BM_SPEED 0x02 /* bookmark values */ static struct { @@ -72,6 +74,9 @@ static struct { long resume_time; int repeat_mode; bool shuffle; + /* optional values */ + int pitch; + int speed; } bm; static bool add_bookmark(const char* bookmark_file_name, const char* bookmark, @@ -82,7 +87,7 @@ static void say_bookmark(const char* bookmark, int bookmark_id, bool show_playlist_name); static bool play_bookmark(const char* bookmark); static bool generate_bookmark_file_name(const char *in); -static bool parse_bookmark(const char *bookmark, const int flags); +static bool parse_bookmark(const char *bookmark, const bool get_filenames); static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line); static const char* get_bookmark_info(int list_index, void* data, @@ -285,7 +290,7 @@ static bool add_bookmark(const char* bookmark_file_name, const char* bookmark, cp = strchr(global_read_buffer,'/'); tmp = strrchr(global_read_buffer,';'); - if (parse_bookmark(global_read_buffer, 0) && + if (parse_bookmark(global_read_buffer, false) && (!unique || len != tmp -cp || strncmp(playlist,cp,len))) { bookmark_count++; @@ -334,20 +339,27 @@ static char* create_bookmark() /* create the bookmark */ snprintf(global_bookmark, sizeof(global_bookmark), - "%d;%ld;%d;%d;%ld;%d;%d;%s;%s", + /* new optional bookmark token descriptors should be inserted + just before the "%s;%s" in this line... */ + ">%d;%d;%ld;%d;%ld;%d;%d;%d;%d;%s;%s", + /* ... their flags should go here ... */ + BM_PITCH | BM_SPEED, resume_index, id3->offset, playlist_get_seed(NULL), - 0, id3->elapsed, global_settings.repeat_mode, global_settings.playlist_shuffle, + /* ...and their values should go here */ + sound_get_pitch(), + dsp_get_timestretch(), + /* 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, 0)) + if (parse_bookmark(global_bookmark, false)) return global_bookmark; else return NULL; @@ -563,9 +575,7 @@ static const char* get_bookmark_info(int list_index, } } - const int flags = F_BMFILES; - - if (!parse_bookmark(bookmarks->items[index - bookmarks->start], flags)) + if (!parse_bookmark(bookmarks->items[index - bookmarks->start], true)) { return list_index % 2 == 0 ? (char*) str(LANG_BOOKMARK_INVALID) : " "; } @@ -832,9 +842,7 @@ static void say_bookmark(const char* bookmark, { bool is_dir; - const int flags = F_BMFILES; - - if (!parse_bookmark(bookmark, flags)) + if (!parse_bookmark(bookmark, true)) { talk_id(LANG_BOOKMARK_INVALID, false); return; @@ -888,12 +896,16 @@ static void say_bookmark(const char* bookmark, /* ------------------------------------------------------------------------*/ static bool play_bookmark(const char* bookmark) { - const int flags = F_BMFILES; + /* preset pitch and speed to 100% in case bookmark doesn't have info */ + bm.pitch = sound_get_pitch(); + bm.speed = dsp_get_timestretch(); - if (parse_bookmark(bookmark, flags)) + if (parse_bookmark(bookmark, true)) { global_settings.repeat_mode = bm.repeat_mode; global_settings.playlist_shuffle = bm.shuffle; + sound_set_pitch(bm.pitch); + dsp_set_timestretch(bm.speed); return bookmark_play(global_temp_buffer, bm.resume_index, bm.resume_offset, bm.resume_seed, global_filename); } @@ -924,27 +936,43 @@ static const char* long_token(const char* s, long* dest) /* ----------------------------------------------------------------------- */ /* This function takes a bookmark and parses it. This function also */ -/* validates the bookmark. Flags are set to indicate which bookmark */ -/* tokens are to be processed. */ +/* validates the bookmark. The parse_filenames flag indicates whether */ +/* the filename tokens are to be extracted. */ /* ----------------------------------------------------------------------- */ -static bool parse_bookmark(const char *bookmark, const int flags) +static bool parse_bookmark(const char *bookmark, const bool parse_filenames) { const char* s = bookmark; const char* end; -#define FLAG(a) (flags & a) #define GET_INT_TOKEN(var) s = long_token(s, (long *)&var) #define GET_BOOL_TOKEN(var) var = (atoi(s)!=0); s = skip_token(s) + /* if new format bookmark, extract the optional content flags, + otherwise treat as an original format bookmark */ + int opt_flags = 0; + bool new_format = (strchr(s, '>') == s); + if (new_format) + { + s++; + GET_INT_TOKEN(opt_flags); + } + + /* extract all original bookmark tokens */ GET_INT_TOKEN(bm.resume_index); GET_INT_TOKEN(bm.resume_offset); GET_INT_TOKEN(bm.resume_seed); - /* skip deprecated token */ - s = skip_token(s); + if (!new_format) /* skip deprecated token */ + s = skip_token(s); GET_INT_TOKEN(bm.resume_time); GET_INT_TOKEN(bm.repeat_mode); GET_BOOL_TOKEN(bm.shuffle); + /* extract all optional bookmark tokens */ + if (opt_flags & BM_PITCH) + GET_INT_TOKEN(bm.pitch); + if (opt_flags & BM_SPEED) + GET_INT_TOKEN(bm.speed); + if (*s == 0) { return false; @@ -953,7 +981,7 @@ static bool parse_bookmark(const char *bookmark, const int flags) end = strchr(s, ';'); /* extract file names */ - if (FLAG(F_BMFILES)) + if (parse_filenames) { size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s); len = MIN(TEMP_BUF_SIZE - 1, len);