From 30d8f6192ff8217afb7d9bf0722dfd2c66a4d599 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Thu, 20 Jan 2005 16:24:26 +0000 Subject: Added music playing from ID3 browser. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5616 a1c6a512-1295-4272-9138-f99709370657 --- apps/dbtree.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++----------- apps/dbtree.h | 2 +- apps/playlist.c | 14 ++++++----- apps/tree.c | 40 +++++++++++++++--------------- 4 files changed, 91 insertions(+), 40 deletions(-) (limited to 'apps') 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]; -- cgit v1.2.3