A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 253 lines 7.8 kB view raw
1#include <stdlib.h> 2#include <stdio.h> 3 4#define ARTISTLEN 60 5#define ALBUMLEN 64 6#define SONGLEN 120 7#define GENRELEN 28 8#define FILELEN 176 9#define SONGARRAYLEN 715 10#define ALBUMARRAYLEN 186 11 12 13#define BE32(_x_) (((_x_ & 0xff000000) >> 24) | \ 14 ((_x_ & 0x00ff0000) >> 8) | \ 15 ((_x_ & 0x0000ff00) << 8) | \ 16 ((_x_ & 0x000000ff) << 24)) 17#define BE16(_x_) ( ((_x_&0xff00) >> 8) | ((_x_&0xff)<<8)) 18 19struct header { 20 int version; 21 int artiststart; 22 int albumstart; 23 int songstart; 24 int filestart; 25 int artistcount; 26 int albumcount; 27 int songcount; 28 int filecount; 29 int artistlen; 30 int albumlen; 31 int songlen; 32 int genrelen; 33 int filelen; 34 int songarraylen; 35 int albumarraylen; 36 int rundbdirty; 37} header; 38 39struct FileEntry { 40 char name[FILELEN]; 41 int hash; 42 int tagoffset; 43 int rundboffset; 44} FileEntry; 45 46struct SongEntry { 47 char name[SONGLEN]; 48 int artist; 49 int album; 50 int file; 51 char genre[GENRELEN]; 52 short bitrate; 53 short year; 54} SongEntry; 55 56struct ArtistEntry { 57 char name[ARTISTLEN]; 58 int album[ALBUMARRAYLEN]; 59} ArtistEntry; 60 61struct AlbumEntry { 62 char name[ALBUMLEN]; 63 int artist; 64 int song[SONGARRAYLEN]; 65} AlbumEntry; 66 67struct RundbHeader { 68 int version; 69 int entrycount; 70} RundbHeader; 71 72struct RundbEntry { 73 int file; 74 int hash; 75 short rating; 76 short voladj; 77 int playcount; 78 int lastplayed; 79} RundbEntry; 80 81FILE *fp,*fp2; 82 83void showsong(int offset) { 84 fseek(fp,offset,SEEK_SET); 85 fread(&SongEntry,sizeof(struct SongEntry),1,fp); 86 SongEntry.artist=BE32(SongEntry.artist); 87 SongEntry.album=BE32(SongEntry.album); 88 SongEntry.file=BE32(SongEntry.file); 89 SongEntry.year=BE16(SongEntry.year); 90 SongEntry.bitrate=BE16(SongEntry.bitrate); 91 printf("Offset: 0x%x\nName: %s\nArtist: 0x%x\nAlbum: 0x%x\nFile: 0x%x\nGenre: %s\nBitrate: %d\nYear: %d\n\n",offset,SongEntry.name,SongEntry.artist,SongEntry.album,SongEntry.file,SongEntry.genre,SongEntry.bitrate,SongEntry.year); 92} 93 94void showalbum(int offset) { 95 int i; 96 fseek(fp,offset,SEEK_SET); 97 fread(&AlbumEntry,sizeof(struct AlbumEntry),1,fp); 98 AlbumEntry.artist=BE32(AlbumEntry.artist); 99 printf("Offset: 0x%x\nAlbum: %s\nArtist: 0x%x\n",offset,AlbumEntry.name,AlbumEntry.artist); 100 for(i=0;i<header.songarraylen;i++) { 101 AlbumEntry.song[i]=BE32(AlbumEntry.song[i]); 102 printf("Song %d: 0x%x\n",i,AlbumEntry.song[i]); 103 } 104} 105 106void showfile(int offset) { 107 fseek(fp,offset,SEEK_SET); 108 fread(&FileEntry,sizeof(struct FileEntry),1,fp); 109 FileEntry.hash=BE32(FileEntry.hash); 110 FileEntry.tagoffset=BE32(FileEntry.tagoffset); 111 FileEntry.rundboffset=BE32(FileEntry.rundboffset); 112 printf("Offset: 0x%x\nFilename: %s\nHash: 0x%x\nTag: 0x%x\nRunDB: 0x%x\n", 113 offset,FileEntry.name,FileEntry.hash, 114 FileEntry.tagoffset, FileEntry.rundboffset); 115} 116 117void showartist(int offset) { 118 int i; 119 fseek(fp,offset,SEEK_SET); 120 fread(&ArtistEntry,sizeof(struct ArtistEntry),1,fp); 121 printf("Offset: 0x%x\nArtist: %s\n",offset,ArtistEntry.name); 122 for(i=0;i<header.albumarraylen;i++) { 123 ArtistEntry.album[i]=BE32(ArtistEntry.album[i]); 124 printf("Album %d: 0x%x\n",i,ArtistEntry.album[i]); 125 } 126} 127 128void showrundb(int offset) { 129 fseek(fp2,offset,SEEK_SET); 130 fread(&RundbEntry,sizeof(struct RundbEntry),1,fp2); 131 RundbEntry.file=BE32(RundbEntry.file); 132 RundbEntry.hash=BE32(RundbEntry.hash); 133 RundbEntry.playcount=BE32(RundbEntry.playcount); 134 RundbEntry.lastplayed=BE32(RundbEntry.lastplayed); 135 RundbEntry.rating=BE16(RundbEntry.rating); 136 RundbEntry.voladj=BE16(RundbEntry.voladj); 137 printf("Offset: 0x%x\nFileEntry: 0x%x\nHash: 0x%x\nRating: %d\nVoladj: 0x%x\n",offset,RundbEntry.file,RundbEntry.hash,RundbEntry.rating,RundbEntry.voladj); 138 printf("Playcount: 0x%x\nLastplayed: %d\n",RundbEntry.playcount,RundbEntry.lastplayed); 139} 140 141int main() { 142 fp=fopen("rockbox.tagdb","r"); 143 fp2=fopen("rockbox.rundb","r"); 144 int *p,i,temp,temp2,temp3,temp4; 145 if(fp<0) return -1; 146 fread(&header,sizeof(header),1,fp); 147 p=&header; 148 for(i=0;i<17;i++) { 149 *p=BE32(*p); 150 p++; 151 } 152 if(fp2>=0) { 153 fread(&RundbHeader,sizeof(RundbHeader),1,fp2); 154 p=&RundbHeader; 155 for(i=0;i<2;i++) { 156 *p=BE32(*p); 157 p++; 158 } 159 } 160 printf("db version : 0x%x\n",header.version&0xFF); 161 printf("Artist start : 0x%x\n",header.artiststart); 162 printf("Album start : 0x%x\n",header.albumstart); 163 printf("Song start : 0x%x\n",header.songstart); 164 printf("File start : 0x%x\n",header.filestart); 165 printf("Artist count : %d\n",header.artistcount); 166 printf("Album count : %d\n",header.albumcount); 167 printf("Song count : %d\n",header.songcount); 168 printf("File count : %d\n",header.filecount); 169 printf("Artist len : %d\n",header.artistlen); 170 printf("Album len : %d\n",header.albumlen); 171 printf("Song len : %d\n",header.songlen); 172 printf("Genre len : %d\n",header.genrelen); 173 printf("File len : %d\n",header.filelen); 174 printf("Songarraylen : %d\n",header.songarraylen); 175 printf("Albumarraylen : %d\n",header.albumarraylen); 176 printf("Rundb dirty : %d\n",header.rundbdirty); 177 if(fp2>=0) { 178 printf("Rundb version : 0x%x\n",RundbHeader.version&0xFF); 179 printf("Rundb entrys : %d\n",RundbHeader.entrycount); 180 } 181 if( sizeof(struct SongEntry)!=(header.songlen+header.genrelen+16)) { 182 printf("Song Entry Size mismatch.. update the code to correct size.\n"); 183 return; 184 } 185 if(sizeof(struct AlbumEntry)!=(header.albumlen+4+header.songarraylen*4)) { 186printf("Album Entry Size mismatch.. update the code to correct size.\n"); 187 return; 188 } 189 if(sizeof(struct ArtistEntry)!=(header.artistlen+header.albumarraylen*4)) { 190printf("Artist Entry Size mismatch.. update the code to correct size.\n"); 191 return; 192 } 193 if(sizeof(struct FileEntry)!=(header.filelen+12)) { 194 printf("File Entry Size mismatch.. update the code to correct size.\n"); 195 return; 196 } 197 198 do { 199 printf("\n\nShow artist(1)/album(2)/song(3)/file(4)"); 200 if(fp2>=0) printf("/rundb(5)"); 201 printf(" ? "); 202 fflush(stdout); 203 temp=temp2=temp3=0; 204 scanf("%d",&temp); 205 printf("Record (-1 for offset) ? "); 206 fflush(stdout); 207 scanf("%d",&temp2); 208 if(temp2==-1) { 209 printf("Offset ? 0x"); 210 fflush(stdout); 211 scanf("%x",&temp3); 212 } 213 switch(temp) { 214 case 1: 215 if(temp2==-1) 216 showartist(temp3); 217 else 218 showartist(header.artiststart + 219 temp2*sizeof(struct ArtistEntry)); 220 break; 221 case 2: 222 if(temp2==-1) 223 showalbum(temp3); 224 else 225 showalbum(header.albumstart + 226 temp2*sizeof(struct AlbumEntry)); 227 break; 228 case 3: 229 if(temp2==-1) 230 showsong(temp3); 231 else 232 showsong(header.songstart + 233 temp2*sizeof(struct SongEntry)); 234 break; 235 case 4: 236 if(temp2==-1) 237 showfile(temp3); 238 else 239 showfile(header.filestart + 240 temp2*sizeof(struct FileEntry)); 241 break; 242 case 5: if(temp2==-1) 243 showrundb(temp3); 244 else 245 showrundb(8+temp2*sizeof(struct RundbEntry)); 246 break; 247 default: 248 return; 249 break; 250 } 251 } while(1); 252 fclose(fp); 253}