summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2005-01-20 16:24:26 +0000
committerBjörn Stenberg <bjorn@haxx.se>2005-01-20 16:24:26 +0000
commit30d8f6192ff8217afb7d9bf0722dfd2c66a4d599 (patch)
tree8ec22be7b19a98d74ac7d6ea3f77db106d6b46dd
parentbe7452d31eee7d2cc78c371d0dca885167922e44 (diff)
downloadrockbox-30d8f6192ff8217afb7d9bf0722dfd2c66a4d599.tar.gz
rockbox-30d8f6192ff8217afb7d9bf0722dfd2c66a4d599.tar.bz2
rockbox-30d8f6192ff8217afb7d9bf0722dfd2c66a4d599.zip
Added music playing from ID3 browser.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5616 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/dbtree.c75
-rw-r--r--apps/dbtree.h2
-rw-r--r--apps/playlist.c14
-rw-r--r--apps/tree.c40
4 files changed, 91 insertions, 40 deletions
diff --git a/apps/dbtree.c b/apps/dbtree.c
index 46acfff3d5..6925fd3f29 100644
--- a/apps/dbtree.c
+++ b/apps/dbtree.c
@@ -59,6 +59,8 @@ static int
albumlen, albumarraylen,
artistlen, initialized = 0;
+static int db_play_folder(struct tree_context* c);
+
int db_init(void)
{
unsigned int version;
@@ -143,7 +145,7 @@ int db_load(struct tree_context* c)
return 0;
}
- c->dentry_size = 2 * sizeof(int);
+ c->dentry_size = 2;
c->dirfull = false;
DEBUGF("db_load(%d, %x, %d)\n", table, extra, c->firstpos);
@@ -157,9 +159,9 @@ int db_load(struct tree_context* c)
case root: {
static const int tables[] = {allartists, allalbums, allsongs};
char* nbuf = (char*)nptr;
- char* labels[3] = { str(LANG_ID3DB_ARTISTS),
- str(LANG_ID3DB_ALBUMS),
- str(LANG_ID3DB_SONGS)};
+ char* labels[] = { str(LANG_ID3DB_ARTISTS),
+ str(LANG_ID3DB_ALBUMS),
+ str(LANG_ID3DB_SONGS)};
for (i=0; i < 3; i++) {
strcpy(nbuf, labels[i]);
@@ -176,6 +178,7 @@ int db_load(struct tree_context* c)
offset = songstart + c->firstpos * (songlen + 12);
itemcount = songcount;
stringlen = songlen;
+ c->dentry_size = 3;
break;
case allalbums:
@@ -226,13 +229,14 @@ int db_load(struct tree_context* c)
offset = safeplace[0];
itemcount = songarraylen;
stringlen = songlen;
+ c->dentry_size = 3;
break;
default:
DEBUGF("Unsupported table %d\n", table);
return -1;
}
- max_items = dcachesize / c->dentry_size;
+ max_items = dcachesize / (c->dentry_size * sizeof(int));
end_of_nbuf -= safeplacelen;
c->dirlength = itemcount;
@@ -256,6 +260,7 @@ int db_load(struct tree_context* c)
for ( i=0; i < max_items; i++ ) {
int rc, skip=0;
+ int intbuf[4];
if (safeplace) {
if (!safeplace[i]) {
@@ -282,8 +287,15 @@ int db_load(struct tree_context* c)
case allsongs:
case songs4album:
/* save offset of this song */
- skip = 12;
dptr[1] = offset;
+
+ rc = read(fd, intbuf, 12);
+ if (rc < 12) {
+ DEBUGF("%d read(%d) returned %d\n", i, 12, rc);
+ return -1;
+ }
+ /* save offset of filename */
+ dptr[2] = BE32(intbuf[2]);
break;
case allalbums:
@@ -309,7 +321,7 @@ int db_load(struct tree_context* c)
c->dirfull = true;
break;
}
- dptr = (void*)dptr + c->dentry_size;
+ dptr = (void*)dptr + c->dentry_size * sizeof(int);
if (!safeplace)
offset += stringlen + skip;
@@ -320,8 +332,9 @@ int db_load(struct tree_context* c)
return i;
}
-void db_enter(struct tree_context* c)
+int db_enter(struct tree_context* c)
{
+ int rc = 0;
int newextra = ((int*)c->dircache)[(c->dircursor + c->dirstart)*2 + 1];
c->dirpos[c->dirlevel] = c->dirstart;
@@ -348,14 +361,11 @@ void db_enter(struct tree_context* c)
c->currextra = newextra;
break;
- case songs4album:
case allsongs:
- splash(HZ,true,"No playing implemented yet");
+ case songs4album:
c->dirlevel--;
-#if 0
- /* find filenames, build playlist, play */
- playlist_create(NULL,NULL);
-#endif
+ if (db_play_folder(c) >= 0)
+ rc = 3;
break;
default:
@@ -363,6 +373,8 @@ void db_enter(struct tree_context* c)
}
c->dirstart = c->dircursor = c->firstpos = 0;
+
+ return rc;
}
void db_exit(struct tree_context* c)
@@ -375,6 +387,41 @@ void db_exit(struct tree_context* c)
c->firstpos = c->pos_history[c->dirlevel];
}
+static int db_play_folder(struct tree_context* c)
+{
+ char buf[MAX_PATH];
+ int rc, i;
+ int filenum = c->dircursor + c->dirstart;
+
+ if (playlist_create(NULL, NULL) < 0) {
+ DEBUGF("Failed creating playlist\n");
+ return -1;
+ }
+
+ /* TODO: add support for very long tables */
+
+ for (i=0; i < c->filesindir; i++) {
+ int pathoffset = ((int*)c->dircache)[i * c->dentry_size + 2];
+ lseek(fd, pathoffset, SEEK_SET);
+ rc = read(fd, buf, sizeof(buf));
+ if (rc < songlen) {
+ DEBUGF("short path read(%d) = %d\n", sizeof(buf), rc);
+ return -2;
+ }
+
+ playlist_insert_track(NULL, buf, PLAYLIST_INSERT, false);
+ }
+
+ if (global_settings.playlist_shuffle)
+ filenum = playlist_shuffle(current_tick, filenum);
+ if (!global_settings.play_selected)
+ filenum = 0;
+
+ playlist_start(filenum,0);
+
+ return 0;
+}
+
#ifdef HAVE_LCD_BITMAP
const char* db_get_icon(struct tree_context* c)
{
diff --git a/apps/dbtree.h b/apps/dbtree.h
index 43c903ccf3..b0c726881f 100644
--- a/apps/dbtree.h
+++ b/apps/dbtree.h
@@ -25,7 +25,7 @@ enum table { invalid, root, allsongs, allalbums, allartists,
albums4artist, songs4album };
int db_init(void);
-void db_enter(struct tree_context* c);
+int db_enter(struct tree_context* c);
void db_exit(struct tree_context* c);
int db_load(struct tree_context* c);
#ifdef HAVE_LCD_BITMAP
diff --git a/apps/playlist.c b/apps/playlist.c
index 651a5afeea..924b9041e8 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -244,7 +244,8 @@ static void new_playlist(struct playlist_info* playlist, const char *dir,
*/
static void create_control(struct playlist_info* playlist)
{
- playlist->control_fd = creat(playlist->control_filename, 0000200);
+ playlist->control_fd = open(playlist->control_filename,
+ O_CREAT|O_RDWR|O_TRUNC);
if (playlist->control_fd < 0)
{
if (check_rockboxdir())
@@ -950,18 +951,19 @@ static int get_filename(struct playlist_info* playlist, int seek,
if (control_file)
mutex_lock(&playlist->control_mutex);
- lseek(fd, seek, SEEK_SET);
- max = read(fd, tmp_buf, buf_length);
+ if (lseek(fd, seek, SEEK_SET) != seek)
+ max = -1;
+ else
+ max = read(fd, tmp_buf, buf_length);
if (control_file)
- mutex_unlock(&playlist->control_mutex);
+ mutex_unlock(&playlist->control_mutex);
}
if (max < 0)
{
if (control_file)
- splash(HZ*2, true,
- str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));
+ splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));
else
splash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
diff --git a/apps/tree.c b/apps/tree.c
index d0f4ab9d68..0809ecbfae 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -365,7 +365,7 @@ static int showdir(void)
int attr = 0;
if (id3db) {
- name = ((char**)tc.dircache)[i * 2];
+ name = ((char**)tc.dircache)[i * tc.dentry_size];
icon = db_get_icon(&tc);
}
else {
@@ -717,23 +717,23 @@ static bool dirbrowse(void)
break;
if (id3db)
- db_enter(&tc);
- else {
- switch (ft_enter(&tc))
- {
- case 1: reload_dir = true; break;
- case 2: reload_root = true; break;
- case 3: start_wps = true; break;
- case 4: exit_func = true; break;
- default: break;
- }
+ i = db_enter(&tc);
+ else
+ i = ft_enter(&tc);
+
+ switch (i)
+ {
+ case 1: reload_dir = true; break;
+ case 2: reload_root = true; break;
+ case 3: start_wps = true; break;
+ case 4: exit_func = true; break;
+ default: break;
+ }
#ifdef HAVE_LCD_BITMAP
- /* maybe we have a new font */
- tree_max_on_screen = recalc_screen_height();
+ /* maybe we have a new font */
+ tree_max_on_screen = recalc_screen_height();
#endif
- }
-
/* make sure cursor is on screen */
while ( tc.dircursor > tree_max_on_screen )
{
@@ -1013,6 +1013,7 @@ static bool dirbrowse(void)
#endif
{
int onplay_result;
+ int attr = 0;
if(!numentries)
onplay_result = onplay(NULL, 0);
@@ -1023,8 +1024,9 @@ static bool dirbrowse(void)
else
snprintf(buf, sizeof buf, "/%s",
dircache[tc.dircursor+tc.dirstart].name);
- onplay_result = onplay(buf,
- dircache[tc.dircursor+tc.dirstart].attr);
+ if (!id3db)
+ attr = dircache[tc.dircursor+tc.dirstart].attr;
+ onplay_result = onplay(buf, attr);
}
switch (onplay_result)
@@ -1166,7 +1168,7 @@ static bool dirbrowse(void)
int attr = 0;
if (id3db)
- name = ((char**)tc.dircache)[lasti * 2];
+ name = ((char**)tc.dircache)[lasti * tc.dentry_size];
else {
struct entry* dc = tc.dircache;
struct entry* e = &dc[lasti];
@@ -1186,7 +1188,7 @@ static bool dirbrowse(void)
thumbnail_time = -1; /* cancel whatever we were about to say */
if (id3db)
- name = ((char**)tc.dircache)[lasti * 2];
+ name = ((char**)tc.dircache)[lasti * tc.dentry_size];
else {
struct entry* dc = tc.dircache;
struct entry* e = &dc[lasti];