From: <ny...@us...> - 2007-01-18 17:34:30
|
Revision: 271 http://svn.sourceforge.net/pmplib/?rev=271&view=rev Author: nyaochi Date: 2007-01-18 09:34:30 -0800 (Thu, 18 Jan 2007) Log Message: ----------- Experimental code for generating iriver E10 playlists. Playlists for iriver E10 are actually stored in the database: *.plp files are found to be dummy. Although I had to change a DWORD value in db.dic, the playlists worked on my player. I still need to improve dic.c and dat.c to handle large number of files. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-18 17:34:30 UTC (rev 271) @@ -452,6 +452,12 @@ } } + /* Read Music page(s) */ + dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * 2); + while (ph.next_page) { + dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * (ph.next_page - 1)); + } + free(buffer); return 0; } @@ -460,7 +466,7 @@ { uint32_t i = 0; page_header_t ph; - long buffer_size = PAGESIZE * 2; + long buffer_size = PAGESIZE * 3; uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); if (!buffer) { @@ -506,6 +512,23 @@ dic->header.num_dat_pages += 1; } + /* Write References page(s) */ + i = 0; + memset(&ph, 0, sizeof(ph)); + ph.next_page = dic->header.num_dat_pages + 2; + dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * 2); + dic->header.num_dat_pages += 1; + while (ph.next_page) { + uint32_t page = ph.next_page++; + buffer_size = PAGESIZE * page; + buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); + i += ph.num_entries; + dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * (page - 1)); + dic->header.num_dat_pages += 1; + } + + if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { free(buffer); return 1; @@ -524,10 +547,39 @@ fprintf(fp, "MUSIC = {\n"); dat_list_dump(&dat->musics, &dic->music, fp); fprintf(fp, "}\n"); + fprintf(fp, "REFERENCES = {\n"); + dat_list_dump(&dat->references, &dic->references, fp); + fprintf(fp, "}\n"); } +static uint32_t findfile(dat_t* dat, const ucs2char_t *filename) +{ + int i; + const ucs2char_t *filepart = NULL; + ucs2char_t *pathname = alloca(sizeof(ucs2char_t) * (ucs2len(filename) + 1)); + + filepart = ucs2rchr(filename, '/'); + if (!filepart) { + filepart = filename; + } else { + filepart++; + } + + ucs2ncpy(pathname, filename, (filepart-filename)); + pathname[filepart-filename] = 0; + + for (i = 0;i < dat->musics.num_entries;++i) { + dat_entry_t* entry = &dat->musics.entries[i]; + if (ucs2icmp(entry->fields[IP3DBF_MUSIC_FILENAME].value.str, filepart) == 0 && + ucs2icmp(entry->fields[IP3DBF_MUSIC_FILEPATH].value.str, pathname) == 0) { + return entry->fields[IP3DBF_MUSIC_UID].value.dword; + } + } + return 0; +} + typedef struct { ucs2char_t* path; uint32_t uid; @@ -624,7 +676,7 @@ return p ? p+1 : NULL; } -void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists) +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, ip3db_playlist_t* playlists, int num_playlists) { /* Procedure: * 1) Construct the object chunk and attach music records with Object UIDs. @@ -659,6 +711,7 @@ static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; + dat_list_t* datr = &dat->references; uint32_t num_objects = num_records + num_playlists; object_record_t *objects = (object_record_t*)malloc(sizeof(object_record_t) * num_objects); dircache_t dc; @@ -668,6 +721,7 @@ /* Clear all entries. */ dat_list_finish(dato); dat_list_finish(datm); + dat_list_finish(datr); dat_uidmap_finish(dat->objects_uidmap); /* Append an entry for the root directory. */ @@ -763,18 +817,31 @@ ip3db_variant_set_dword(&entry->fields[IP3DBF_MUSIC_UID], uid); } else if (objects[i].filetype == 4) { /* Playlist file. */ - const ip3db_playlist_t* playlist = &playlists[objects[i].index]; + ip3db_playlist_t* pl = &playlists[objects[i].index]; - uid = dato->num_entries; + pl->uid = dato->num_entries; entry = dat_list_expand(dato); dat_entry_init(entry, &dic->objects); - ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], pl->uid); ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_PARENTUID], puid); ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 4); ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], file); } } + /* Loop for playlists. */ + for (i = 0;i < num_playlists;++i) { + const ip3db_playlist_t* pl = &playlists[i]; + for (j = 0;j < pl->num_entries;++j) { + entry = dat_list_expand(datr); + dat_entry_init(entry, &dic->references); + + ip3db_variant_set_dword(&entry->fields[IP3DBF_REFERENCES_PARENTCLUSTER], pl->uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_REFERENCES_CHILDCLUSTER], findfile(dat, pl->entries[j])); + ip3db_variant_set_word(&entry->fields[IP3DBF_REFERENCES_FILEFORMAT], 0x3009); + } + } + dircache_finish(&dc); dat->objects_uidmap = dat_uidmap_create(&dat->objects); Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2007-01-18 17:34:30 UTC (rev 271) @@ -40,6 +40,7 @@ struct tag_dat_t { dat_list_t objects; dat_list_t musics; + dat_list_t references; sort_index_t* objects_uidmap; }; @@ -48,6 +49,6 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); int dat_write(dat_t* dat, dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); -void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists); +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, ip3db_playlist_t* playlists, int num_playlists); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2007-01-18 17:34:30 UTC (rev 271) @@ -57,6 +57,11 @@ {0, 0x043E, {IP3DBF_MUSIC_ALBUM, IP3DBF_MUSIC_TRACKNUMBER, IP3DBF_MUSIC_NONE}}, }; +static dic_index_t references_indices[] = { + {0, 0x0764, {IP3DBF_REFERENCES_PARENTCLUSTER, IP3DBF_REFERENCES_NONE, IP3DBF_REFERENCES_NONE}}, + {0, 0x078C, {IP3DBF_REFERENCES_CHILDCLUSTER, IP3DBF_REFERENCES_NONE, IP3DBF_REFERENCES_NONE}}, +}; + static dic_index_t objects_indices[] = { {0, 0x099A, {IP3DBF_OBJECTS_UID, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, {0, 0x09F0, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, @@ -138,6 +143,11 @@ dic->music.fields = (dic_field_t*)calloc(dic->music.num_fields, sizeof(dic_field_t)); dic->music.num_indices = sizeof(music_indices) / sizeof(music_indices[0]); dic->music.indices = music_indices; + dic_table_init(&dic->references); + dic->references.num_fields = IP3DBF_REFERENCES_LAST; + dic->references.fields = (dic_field_t*)calloc(dic->references.num_fields, sizeof(dic_field_t)); + dic->references.num_indices = sizeof(references_indices) / sizeof(references_indices[0]); + dic->references.indices = references_indices; dic_table_init(&dic->objects); dic->objects.num_fields = IP3DBF_OBJECTS_LAST; dic->objects.fields = (dic_field_t*)calloc(dic->objects.num_fields, sizeof(dic_field_t)); @@ -159,6 +169,7 @@ { if (dic) { dic_table_finish(&dic->music); + dic_table_finish(&dic->references); dic_table_finish(&dic->objects); free(dic->buffer); free(dic); @@ -207,6 +218,12 @@ next = dic->music.fields[i].next; } + next = 0x00000764; + for (i = 0;i < dic->references.num_fields;++i) { + dic_field_serialize(buffer + next, &dic->references.fields[i], is_storing); + next = dic->references.fields[i].next; + } + next = 0x0000099A; for (i = 0;i < dic->objects.num_fields;++i) { dic_field_serialize(buffer + next, &dic->objects.fields[i], is_storing); @@ -218,6 +235,11 @@ serialize_uint32be(buffer + offset, &dic->music.indices[i].idx_root, is_storing); } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t offset = dic->references.indices[i].offset + sizeof(uint32_t) * 2; + serialize_uint32be(buffer + offset, &dic->references.indices[i].idx_root, is_storing); + } + for (i = 0;i < dic->objects.num_indices;++i) { uint32_t offset = dic->objects.indices[i].offset + sizeof(uint32_t) * 2; serialize_uint32be(buffer + offset, &dic->objects.indices[i].idx_root, is_storing); @@ -231,8 +253,13 @@ fprintf(fp, "===== db.dic =====\n"); fprintf(fp, "MUSIC = {\n"); dic_table_dump(&dic->music, fp); + fprintf(fp, "}\n"); + fprintf(fp, "REFERENCES = {\n"); + dic_table_dump(&dic->references, fp); + fprintf(fp, "}\n"); fprintf(fp, "OBJECTS = {\n"); dic_table_dump(&dic->objects, fp); + fprintf(fp, "}\n"); fprintf(fp, "\n"); } @@ -243,6 +270,9 @@ case IP3DBIDX_MUSIC: indices = dic->music.indices; break; + case IP3DBIDX_REFERENCES: + indices = dic->references.indices; + break; case IP3DBIDX_OBJECTS: indices = dic->objects.indices; break; @@ -261,6 +291,9 @@ case IP3DBIDX_MUSIC: indices = dic->music.indices; break; + case IP3DBIDX_REFERENCES: + indices = dic->references.indices; + break; case IP3DBIDX_OBJECTS: indices = dic->objects.indices; break; @@ -280,6 +313,9 @@ case IP3DBIDX_MUSIC: tbl = &dic->music; break; + case IP3DBIDX_REFERENCES: + tbl = &dic->references; + break; case IP3DBIDX_OBJECTS: tbl = &dic->objects; break; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2007-01-18 17:34:30 UTC (rev 271) @@ -54,6 +54,7 @@ struct tag_dic_t { dic_header_t header; dic_table_t music; + dic_table_t references; dic_table_t objects; uint8_t* buffer; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-18 17:34:30 UTC (rev 271) @@ -700,11 +700,21 @@ /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); - from_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + if (idx_root) { + from_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + } } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); + if (idx_root) { + from_be_avltree(idx->avl, idx_root, &dic->references, i, 0); + } + } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); - from_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + if (idx_root) { + from_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + } } return 0; } @@ -728,6 +738,10 @@ uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); to_be_avltree(idx->avl, idx_root, &dic->music, i, 0); } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); + to_be_avltree(idx->avl, idx_root, &dic->references, i, 0); + } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); to_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); @@ -756,6 +770,15 @@ fprintf(fpo, "]\n"); avl_dump(idx->avl, idx_root, &dic->music, i, 0, fpo); } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); + fprintf(fpo, "["); + dic_repr_index(dic, IP3DBIDX_REFERENCES, i, fpo); + fprintf(fpo, "]\n"); + if (idx_root) { + avl_dump(idx->avl, idx_root, &dic->references, i, 0, fpo); + } + } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); fprintf(fpo, "["); @@ -822,6 +845,12 @@ dic_set_idxroot(dic, IP3DBIDX_MUSIC, index, root); } + for (index = 0;index < dic->references.num_indices;++index) { + uint32_t root = 0; + idx_construct_index(idx, &dic->references, &dat->references, &root, index); + dic_set_idxroot(dic, IP3DBIDX_REFERENCES, index, root); + } + for (index = 0;index < dic->objects.num_indices;++index) { uint32_t root = 0; idx_construct_index(idx, &dic->objects, &dat->objects, &root, index); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-18 17:34:30 UTC (rev 271) @@ -57,6 +57,7 @@ ucs2char_t* filename; int num_entries; ucs2char_t **entries; + uint32_t uid; } ip3db_playlist_t; /** @@ -94,6 +95,15 @@ IP3DBF_MUSIC_LAST, }; +enum { + IP3DBF_REFERENCES_NONE = -1, + IP3DBF_REFERENCES_BEGIN = 0, + IP3DBF_REFERENCES_PARENTCLUSTER = 0, + IP3DBF_REFERENCES_CHILDCLUSTER, + IP3DBF_REFERENCES_FILEFORMAT, + IP3DBF_REFERENCES_LAST, +}; + /** * A music record. */ @@ -125,6 +135,7 @@ enum { IP3DBIDX_NONE = -1, IP3DBIDX_MUSIC = 0, + IP3DBIDX_REFERENCES, IP3DBIDX_OBJECTS, IP3DBIDX_LAST, }; @@ -150,6 +161,14 @@ IP3DBIDX_MUSIC_LAST, }; +enum { + IP3DBIDX_REFERENCES_NONE = -1, + IP3DBIDX_REFERENCES_BEGIN = 0, + IP3DBIDX_REFERENCES_PARENTCLUSTER = 0, + IP3DBIDX_REFERENCES_CHILDCLUSTER, + IP3DBIDX_REFERENCES_LAST, +}; + /** * Indices for the object chunk. */ Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 17:34:30 UTC (rev 271) @@ -652,7 +652,11 @@ dst->num_entries = src->num_entries; dst->entries = (ucs2char_t**)ucs2malloc(sizeof(ucs2char_t*) * src->num_entries); for (j = 0;j < src->num_entries;++j) { - dst->entries[j] = ucs2dup(src->entries[j]); + ucs2char_t filename[MAX_PATH]; + + ucs2cpy(filename, filepath_skipdrive(src->entries[j], music->pmp->info.path_to_root)); + filepath_slash(filename); + dst->entries[j] = ucs2dup(filename); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |