| 1 | /*
|
|---|
| 2 | ** SonyDB.cpp
|
|---|
| 3 | **
|
|---|
| 4 | ** Made by (julien)
|
|---|
| 5 | */
|
|---|
| 6 |
|
|---|
| 7 | #include <stdio.h>
|
|---|
| 8 | #include <fstream>
|
|---|
| 9 | #include "sonydb.h"
|
|---|
| 10 |
|
|---|
| 11 | using namespace std;
|
|---|
| 12 |
|
|---|
| 13 | #ifndef _WIN32
|
|---|
| 14 | #define strnicmp(x, y, z) strncasecmp(x, y, z)
|
|---|
| 15 | #define stricmp(x, y) strcasecmp(x, y)
|
|---|
| 16 | #endif
|
|---|
| 17 |
|
|---|
| 18 | //SORT function for song vectors
|
|---|
| 19 | #define SKIP_THE_AND_WHITESPACE(x) { while (!isalnum(*x) && *x) x++; if (!strnicmp(x,"the ",4)) x+=4; while (*x == ' ') x++; }
|
|---|
| 20 | static int STRCMP_NULLOK(const char *pa, const char *pb)
|
|---|
| 21 | {
|
|---|
| 22 | if (!pa) pa="";
|
|---|
| 23 | else SKIP_THE_AND_WHITESPACE(pa)
|
|---|
| 24 |
|
|---|
| 25 | if (!pb) pb="";
|
|---|
| 26 | else SKIP_THE_AND_WHITESPACE(pb)
|
|---|
| 27 | return stricmp(pa,pb);
|
|---|
| 28 | }
|
|---|
| 29 |
|
|---|
| 30 | static int STRCMP2_NULLOK(const char *pa, const char *pb)
|
|---|
| 31 | {
|
|---|
| 32 | if (!pa) pa="";
|
|---|
| 33 | if (!pb) pb="";
|
|---|
| 34 | return stricmp(pa,pb);
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | static int STRNCMP_NULLOK(const char *pa, const char *pb, int size)
|
|---|
| 38 | {
|
|---|
| 39 | if (!pa) pa="";
|
|---|
| 40 | if (!pb) pb="";
|
|---|
| 41 | return strnicmp(pa, pb, size);
|
|---|
| 42 | }
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 | SonyDb::SonyDb()
|
|---|
| 47 | {
|
|---|
| 48 | this->driveLetter = 0;
|
|---|
| 49 | this->deviceName = (char*)calloc(sizeof(char), 256);
|
|---|
| 50 | this->trackListLoaded = false;
|
|---|
| 51 | this->nbTrackToAdd = 0;
|
|---|
| 52 | this->nbTrackToDel = 0;
|
|---|
| 53 | this->lastTrackIndex = 1;
|
|---|
| 54 | this->codeType = ENCODING_USE_NONE;
|
|---|
| 55 | this->copying = false;
|
|---|
| 56 | this->copyIndex = 0;
|
|---|
| 57 | this->copyPercent = 0;
|
|---|
| 58 | this->addTrackTotalByte = 0;
|
|---|
| 59 | this->delTrackTotalByte = 0;
|
|---|
| 60 | this->freeSpaceDisk = 0;
|
|---|
| 61 | this->neededSpace = 0;
|
|---|
| 62 | this->totalDiskSpaceValue = 0;
|
|---|
| 63 | this->useAllTags = false;
|
|---|
| 64 |
|
|---|
| 65 |
|
|---|
| 66 | totalDiskSpace = (char*)calloc(sizeof(char), 64);
|
|---|
| 67 | freeDiskSpaceAfterApply = (char*)calloc(sizeof(char), 64);
|
|---|
| 68 | totalUsedSpaceAfterApply = (char*)calloc(sizeof(char), 64);
|
|---|
| 69 | delTrackTotalByteString = (char*)calloc(sizeof(char), 64);
|
|---|
| 70 | addTrackTotalByteString = (char*)calloc(sizeof(char), 64);
|
|---|
| 71 | neededSpace = (char*)calloc(sizeof(char), 64);
|
|---|
| 72 |
|
|---|
| 73 | //debug
|
|---|
| 74 | //fp = fopen("c:/Debug_ml_sony.log", "ab");
|
|---|
| 75 | //fprintf(fp,"+++++++++++++\n");
|
|---|
| 76 | //fflush(fp);
|
|---|
| 77 | fp = stderr;
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | //clean the song list before living
|
|---|
| 81 | SonyDb::~SonyDb()
|
|---|
| 82 | {
|
|---|
| 83 | //free track list
|
|---|
| 84 | freeAllTracks();
|
|---|
| 85 |
|
|---|
| 86 | //free device Name
|
|---|
| 87 | free(this->deviceName);
|
|---|
| 88 |
|
|---|
| 89 | //free disk space info
|
|---|
| 90 | free(totalDiskSpace);
|
|---|
| 91 | free(totalUsedSpaceAfterApply);
|
|---|
| 92 | free(freeDiskSpaceAfterApply);
|
|---|
| 93 | free(delTrackTotalByteString);
|
|---|
| 94 | free(addTrackTotalByteString);
|
|---|
| 95 | free(neededSpace);
|
|---|
| 96 |
|
|---|
| 97 | //debug
|
|---|
| 98 | //fclose(fp);
|
|---|
| 99 |
|
|---|
| 100 | if (driveLetter) free(driveLetter);
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | //free track list
|
|---|
| 104 | void SonyDb::freeAllTracks()
|
|---|
| 105 | {
|
|---|
| 106 | for (vector<Song>::iterator i = songs.begin(); i != songs.end(); i++)
|
|---|
| 107 | {
|
|---|
| 108 | if ((*i).album) free((*i).album);
|
|---|
| 109 | if ((*i).artist) free((*i).artist);
|
|---|
| 110 | if ((*i).title) free((*i).title);
|
|---|
| 111 | if ((*i).genre) free((*i).genre);
|
|---|
| 112 | if ((*i).filename) free((*i).filename);
|
|---|
| 113 | }
|
|---|
| 114 | while (songs.size() > 0)
|
|---|
| 115 | songs.pop_back();
|
|---|
| 116 | }
|
|---|
| 117 |
|
|---|
| 118 | //free playlist
|
|---|
| 119 | void SonyDb::freeAllPlaylist()
|
|---|
| 120 | {
|
|---|
| 121 | vector<Song *> plSongs;
|
|---|
| 122 |
|
|---|
| 123 | for (vector<Playlist>::iterator pl = playlist.begin(); pl != playlist.end(); pl++)
|
|---|
| 124 | {
|
|---|
| 125 | plSongs = (*pl).songs;
|
|---|
| 126 | for (vector<Song*>::iterator i = plSongs.begin(); i != plSongs.end(); i++)
|
|---|
| 127 | {
|
|---|
| 128 | if ((*i)->statusOfSong == MODIFIED)
|
|---|
| 129 | {
|
|---|
| 130 | free((*i)->filename);
|
|---|
| 131 | free((*i)->artist);
|
|---|
| 132 | free((*i)->album);
|
|---|
| 133 | free((*i)->genre);
|
|---|
| 134 | free((*i)->title);
|
|---|
| 135 | }
|
|---|
| 136 | }
|
|---|
| 137 | }
|
|---|
| 138 | while (playlist.size() > 0)
|
|---|
| 139 | playlist.pop_back();
|
|---|
| 140 | }
|
|---|
| 141 |
|
|---|
| 142 | int SonyDb::getId()
|
|---|
| 143 | {
|
|---|
| 144 | return (this->id);
|
|---|
| 145 | }
|
|---|
| 146 |
|
|---|
| 147 | void SonyDb::setId(int newId)
|
|---|
| 148 | {
|
|---|
| 149 | this->id = newId;
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | void SonyDb::setUseAllTags(bool value)
|
|---|
| 153 | {
|
|---|
| 154 | useAllTags = value;
|
|---|
| 155 | }
|
|---|
| 156 |
|
|---|
| 157 | bool SonyDb::getUseAllTags()
|
|---|
| 158 | {
|
|---|
| 159 | return (useAllTags);
|
|---|
| 160 | }
|
|---|
| 161 |
|
|---|
| 162 | vector<Playlist*> SonyDb::getPlaylist()
|
|---|
| 163 | {
|
|---|
| 164 | vector<Playlist*> ret;
|
|---|
| 165 | for (vector<Playlist>::iterator pl = playlist_temporary.begin(); pl != playlist_temporary.end(); pl++)
|
|---|
| 166 | ret.push_back(&(*pl));
|
|---|
| 167 | for (vector<Playlist>::iterator pl2 = playlist.begin(); pl2 != playlist.end(); pl2++)
|
|---|
| 168 | ret.push_back(&(*pl2));
|
|---|
| 169 | return (ret);
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | vector<Song*> SonyDb::getSongsInPlaylist(int source)
|
|---|
| 173 | {
|
|---|
| 174 | vector<Song*> ret;
|
|---|
| 175 | Song *p;
|
|---|
| 176 | vector<Song *> plSongs;
|
|---|
| 177 | vector<Playlist>::iterator playlistBegin;
|
|---|
| 178 | vector<Playlist>::iterator playlistEnd;
|
|---|
| 179 |
|
|---|
| 180 | if (this->copying)
|
|---|
| 181 | {
|
|---|
| 182 | playlistBegin = playlist_temporary.begin();
|
|---|
| 183 | playlistEnd = playlist_temporary.end();
|
|---|
| 184 | }
|
|---|
| 185 | else
|
|---|
| 186 | {
|
|---|
| 187 | playlistBegin = playlist.begin();
|
|---|
| 188 | playlistEnd = playlist.end();
|
|---|
| 189 | }
|
|---|
| 190 |
|
|---|
| 191 | for (vector<Playlist>::iterator pl = playlistBegin; pl != playlistEnd; pl++)
|
|---|
| 192 | {
|
|---|
| 193 | if (pl->index == source)
|
|---|
| 194 | {
|
|---|
| 195 | plSongs = pl->songs;
|
|---|
| 196 | for (vector<Song*>::iterator i = plSongs.begin(); i != plSongs.end(); i++)
|
|---|
| 197 | {
|
|---|
| 198 | if ((*i)->statusOfSong != EMPTYTRACK)
|
|---|
| 199 | {
|
|---|
| 200 | //new song
|
|---|
| 201 | p = (Song *)calloc(sizeof(Song),1);
|
|---|
| 202 | p->filename = strdup((*i)->filename);
|
|---|
| 203 | p->artist = strdup((*i)->artist);
|
|---|
| 204 | p->album = strdup((*i)->album);
|
|---|
| 205 | p->genre = strdup((*i)->genre);
|
|---|
| 206 | p->title = strdup((*i)->title);
|
|---|
| 207 |
|
|---|
| 208 | p->track_nr = (*i)->track_nr;
|
|---|
| 209 | p->songlen = (*i)->songlen;
|
|---|
| 210 | p->year = (*i)->year;
|
|---|
| 211 | p->statusOfSong = (*i)->statusOfSong;
|
|---|
| 212 | p->sonyDbOrder = (*i)->sonyDbOrder;
|
|---|
| 213 | ret.push_back(p);
|
|---|
| 214 | }
|
|---|
| 215 | }
|
|---|
| 216 | return (ret);
|
|---|
| 217 | }
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | //not found in temporary playlists so try in other playlist
|
|---|
| 221 | playlistBegin = playlist.begin();
|
|---|
| 222 | playlistEnd = playlist.end();
|
|---|
| 223 |
|
|---|
| 224 | for (vector<Playlist>::iterator pl2 = playlistBegin; pl2 != playlistEnd; pl2++)
|
|---|
| 225 | {
|
|---|
| 226 | if (pl2->index == source)
|
|---|
| 227 | {
|
|---|
| 228 | plSongs = pl2->songs;
|
|---|
| 229 | for (vector<Song*>::iterator i = plSongs.begin(); i != plSongs.end(); i++)
|
|---|
| 230 | {
|
|---|
| 231 | if ((*i)->statusOfSong != EMPTYTRACK)
|
|---|
| 232 | {
|
|---|
| 233 | //new song
|
|---|
| 234 | p = (Song *)calloc(sizeof(Song),1);
|
|---|
| 235 | p->filename = strdup((*i)->filename);
|
|---|
| 236 | p->artist = strdup((*i)->artist);
|
|---|
| 237 | p->album = strdup((*i)->album);
|
|---|
| 238 | p->genre = strdup((*i)->genre);
|
|---|
| 239 | p->title = strdup((*i)->title);
|
|---|
| 240 |
|
|---|
| 241 | p->track_nr = (*i)->track_nr;
|
|---|
| 242 | p->songlen = (*i)->songlen;
|
|---|
| 243 | p->year = (*i)->year;
|
|---|
| 244 | p->statusOfSong = (*i)->statusOfSong;
|
|---|
| 245 | p->sonyDbOrder = (*i)->sonyDbOrder;
|
|---|
| 246 | ret.push_back(p);
|
|---|
| 247 | }
|
|---|
| 248 | }
|
|---|
| 249 | return (ret);
|
|---|
| 250 | }
|
|---|
| 251 | }
|
|---|
| 252 |
|
|---|
| 253 | return (ret);
|
|---|
| 254 | }
|
|---|
| 255 |
|
|---|
| 256 | bool SonyDb::deletePlaylist(int source, bool removeSongs)
|
|---|
| 257 | {
|
|---|
| 258 | vector<Song *> plSongs;
|
|---|
| 259 |
|
|---|
| 260 | for (vector<Playlist>::iterator pl = playlist.begin(); pl != playlist.end(); pl++)
|
|---|
| 261 | {
|
|---|
| 262 | if (pl->index == source)
|
|---|
| 263 | {
|
|---|
| 264 | plSongs = pl->songs;
|
|---|
| 265 | if (removeSongs)
|
|---|
| 266 | {
|
|---|
| 267 | for (vector<Song*>::iterator song = plSongs.begin(); song != plSongs.end(); song++)
|
|---|
| 268 | {
|
|---|
| 269 | delSong(*song);
|
|---|
| 270 | }
|
|---|
| 271 | }
|
|---|
| 272 | pl->songs.clear();
|
|---|
| 273 | playlist.erase(pl);
|
|---|
| 274 | return (true);
|
|---|
| 275 | }
|
|---|
| 276 | }
|
|---|
| 277 | return (false);
|
|---|
| 278 |
|
|---|
| 279 | }
|
|---|
| 280 |
|
|---|
| 281 | vector<Song*> SonyDb::getSongs()
|
|---|
| 282 | {
|
|---|
| 283 | vector<Song*> ret;
|
|---|
| 284 | Song *p;
|
|---|
| 285 |
|
|---|
| 286 | if (this->copying)
|
|---|
| 287 | {
|
|---|
| 288 | for (vector<Song>::iterator i = songs_temporary.begin(); i != songs_temporary.end(); i++)
|
|---|
| 289 | {
|
|---|
| 290 | if ((*i).statusOfSong != EMPTYTRACK)
|
|---|
| 291 | {
|
|---|
| 292 | //new song
|
|---|
| 293 | p = (Song *)calloc(sizeof(Song),1);
|
|---|
| 294 | p->filename = strdup((*i).filename);
|
|---|
| 295 | p->artist = strdup((*i).artist);
|
|---|
| 296 | p->album = strdup((*i).album);
|
|---|
| 297 | p->genre = strdup((*i).genre);
|
|---|
| 298 | p->title = strdup((*i).title);
|
|---|
| 299 |
|
|---|
| 300 | p->track_nr = (*i).track_nr;
|
|---|
| 301 | p->songlen = (*i).songlen;
|
|---|
| 302 | p->year = (*i).year;
|
|---|
| 303 | p->statusOfSong = (*i).statusOfSong;
|
|---|
| 304 | p->sonyDbOrder = (*i).sonyDbOrder;
|
|---|
| 305 | ret.push_back(p);
|
|---|
| 306 | }
|
|---|
| 307 | }
|
|---|
| 308 | }
|
|---|
| 309 | else
|
|---|
| 310 | {
|
|---|
| 311 | for (vector<Song>::iterator i = songs.begin(); i != songs.end(); i++)
|
|---|
| 312 | {
|
|---|
| 313 | if ((*i).statusOfSong != EMPTYTRACK)
|
|---|
| 314 | {
|
|---|
| 315 | //new song
|
|---|
| 316 | p = (Song *)calloc(sizeof(Song),1);
|
|---|
| 317 | p->filename = strdup((*i).filename);
|
|---|
| 318 | p->artist = strdup((*i).artist);
|
|---|
| 319 | p->album = strdup((*i).album);
|
|---|
| 320 | p->genre = strdup((*i).genre);
|
|---|
| 321 | p->title = strdup((*i).title);
|
|---|
| 322 |
|
|---|
| 323 | p->track_nr = (*i).track_nr;
|
|---|
| 324 | p->songlen = (*i).songlen;
|
|---|
| 325 | p->year = (*i).year;
|
|---|
| 326 | p->statusOfSong = (*i).statusOfSong;
|
|---|
| 327 | p->sonyDbOrder = (*i).sonyDbOrder;
|
|---|
| 328 | ret.push_back(p);
|
|---|
| 329 | }
|
|---|
| 330 | }
|
|---|
| 331 | }
|
|---|
| 332 | return (ret);
|
|---|
| 333 | }
|
|---|
| 334 |
|
|---|
| 335 |
|
|---|
| 336 | int SonyDb::progressIndex()
|
|---|
| 337 | {
|
|---|
| 338 | return (this->copyIndex);
|
|---|
| 339 | }
|
|---|
| 340 |
|
|---|
| 341 |
|
|---|
| 342 | int SonyDb::isTrackListLoaded()
|
|---|
| 343 | {
|
|---|
| 344 | return (this->trackListLoaded);
|
|---|
| 345 | }
|
|---|
| 346 |
|
|---|
| 347 | int SonyDb::getNbTrackToDel()
|
|---|
| 348 | {
|
|---|
| 349 | return (this->nbTrackToDel);
|
|---|
| 350 | }
|
|---|
| 351 |
|
|---|
| 352 | int SonyDb::getNbTrackToAdd()
|
|---|
| 353 | {
|
|---|
| 354 | return (this->nbTrackToAdd);
|
|---|
| 355 | }
|
|---|
| 356 |
|
|---|
| 357 | bool SonyDb::updSong(Song *songToUpd)
|
|---|
| 358 | {
|
|---|
| 359 | if (this->copying)
|
|---|
| 360 | {
|
|---|
| 361 | for (vector<Song>::iterator song = songs_temporary.begin(); song != songs_temporary.end(); song++)
|
|---|
| 362 | {
|
|---|
| 363 | //song is the same
|
|---|
| 364 | if (song->sonyDbOrder == songToUpd->sonyDbOrder)
|
|---|
| 365 | {
|
|---|
| 366 | if (song->statusOfSong != REMOVE_FROM_DEVICE &&
|
|---|
| 367 | song->statusOfSong != EMPTYTRACK)
|
|---|
| 368 | {
|
|---|
| 369 | song->artist = strdup(songToUpd->artist);
|
|---|
| 370 | song->album = strdup(songToUpd->album);
|
|---|
| 371 | song->genre = strdup(songToUpd->genre);
|
|---|
| 372 | song->title = strdup(songToUpd->title);
|
|---|
| 373 |
|
|---|
| 374 | song->track_nr = songToUpd->track_nr;
|
|---|
| 375 | song->songlen = songToUpd->songlen;
|
|---|
| 376 | song->year = songToUpd->year;
|
|---|
| 377 | return (true);
|
|---|
| 378 | }
|
|---|
| 379 | return (false);
|
|---|
| 380 | }
|
|---|
| 381 | }
|
|---|
| 382 | }
|
|---|
| 383 | else
|
|---|
| 384 | {
|
|---|
| 385 | for (vector<Song>::iterator song = songs.begin(); song != songs.end(); song++)
|
|---|
| 386 | {
|
|---|
| 387 | //song is the same
|
|---|
| 388 | if (song->sonyDbOrder == songToUpd->sonyDbOrder)
|
|---|
| 389 | {
|
|---|
| 390 | if (song->statusOfSong != REMOVE_FROM_DEVICE &&
|
|---|
| 391 | song->statusOfSong != EMPTYTRACK)
|
|---|
| 392 | {
|
|---|
| 393 | song->artist = strdup(songToUpd->artist);
|
|---|
| 394 | song->album = strdup(songToUpd->album);
|
|---|
| 395 | song->genre = strdup(songToUpd->genre);
|
|---|
| 396 | song->title = strdup(songToUpd->title);
|
|---|
| 397 |
|
|---|
| 398 | song->track_nr = songToUpd->track_nr;
|
|---|
| 399 | song->songlen = songToUpd->songlen;
|
|---|
| 400 | song->year = songToUpd->year;
|
|---|
| 401 | return (true);
|
|---|
| 402 | }
|
|---|
| 403 | return (false);
|
|---|
| 404 | }
|
|---|
| 405 | }
|
|---|
| 406 | }
|
|---|
| 407 | return (0);
|
|---|
| 408 | }
|
|---|
| 409 |
|
|---|
| 410 | int SonyDb::delSong(Song *songToDel)
|
|---|
| 411 | {
|
|---|
| 412 | if (this->copying)
|
|---|
| 413 | {
|
|---|
| 414 | for (vector<Song>::iterator song = songs_temporary.begin(); song != songs_temporary.end(); song++)
|
|---|
| 415 | {
|
|---|
| 416 | //song is the same
|
|---|
| 417 | if ((STRCMP2_NULLOK((*song).album, (songToDel)->album) == 0) &&
|
|---|
| 418 | (STRCMP2_NULLOK((*song).artist, (songToDel)->artist) == 0) &&
|
|---|
| 419 | (STRCMP2_NULLOK((*song).title, (songToDel)->title) == 0))
|
|---|
| 420 | {
|
|---|
| 421 | if ((*song).statusOfSong == ADD_TO_DEVICE) //song is not yet on the device
|
|---|
| 422 | {
|
|---|
| 423 | //remove it from the list
|
|---|
| 424 | songs_temporary.erase(song);
|
|---|
| 425 | nbTrackToAdd--;
|
|---|
| 426 | //size of the song
|
|---|
| 427 | struct stat results;
|
|---|
| 428 | if (stat((*songToDel).filename, &results) == 0)
|
|---|
| 429 | addTrackTotalByte -= results.st_size;
|
|---|
| 430 | return (2);
|
|---|
| 431 | }
|
|---|
| 432 | }
|
|---|
| 433 | }
|
|---|
| 434 | }
|
|---|
| 435 | else
|
|---|
| 436 | {
|
|---|
| 437 | for (vector<Song>::iterator song = songs.begin(); song != songs.end(); song++)
|
|---|
| 438 | {
|
|---|
| 439 | //song is the same
|
|---|
| 440 | if ((STRCMP2_NULLOK((*song).album, (songToDel)->album) == 0) &&
|
|---|
| 441 | (STRCMP2_NULLOK((*song).artist, (songToDel)->artist) == 0) &&
|
|---|
| 442 | (STRCMP2_NULLOK((*song).title, (songToDel)->title) == 0))
|
|---|
| 443 | {
|
|---|
| 444 | if ((*song).statusOfSong == ADD_TO_DEVICE) //song is not yet on the device
|
|---|
| 445 | {
|
|---|
| 446 | //remove it from the list
|
|---|
| 447 | songs.erase(song);
|
|---|
| 448 | nbTrackToAdd--;
|
|---|
| 449 | //size of the song
|
|---|
| 450 | struct stat results;
|
|---|
| 451 | if (stat((*songToDel).filename, &results) == 0)
|
|---|
| 452 | addTrackTotalByte -= results.st_size;
|
|---|
| 453 | return (2);
|
|---|
| 454 | }
|
|---|
| 455 | if ((*song).statusOfSong == ON_DEVICE)
|
|---|
| 456 | {
|
|---|
| 457 | (*song).statusOfSong = REMOVE_FROM_DEVICE;
|
|---|
| 458 | nbTrackToDel++;
|
|---|
| 459 | //size of the song
|
|---|
| 460 | struct stat results;
|
|---|
| 461 | if (stat((*songToDel).filename, &results) == 0)
|
|---|
| 462 | delTrackTotalByte += results.st_size;
|
|---|
| 463 | return (1);
|
|---|
| 464 | }
|
|---|
| 465 | }
|
|---|
| 466 | }
|
|---|
| 467 | }
|
|---|
| 468 | return (0);
|
|---|
| 469 | }
|
|---|
| 470 |
|
|---|
| 471 | int SonyDb::getNbPlaylist()
|
|---|
| 472 | {
|
|---|
| 473 | return(this->playlist.size());
|
|---|
| 474 | }
|
|---|
| 475 |
|
|---|
| 476 | bool SonyDb::addPlaylist(Playlist *p)
|
|---|
| 477 | {
|
|---|
| 478 | if (this->copying)
|
|---|
| 479 | playlist_temporary.push_back(*p);
|
|---|
| 480 | else
|
|---|
| 481 | playlist.push_back(*p);
|
|---|
| 482 | return (true);
|
|---|
| 483 | }
|
|---|
| 484 |
|
|---|
| 485 | bool SonyDb::addSong(Song *songToAdd)
|
|---|
| 486 | {
|
|---|
| 487 | //check how much space is needed
|
|---|
| 488 | struct stat results;
|
|---|
| 489 | if (stat((*songToAdd).filename, &results) == 0)
|
|---|
| 490 | addTrackTotalByte += results.st_size;
|
|---|
| 491 |
|
|---|
| 492 | if (this->copying)
|
|---|
| 493 | {
|
|---|
| 494 | //add the song to the temporary list
|
|---|
| 495 | songToAdd->sonyDbOrder = 0;
|
|---|
| 496 | songs_temporary.push_back(*songToAdd);
|
|---|
| 497 | nbTrackToAdd++;
|
|---|
| 498 | }
|
|---|
| 499 | else
|
|---|
| 500 | {
|
|---|
| 501 | //check if song is already present on device
|
|---|
| 502 | for (vector<Song>::iterator song = songs.begin(); song != songs.end(); song++)
|
|---|
| 503 | {
|
|---|
| 504 | //song is the same
|
|---|
| 505 | if ((STRCMP2_NULLOK((*song).album, (songToAdd)->album) == 0) &&
|
|---|
| 506 | (STRCMP2_NULLOK((*song).artist, (songToAdd)->artist) == 0) &&
|
|---|
| 507 | (STRCMP2_NULLOK((*song).title, (songToAdd)->title) == 0))
|
|---|
| 508 | {
|
|---|
| 509 | if ((*song).statusOfSong != ADD_TO_DEVICE)
|
|---|
| 510 | (*song).statusOfSong = ON_DEVICE;
|
|---|
| 511 | free(songToAdd->filename);
|
|---|
| 512 | songToAdd->filename = strdup((*song).filename);
|
|---|
| 513 | return (false);
|
|---|
| 514 | }
|
|---|
| 515 | }
|
|---|
| 516 |
|
|---|
| 517 | //add the song
|
|---|
| 518 | nbTrackToAdd++;
|
|---|
| 519 | songToAdd->sonyDbOrder = 0; //changed when copied to the device in writeTracks
|
|---|
| 520 | songs.push_back(*songToAdd);
|
|---|
| 521 | }
|
|---|
| 522 |
|
|---|
| 523 | return (true);
|
|---|
| 524 | }
|
|---|
| 525 |
|
|---|
| 526 |
|
|---|
| 527 |
|
|---|
| 528 |
|
|---|
| 529 | /*****************************************************************************************/
|
|---|
| 530 | /** read/write functions (common header) */
|
|---|
| 531 |
|
|---|
| 532 | bool SonyDb::getHeader(sonyFileHeader *header, FILE *f)
|
|---|
| 533 | {
|
|---|
| 534 | //read header file
|
|---|
| 535 | if ( fread(header, sizeof(sonyFileHeader), 1, f ) != 1)
|
|---|
| 536 | {
|
|---|
| 537 | fprintf(fp, "error could not read file header (fileheader)\n");
|
|---|
| 538 | fflush(fp);
|
|---|
| 539 | return false;
|
|---|
| 540 | }
|
|---|
| 541 | /* else
|
|---|
| 542 | {
|
|---|
| 543 | fprintf(fp, "header\n: magic:%08x, cte: %08x ,count:%08x \n", header->magic, header->cte, header->count);
|
|---|
| 544 |
|
|---|
| 545 | }
|
|---|
| 546 | */
|
|---|
| 547 |
|
|---|
| 548 | return true;
|
|---|
| 549 | }
|
|---|
| 550 |
|
|---|
| 551 | bool SonyDb::getObjectPointer(sonyObjectPointer *Opointer, FILE *f)
|
|---|
| 552 | {
|
|---|
| 553 | //read object pointer
|
|---|
| 554 | if ( fread(Opointer, sizeof(sonyObjectPointer), 1, f ) != 1 )
|
|---|
| 555 | {
|
|---|
| 556 | fprintf(fp, "error could not read file header (filePointer)\n");
|
|---|
| 557 | fflush(fp);
|
|---|
| 558 | return false;
|
|---|
| 559 | }
|
|---|
| 560 | else
|
|---|
| 561 | {
|
|---|
| 562 | //fprintf(fp, "objectPointer: magic:%x length:%x, offset:%x\n", Opointer->magic, Opointer->length, Opointer->offset);
|
|---|
| 563 | //get values from big endian
|
|---|
| 564 | Opointer->length = UINT32_SWAP_BE_LE(Opointer->length);
|
|---|
| 565 | Opointer->offset = UINT32_SWAP_BE_LE(Opointer->offset);
|
|---|
| 566 | //fprintf(fp, "sizeof: %i, objectPointer\n: magic:%s length:%08x, offset:%08x\n",sizeof(sonyObjectPointer), Opointer->magic, Opointer->length, Opointer->offset);
|
|---|
| 567 | }
|
|---|
| 568 | return true;
|
|---|
| 569 | }
|
|---|
| 570 |
|
|---|
| 571 | bool SonyDb::getObject(sonyObject *obj, FILE *f)
|
|---|
| 572 | {
|
|---|
| 573 | //read object
|
|---|
| 574 | if ( fread(obj, sizeof(sonyObject), 1, f ) !=1 )
|
|---|
| 575 | {
|
|---|
| 576 | fprintf(fp, "error could not read file header (object)\n");
|
|---|
| 577 | fflush(fp);
|
|---|
| 578 | return false;
|
|---|
| 579 | }
|
|---|
| 580 | else
|
|---|
| 581 | {
|
|---|
| 582 | //fprintf(fp, "object: magic:%x size :%x, count:%x \n", obj->magic, obj->size, obj->count);
|
|---|
| 583 | //get values from big endian
|
|---|
| 584 | obj->size = UINT16_SWAP_BE_LE(obj->size);
|
|---|
| 585 | obj->count = UINT16_SWAP_BE_LE(obj->count);
|
|---|
| 586 | //fprintf(fp, "sizeof: %i, object\n: magic:%s size :%08x, count:%08x \n", sizeof(sonyObject), obj->magic, obj->size, obj->count);
|
|---|
| 587 | }
|
|---|
| 588 | return true;
|
|---|
| 589 | }
|
|---|
| 590 |
|
|---|
| 591 | // write a file header
|
|---|
| 592 | bool SonyDb::writeHeader(sonyFileHeader *h, FILE *f)
|
|---|
| 593 | {
|
|---|
| 594 | return(writeHeader(h, f, 1));
|
|---|
| 595 | }
|
|---|
| 596 |
|
|---|
| 597 | // write a file header specifying the object pointer count
|
|---|
| 598 | bool SonyDb::writeHeader(sonyFileHeader *h, FILE *f, int count)
|
|---|
| 599 | {
|
|---|
| 600 | h->cte[0] = 0x01;
|
|---|
| 601 | h->cte[1] = 0x01;
|
|---|
| 602 | h->cte[2] = 0x00;
|
|---|
| 603 | h->cte[3] = 0x00;
|
|---|
| 604 | h->count = count;
|
|---|
| 605 | for (int i = 0; i < 7; i++)
|
|---|
| 606 | h->padding[i]= 0x00;
|
|---|
| 607 |
|
|---|
| 608 | if (fwrite(h, sizeof(sonyFileHeader), 1, f) == 1)
|
|---|
| 609 | return (true);
|
|---|
| 610 | else
|
|---|
| 611 | return (false);
|
|---|
| 612 | }
|
|---|
| 613 |
|
|---|
| 614 | // write an object pointer header
|
|---|
| 615 | bool SonyDb::writeObjectPointer(sonyObjectPointer *p, FILE *f)
|
|---|
| 616 | {
|
|---|
| 617 | p->padding = 0x00000000;
|
|---|
| 618 |
|
|---|
| 619 | if (fwrite(p, sizeof(sonyFileHeader), 1, f) == 1)
|
|---|
| 620 | return (true);
|
|---|
| 621 | else
|
|---|
| 622 | return (false);
|
|---|
| 623 | return (true);
|
|---|
| 624 | }
|
|---|
| 625 |
|
|---|
| 626 | //internal write an object header
|
|---|
| 627 | bool SonyDb::writeObject(sonyObject *obj, FILE *f)
|
|---|
| 628 | {
|
|---|
| 629 | if (fwrite(obj, sizeof(sonyFileHeader), 1, f) == 1)
|
|---|
| 630 | return (true);
|
|---|
| 631 | else
|
|---|
| 632 | return (false);
|
|---|
| 633 | }
|
|---|
| 634 |
|
|---|
| 635 |
|
|---|
| 636 | /*****************************************************************************************/
|
|---|
| 637 |
|
|---|
| 638 | //internal write a track header
|
|---|
| 639 | bool SonyDb::writeTrackHeader(sonyTrack *t, FILE *f)
|
|---|
| 640 | {
|
|---|
| 641 | if (fwrite(t, sizeof(sonyTrack), 1, f) != 1)
|
|---|
| 642 | {
|
|---|
| 643 | fprintf(fp, "error could not write file header (object)\n");
|
|---|
| 644 | fflush(fp);
|
|---|
| 645 | return false;
|
|---|
| 646 | }
|
|---|
| 647 | return (true);
|
|---|
| 648 | }
|
|---|
| 649 |
|
|---|
| 650 | //internal write a track tag
|
|---|
| 651 | bool SonyDb::writeTrackTag(sonyTrackTag *tt, char *input, FILE *f)
|
|---|
| 652 | {
|
|---|
| 653 | //init
|
|---|
| 654 | int size = TAGSIZE;
|
|---|
| 655 | utf16char *tagRecord;
|
|---|
| 656 |
|
|---|
| 657 | //to utf16
|
|---|
| 658 | tagRecord = ansi_to_utf16(input, (size - 6), true);
|
|---|
| 659 |
|
|---|
| 660 | //write tracktag (tagtype + encoding)
|
|---|
| 661 | if (fwrite(tt, sizeof(sonyTrackTag), 1, f) != 1) return (false);
|
|---|
| 662 |
|
|---|
| 663 | //write tag (data itself)
|
|---|
| 664 | if (fwrite(tagRecord, (size - 6), 1, f) != 1) return (false);
|
|---|
| 665 | free(tagRecord);
|
|---|
| 666 |
|
|---|
| 667 | return (true);
|
|---|
| 668 | }
|
|---|
| 669 |
|
|---|
| 670 | void SonyDb::setTable(char *TableFileName, int type)
|
|---|
| 671 | {
|
|---|
| 672 | this->decodeTableFilename = strdup(TableFileName);
|
|---|
| 673 | this->codeType = type;
|
|---|
| 674 |
|
|---|
| 675 | if (type == ENCODING_USE_KEY)
|
|---|
| 676 | {
|
|---|
| 677 | FILE *t = fopen(decodeTableFilename, "rb");
|
|---|
| 678 | fseek(t, 0x0a, SEEK_SET);
|
|---|
| 679 | fread(&(this->DvId), sizeof(uint32), 1, t);
|
|---|
| 680 | this->DvId = UINT32_SWAP_BE_LE(this->DvId);
|
|---|
| 681 | fclose(t);
|
|---|
| 682 | }
|
|---|
| 683 | }
|
|---|
| 684 |
|
|---|
| 685 |
|
|---|
| 686 |
|
|---|
| 687 | //ported from gym
|
|---|
| 688 | bool SonyDb::loadCodeTable(int id)
|
|---|
| 689 | {
|
|---|
| 690 | FILE *t;
|
|---|
| 691 | uint8 *header1 = (uint8*)malloc(sizeof(uint8) * 134); //deserialize manually ...
|
|---|
| 692 | uint8 *header2 = (uint8*)malloc(sizeof(uint8) * 10);
|
|---|
| 693 | uint8 *tmp = (uint8*)malloc(sizeof(uint8) * 256);
|
|---|
| 694 |
|
|---|
| 695 | t = fopen(decodeTableFilename, "rb");
|
|---|
| 696 | // place cursor in place...
|
|---|
| 697 | fseek(t, 0x4B0 * id, SEEK_SET);
|
|---|
| 698 | fread(header1, sizeof(uint8), 134, t);
|
|---|
| 699 |
|
|---|
| 700 | for (int i = 0; i < 4; i++)
|
|---|
| 701 | {
|
|---|
| 702 | fread(tmp, sizeof(uint8), 256, t);
|
|---|
| 703 | for (int j = 0; j < 256; j++)
|
|---|
| 704 | codeTable[(i*256) + j] = tmp[j];
|
|---|
| 705 | fread(header2, sizeof(uint8), 10, t);
|
|---|
| 706 | }
|
|---|
| 707 |
|
|---|
| 708 | free(header1);
|
|---|
| 709 | free(header2);
|
|---|
| 710 | free(tmp);
|
|---|
| 711 | fclose(t);
|
|---|
| 712 | return true;
|
|---|
| 713 | }
|
|---|
| 714 |
|
|---|
| 715 | //add mp3 file to device
|
|---|
| 716 | bool SonyDb::addOMA(Song *s, int destination)
|
|---|
| 717 | {
|
|---|
| 718 | uint32 key = 0xFFFFFFFF;
|
|---|
| 719 | bool isVBR = false;
|
|---|
| 720 |
|
|---|
| 721 | this->copyPercent = 0;
|
|---|
| 722 | if (s->statusOfSong != ADD_TO_DEVICE)
|
|---|
| 723 | return false;
|
|---|
| 724 |
|
|---|
| 725 | char *filename = GetOMAFilename(destination);
|
|---|
| 726 |
|
|---|
| 727 | fprintf(fp, "sending %s to %s\n", s->filename, filename);
|
|---|
| 728 | fflush(fp);
|
|---|
| 729 |
|
|---|
| 730 | //createDirectory if necessary
|
|---|
| 731 | createDir(destination);
|
|---|
| 732 |
|
|---|
| 733 | //load decode table for this track
|
|---|
| 734 | if (this->codeType == ENCODING_USE_TABLE)
|
|---|
| 735 | this->loadCodeTable(destination - 1);
|
|---|
| 736 |
|
|---|
| 737 | //or use key
|
|---|
| 738 | if (this->codeType == ENCODING_USE_KEY)
|
|---|
| 739 | key = ( 0x2465 + destination * 0x5296E435 ) ^ this->DvId;
|
|---|
| 740 |
|
|---|
| 741 |
|
|---|
| 742 | FILE *fout = fopen(filename, "wb");
|
|---|
| 743 | if (fout == NULL)
|
|---|
| 744 | {
|
|---|
| 745 | fprintf(fp, "error can't open file %s\n", filename);
|
|---|
| 746 | fflush(fp);
|
|---|
| 747 | return false;
|
|---|
| 748 | }
|
|---|
| 749 |
|
|---|
| 750 | FILE *fin = fopen(s->filename, "rb");
|
|---|
| 751 | float finSize = 0;
|
|---|
| 752 | if (fin == NULL)
|
|---|
| 753 | {
|
|---|
| 754 | fprintf(fp, "error can't open file %s\n", s->filename);
|
|---|
| 755 | fflush(fp);
|
|---|
| 756 | fclose(fout);
|
|---|
| 757 | return false;
|
|---|
| 758 | }
|
|---|
| 759 |
|
|---|
| 760 | //get input file size
|
|---|
| 761 | struct stat results;
|
|---|
| 762 | if (stat(s->filename, &results) == 0)
|
|---|
| 763 | finSize = results.st_size;
|
|---|
| 764 |
|
|---|
| 765 | uint8 *header = (uint8*)malloc(sizeof(uint8) * 11);
|
|---|
| 766 | utf16char *tagRecord;
|
|---|
| 767 | char *tmpTag = (char*)malloc(sizeof(char) * 256);
|
|---|
| 768 | int tagLength;
|
|---|
| 769 | int headerLength = 0;
|
|---|
| 770 | long startPoint = 0;
|
|---|
| 771 | int nbFrames = 0; // estimated number of frames
|
|---|
| 772 |
|
|---|
| 773 | memset(header, 0, 11);
|
|---|
| 774 | if (fread(header, 1, 10, fin) != 10)
|
|---|
| 775 | return false;
|
|---|
| 776 | if (STRNCMP_NULLOK((char*)header, "ID3", 3) == 0)
|
|---|
| 777 | {
|
|---|
| 778 | //skip Idv2 tags
|
|---|
| 779 | startPoint = ((header[6] << 21) + (header[7] << 14) + (header[8] << 7) + header[9]) + 10;
|
|---|
| 780 |
|
|---|
| 781 | }
|
|---|
| 782 | else
|
|---|
| 783 | {
|
|---|
| 784 | //no idv2 tag found
|
|---|
| 785 | startPoint = 0;
|
|---|
| 786 | }
|
|---|
| 787 |
|
|---|
| 788 | //go to the first frame
|
|---|
| 789 | fseek(fin, startPoint, SEEK_SET);
|
|---|
| 790 |
|
|---|
| 791 | memset(header, 0, 11);
|
|---|
| 792 | //skip zeros
|
|---|
| 793 | while (header[0] == 0)
|
|---|
| 794 | {
|
|---|
| 795 | if(fread(header, sizeof(uint8), 1, fin) != 1)
|
|---|
| 796 | {
|
|---|
| 797 | fclose(fout);
|
|---|
| 798 | fclose(fin);
|
|---|
| 799 | return false;
|
|---|
| 800 | }
|
|---|
| 801 | }
|
|---|
| 802 |
|
|---|
| 803 | if (header[0] == 0xFF)
|
|---|
| 804 | {
|
|---|
| 805 | if (fread(header, sizeof(uint8), 3, fin) != 3)
|
|---|
| 806 | {
|
|---|
| 807 | fclose(fout);
|
|---|
| 808 | fclose(fin);
|
|---|
| 809 | return false;
|
|---|
| 810 | }
|
|---|
| 811 |
|
|---|
| 812 | //get mpeg type, layer type and bitrate
|
|---|
| 813 | if ((header[0] & 0xE0) == 0xE0) //we found the first frame
|
|---|
| 814 | {
|
|---|
| 815 | //encoding = mpeg version(2bits), layer version(2bits), bitrate(4bits)
|
|---|
| 816 | s->encoding = ( ((header[0] & 0x1E) << 3) + ((header[1] & 0xF0) >> 4) );
|
|---|
| 817 |
|
|---|
| 818 | // 00 - MPEG Version 2.5 (unofficial extension of MPEG 2)
|
|---|
| 819 | // 01 - reserved
|
|---|
| 820 | // 10 - MPEG Version 2 (ISO/IEC 13818-3)
|
|---|
| 821 | // 11 - MPEG Version 1 (ISO/IEC 11172-3)
|
|---|
| 822 | uint8 mpegVersion = (header[0] & 0x18) >> 3;
|
|---|
| 823 |
|
|---|
| 824 | //00 - reserved
|
|---|
| 825 | //01 - Layer III
|
|---|
| 826 | //10 - Layer II
|
|---|
| 827 | //11 - Layer I
|
|---|
| 828 | uint8 layerVersion = (header[0] & 0x06) >> 1;
|
|---|
| 829 |
|
|---|
| 830 | uint8 samplingRateIndex = (header[1] & 0xC) >> 2;
|
|---|
| 831 |
|
|---|
| 832 | if (((mpegVersion * 3) + samplingRateIndex >= 12) || ((mpegVersion * 3) + layerVersion >= 16))
|
|---|
| 833 | {
|
|---|
| 834 | //header is invalid
|
|---|
| 835 | nbFrames = 0;
|
|---|
| 836 | }
|
|---|
| 837 | else
|
|---|
| 838 | {
|
|---|
| 839 | int SAMPLING_RATES[] = {11025, 12000, 8000, 0, 0, 0, 22050, 24000, 16000, 44100, 48000, 32000};
|
|---|
| 840 | int SAMPLE_PER_FRAME[] = {0,576,1152,384,0,0,0,0,0,576,1152,384,0,1152,1152,384};
|
|---|
| 841 |
|
|---|
| 842 | //sample per frame 0=reserved
|
|---|
| 843 | // MPG2.5 res MPG2 MPG1
|
|---|
| 844 | //reserved 0 0 0 0
|
|---|
| 845 | //Layer III 576 0 576 1152
|
|---|
| 846 | //Layer II 1152 0 1152 1152
|
|---|
| 847 | //Layer I 384 0 384 384
|
|---|
| 848 |
|
|---|
| 849 | int samplingRate = SAMPLING_RATES[(mpegVersion * 3) + samplingRateIndex];
|
|---|
| 850 | int samplePerFrame = SAMPLE_PER_FRAME[(mpegVersion * 4) + layerVersion];
|
|---|
| 851 | nbFrames = (s->songlen * samplingRate) / samplePerFrame;
|
|---|
| 852 | }
|
|---|
| 853 |
|
|---|
| 854 | //skip the the frame header
|
|---|
| 855 | fseek(fin, sizeof(uint8) * 32, SEEK_CUR);
|
|---|
| 856 |
|
|---|
| 857 | //check if first is "XING" for VBR files
|
|---|
| 858 | memset(header, 0, 11);
|
|---|
| 859 | if (fread(header, sizeof(uint8), 4, fin) != 4)
|
|---|
| 860 | {
|
|---|
| 861 | fclose(fout);
|
|---|
| 862 | fclose(fin);
|
|---|
| 863 | return false;
|
|---|
| 864 | }
|
|---|
| 865 |
|
|---|
| 866 | if (STRNCMP_NULLOK((char*)header, "XING", 4) == 0)
|
|---|
| 867 | isVBR = true;
|
|---|
| 868 | }
|
|---|
| 869 | else
|
|---|
| 870 | {
|
|---|
| 871 | fprintf(fp, "File format invalid, could not find first frame%s\n", s->filename);
|
|---|
| 872 | fflush(fp);
|
|---|
| 873 | //return false;
|
|---|
| 874 | }
|
|---|
| 875 | }
|
|---|
| 876 | else
|
|---|
| 877 | {
|
|---|
| 878 | fprintf(fp, "File format invalid, could not find first frame%s\n", s->filename);
|
|---|
| 879 | fflush(fp);
|
|---|
| 880 | //return false;
|
|---|
| 881 | }
|
|---|
| 882 |
|
|---|
| 883 |
|
|---|
| 884 |
|
|---|
| 885 | //go back to the start of mp3 data
|
|---|
| 886 | fseek(fin, startPoint, SEEK_SET);
|
|---|
| 887 |
|
|---|
| 888 | //write the OMA headers :
|
|---|
| 889 | //format is :
|
|---|
| 890 | //"ea3"0x03 (4bytes), sizeOfTotaltags (6bytes)
|
|---|
| 891 | //TIT2(4bytes) sizeOfTag(4bytes) 2flags (2bytes) 0x02(=utf16be format?) titleOftheSong
|
|---|
| 892 | //...
|
|---|
| 893 | //not all size are coded in synchsafe format
|
|---|
| 894 |
|
|---|
| 895 |
|
|---|
| 896 | //idv2 header
|
|---|
| 897 | memset(header, 0, 11);
|
|---|
| 898 | header[0] = 'e';
|
|---|
| 899 | header[1] = 'a';
|
|---|
| 900 | header[2] = '3';
|
|---|
| 901 | header[3] = 0x03;
|
|---|
| 902 | //...zeros
|
|---|
| 903 | header[8] = 0x17;
|
|---|
| 904 | header[9] = 0x76; //size of tag header in Synchsafe format (=3072 bytes - 10 of header)
|
|---|
| 905 | if (fwrite(header, sizeof(uint8), 10, fout) != 10)
|
|---|
| 906 | {
|
|---|
| 907 | fclose(fout);
|
|---|
| 908 | fclose(fin);
|
|---|
| 909 | return false;
|
|---|
| 910 | }
|
|---|
| 911 |
|
|---|
| 912 | //title tag
|
|---|
| 913 | memset(header, 0, 11);
|
|---|
| 914 | memcpy(header, "TIT2", 4);
|
|---|
| 915 | tagLength = strlen(s->title);
|
|---|
| 916 | tagRecord = ansi_to_utf16(s->title, tagLength + 1, true);
|
|---|
| 917 | tagLength = (tagLength * 2) + 1;
|
|---|
| 918 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 919 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 920 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 921 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 922 | header[8] = 0; //flag 1
|
|---|
| 923 | header[9] = 0; //flag 2
|
|---|
| 924 | header[10] = 0x02; //
|
|---|
| 925 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 926 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 927 | {
|
|---|
| 928 | fclose(fout);
|
|---|
| 929 | fclose(fin);
|
|---|
| 930 | return false;
|
|---|
| 931 | }
|
|---|
| 932 | headerLength += (11 * sizeof(uint8));
|
|---|
| 933 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 934 | {
|
|---|
| 935 | fclose(fout);
|
|---|
| 936 | fclose(fin);
|
|---|
| 937 | return false;
|
|---|
| 938 | }
|
|---|
| 939 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 940 | free(tagRecord);
|
|---|
| 941 |
|
|---|
| 942 |
|
|---|
| 943 | //artist tag
|
|---|
| 944 | memset(header, 0, 11);
|
|---|
| 945 | memcpy(header, "TPE1", 4);
|
|---|
| 946 | tagLength = strlen(s->artist);
|
|---|
| 947 | tagRecord = ansi_to_utf16(s->artist, tagLength + 1, true);
|
|---|
| 948 | tagLength = (tagLength * 2) + 1;
|
|---|
| 949 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 950 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 951 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 952 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 953 | header[8] = 0; //flag 1
|
|---|
| 954 | header[9] = 0; //flag 2
|
|---|
| 955 | header[10] = 0x02; //
|
|---|
| 956 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 957 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 958 | {
|
|---|
| 959 | fclose(fout);
|
|---|
| 960 | fclose(fin);
|
|---|
| 961 | return false;
|
|---|
| 962 | }
|
|---|
| 963 | headerLength += (11 * sizeof(uint8));
|
|---|
| 964 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 965 | {
|
|---|
| 966 | fclose(fout);
|
|---|
| 967 | fclose(fin);
|
|---|
| 968 | return false;
|
|---|
| 969 | }
|
|---|
| 970 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 971 | free(tagRecord);
|
|---|
| 972 |
|
|---|
| 973 | //album tag
|
|---|
| 974 | memset(header, 0, 11);
|
|---|
| 975 | memcpy(header, "TALB", 4);
|
|---|
| 976 | tagLength = strlen(s->album);
|
|---|
| 977 | tagRecord = ansi_to_utf16(s->album, tagLength + 1, true);
|
|---|
| 978 | tagLength = (tagLength * 2) + 1;
|
|---|
| 979 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 980 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 981 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 982 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 983 | header[8] = 0; //flag 1
|
|---|
| 984 | header[9] = 0; //flag 2
|
|---|
| 985 | header[10] = 0x02; //
|
|---|
| 986 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 987 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 988 | {
|
|---|
| 989 | fclose(fout);
|
|---|
| 990 | fclose(fin);
|
|---|
| 991 | return false;
|
|---|
| 992 | }
|
|---|
| 993 | headerLength += (11 * sizeof(uint8));
|
|---|
| 994 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 995 | {
|
|---|
| 996 | fclose(fout);
|
|---|
| 997 | fclose(fin);
|
|---|
| 998 | return false;
|
|---|
| 999 | }
|
|---|
| 1000 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 1001 | free(tagRecord);
|
|---|
| 1002 |
|
|---|
| 1003 | //genre tag
|
|---|
| 1004 | memset(header, 0, 11);
|
|---|
| 1005 | memcpy(header, "TCON", 4);
|
|---|
| 1006 | tagLength = strlen(s->genre);
|
|---|
| 1007 | tagRecord = ansi_to_utf16(s->genre, tagLength + 1, true);
|
|---|
| 1008 | tagLength = (tagLength * 2) + 1;
|
|---|
| 1009 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 1010 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 1011 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 1012 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 1013 | header[8] = 0; //flag 1
|
|---|
| 1014 | header[9] = 0; //flag 2
|
|---|
| 1015 | header[10] = 0x02; //
|
|---|
| 1016 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 1017 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 1018 | {
|
|---|
| 1019 | fclose(fout);
|
|---|
| 1020 | fclose(fin);
|
|---|
| 1021 | return false;
|
|---|
| 1022 | }
|
|---|
| 1023 | headerLength += (11 * sizeof(uint8));
|
|---|
| 1024 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 1025 | {
|
|---|
| 1026 | fclose(fout);
|
|---|
| 1027 | fclose(fin);
|
|---|
| 1028 | return false;
|
|---|
| 1029 | }
|
|---|
| 1030 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 1031 | free(tagRecord);
|
|---|
| 1032 |
|
|---|
| 1033 | //track number tag //space are suppose to be replaced by 0x00 not 0x20
|
|---|
| 1034 | sprintf(tmpTag, "OMG_TRACK %02i", s->track_nr);
|
|---|
| 1035 | memset(header, 0, 11);
|
|---|
| 1036 | memcpy(header, "TXXX", 4);
|
|---|
| 1037 | tagLength = strlen(tmpTag);
|
|---|
| 1038 | tagRecord = ansi_to_utf16(tmpTag, tagLength + 1, true);
|
|---|
| 1039 | tagLength = (tagLength * 2) + 1;
|
|---|
| 1040 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 1041 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 1042 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 1043 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 1044 | header[8] = 0; //flag 1
|
|---|
| 1045 | header[9] = 0; //flag 2
|
|---|
| 1046 | header[10] = 0x02; //
|
|---|
| 1047 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 1048 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 1049 | {
|
|---|
| 1050 | fclose(fout);
|
|---|
| 1051 | fclose(fin);
|
|---|
| 1052 | return false;
|
|---|
| 1053 | }
|
|---|
| 1054 | headerLength += (11 * sizeof(uint8));
|
|---|
| 1055 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 1056 | {
|
|---|
| 1057 | fclose(fout);
|
|---|
| 1058 | fclose(fin);
|
|---|
| 1059 | return false;
|
|---|
| 1060 | }
|
|---|
| 1061 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 1062 | free(tagRecord);
|
|---|
| 1063 |
|
|---|
| 1064 | //fixme date of transfert? tag //space are suppose to be replaced by 0x00 not 0x20
|
|---|
| 1065 | sprintf(tmpTag, "OMG_TRLDA 2001/01/01 00:00:00");
|
|---|
| 1066 | memset(header, 0, 11);
|
|---|
| 1067 | memcpy(header, "TXXX", 4);
|
|---|
| 1068 | tagLength = strlen(tmpTag);
|
|---|
| 1069 | tagRecord = ansi_to_utf16(tmpTag, tagLength + 1, true);
|
|---|
| 1070 | tagLength = (tagLength * 2) + 1;
|
|---|
| 1071 | tagLength = (strlen(tmpTag) + 1) * 2;
|
|---|
| 1072 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 1073 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 1074 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 1075 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 1076 | header[8] = 0; //flag 1
|
|---|
| 1077 | header[9] = 0; //flag 2
|
|---|
| 1078 | header[10] = 0x02; //
|
|---|
| 1079 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 1080 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 1081 | {
|
|---|
| 1082 | fclose(fout);
|
|---|
| 1083 | fclose(fin);
|
|---|
| 1084 | return false;
|
|---|
| 1085 | }
|
|---|
| 1086 | headerLength += (11 * sizeof(uint8));
|
|---|
| 1087 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 1088 | {
|
|---|
| 1089 | fclose(fout);
|
|---|
| 1090 | fclose(fin);
|
|---|
| 1091 | return false;
|
|---|
| 1092 | }
|
|---|
| 1093 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 1094 | free(tagRecord);
|
|---|
| 1095 |
|
|---|
| 1096 | //track length tag
|
|---|
| 1097 | sprintf(tmpTag, "%i", s->songlen * 1000);
|
|---|
| 1098 | memset(header, 0, 11);
|
|---|
| 1099 | memcpy(header, "TLEN", 4);
|
|---|
| 1100 | tagLength = strlen(tmpTag);
|
|---|
| 1101 | tagRecord = ansi_to_utf16(tmpTag, tagLength + 1, true);
|
|---|
| 1102 | tagLength = (tagLength * 2) + 1;
|
|---|
| 1103 | header[4] = NOT_SYNCHSAFE_B1(tagLength);//size of the title
|
|---|
| 1104 | header[5] = NOT_SYNCHSAFE_B2(tagLength);
|
|---|
| 1105 | header[6] = NOT_SYNCHSAFE_B3(tagLength);
|
|---|
| 1106 | header[7] = NOT_SYNCHSAFE_B4(tagLength);
|
|---|
| 1107 | header[8] = 0; //flag 1
|
|---|
| 1108 | header[9] = 0; //flag 2
|
|---|
| 1109 | header[10] = 0x02; //
|
|---|
| 1110 | tagLength = (tagLength - 1 )/ 2;
|
|---|
| 1111 | if (fwrite(header, sizeof(uint8), 11, fout) != 11)
|
|---|
| 1112 | {
|
|---|
| 1113 | fclose(fout);
|
|---|
| 1114 | fclose(fin);
|
|---|
| 1115 | return false;
|
|---|
| 1116 | }
|
|---|
| 1117 | headerLength += (11 * sizeof(uint8));
|
|---|
| 1118 | if (fwrite(tagRecord, sizeof(utf16char), tagLength, fout) != tagLength)
|
|---|
| 1119 | {
|
|---|
| 1120 | fclose(fout);
|
|---|
| 1121 | fclose(fin);
|
|---|
| 1122 | return false;
|
|---|
| 1123 | }
|
|---|
| 1124 | headerLength += (tagLength * sizeof(utf16char));
|
|---|
| 1125 | free(tagRecord);
|
|---|
| 1126 |
|
|---|
| 1127 | memset(header, 0, 11);
|
|---|
| 1128 | //fill the rest with 0
|
|---|
| 1129 | while (headerLength < 3062)
|
|---|
| 1130 | {
|
|---|
| 1131 | headerLength += sizeof(uint8);
|
|---|
| 1132 | if (fwrite(header, sizeof(uint8), 1, fout) != 1)
|
|---|
| 1133 | {
|
|---|
| 1134 | fclose(fout);
|
|---|
| 1135 | fclose(fin);
|
|---|
| 1136 | return false;
|
|---|
| 1137 | }
|
|---|
| 1138 | }
|
|---|
| 1139 |
|
|---|
| 1140 | //write second header fixme (some stuff are missing here... important?)
|
|---|
| 1141 | uint8 *header2 = (uint8*)malloc(sizeof(uint8) * 16);
|
|---|
| 1142 | headerLength = 0;
|
|---|
| 1143 | memset(header2, 0, 16);
|
|---|
| 1144 | //first line
|
|---|
| 1145 | memcpy(header2, "EA3", 3);
|
|---|
| 1146 | header2[3] = 0x02;
|
|---|
| 1147 | header2[4] = 0; //size of 2nd header
|
|---|
| 1148 | header2[5] = 0x60;//size of 2nd header
|
|---|
| 1149 | header2[6] = 0xff;// + same value as in 05CIDLST.DAT
|
|---|
| 1150 | if (this->codeType == ENCODING_USE_NONE)
|
|---|
| 1151 | {
|
|---|
| 1152 | header2[7] = 0xff;// cp or sonicstage? or encoded not encoded? 505 =e 1000 =f
|
|---|
| 1153 | }
|
|---|
| 1154 | else
|
|---|
| 1155 | {
|
|---|
| 1156 | header2[7] = 0xfe;// cp or sonicstage? or encoded not encoded? 505 =e 1000 =f
|
|---|
| 1157 | }
|
|---|
| 1158 | header2[12] = 0x01;
|
|---|
| 1159 | header2[13] = 0x0F;
|
|---|
| 1160 | header2[14] = 0x50;
|
|---|
| 1161 | header2[15] = 0x00;// - same value as in 05CIDLST.DAT
|
|---|
| 1162 | if (fwrite(header2, sizeof(uint8), 16, fout) != 16)
|
|---|
| 1163 | {
|
|---|
| 1164 | fclose(fout);
|
|---|
| 1165 | fclose(fin);
|
|---|
| 1166 | return false;
|
|---|
| 1167 | }
|
|---|
| 1168 | headerLength += (16 * sizeof(uint8));
|
|---|
| 1169 |
|
|---|
| 1170 | //second line
|
|---|
| 1171 | memset(header2, 0, 16);
|
|---|
| 1172 | header2[1] = 0x04;// + same value as in 05CIDLST.DAT fixme
|
|---|
| 1173 | //zeros...
|
|---|
| 1174 | header2[5] = 0x01; //fixme 01
|
|---|
| 1175 | header2[6] = 0x02; //fixme 02
|
|---|
| 1176 | header2[7] = 0x03; //fixme 03
|
|---|
| 1177 | header2[8] = 0xc8;
|
|---|
| 1178 | header2[9] = 0xd8;
|
|---|
| 1179 | header2[10] = 0x36;
|
|---|
| 1180 | header2[11] = 0xd8;
|
|---|
| 1181 | header2[12] = 0x11; //fixme 11
|
|---|
| 1182 | header2[13] = 0x22; //fixme 22
|
|---|
| 1183 | header2[14] = 0x33; //fixme 33
|
|---|
| 1184 | header2[15] = 0x44;// - same value as in 05CIDLST.DAT
|
|---|
| 1185 | if (fwrite(header2, sizeof(uint8), 16, fout) != 16)
|
|---|
| 1186 | {
|
|---|
| 1187 | fclose(fout);
|
|---|
| 1188 | fclose(fin);
|
|---|
| 1189 | return false;
|
|---|
| 1190 | }
|
|---|
| 1191 | headerLength += (16 * sizeof(uint8));
|
|---|
| 1192 |
|
|---|
| 1193 | //third line
|
|---|
| 1194 | memset(header2, 0, 16);
|
|---|
| 1195 |
|
|---|
| 1196 | header2[0] = 0x03;// 3 = MP3
|
|---|
| 1197 | header2[1] =(isVBR) ? 0x90 : 0x80 ;// VBR = 90, CBR = 80
|
|---|
| 1198 | header2[2] = s->encoding;// mpeg version(2bits), layer version(2bits), bitrate(4bits)
|
|---|
| 1199 | header2[3] = 0x10;//?? fixme
|
|---|
| 1200 |
|
|---|
| 1201 | //tracklength
|
|---|
| 1202 | uint32 trackLengh = s->songlen * 1000;
|
|---|
| 1203 | header2[4] = (uint8) (((trackLengh) & (uint32) 0xff000000U) >> 24);
|
|---|
| 1204 | header2[5] = (uint8) (((trackLengh) & (uint32) 0x00ff0000U) >> 16);
|
|---|
| 1205 | header2[6] = (uint8) (((trackLengh) & (uint32) 0x0000ff00U) >> 8);
|
|---|
| 1206 | header2[7] = (uint8) ((trackLengh) & (uint32) 0x000000ffU);
|
|---|
| 1207 |
|
|---|
| 1208 | //number of frames
|
|---|
|
|---|