Mercurial > hg > xmms-sid
comparison src/xs_length.c @ 86:9533b78f1a7d
Updated
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 04 Oct 2003 08:21:01 +0000 |
parents | 2bc607888f53 |
children | 94497283affa |
comparison
equal
deleted
inserted
replaced
85:56d2b7a44063 | 86:9533b78f1a7d |
---|---|
29 | 29 |
30 | 30 |
31 /* | 31 /* |
32 * Pointer to database in memory | 32 * Pointer to database in memory |
33 */ | 33 */ |
34 static t_xs_sldb_node *xs_database = NULL, *xs_dblast = NULL; | 34 static t_xs_sldb_node *xs_database = NULL; |
35 static t_xs_sldb_node **xs_dbindex = NULL; | 35 static t_xs_sldb_node **xs_dbindex = NULL; |
36 static gint xs_dbnodes = 0; | 36 static gint xs_dbnodes = 0; |
37 | 37 |
38 | 38 |
39 /* | 39 /* |
43 { | 43 { |
44 t_xs_sldb_node *pResult; | 44 t_xs_sldb_node *pResult; |
45 | 45 |
46 /* Allocate memory for new node */ | 46 /* Allocate memory for new node */ |
47 pResult = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node)); | 47 pResult = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node)); |
48 if (pResult == NULL) return NULL; | 48 if (!pResult) return NULL; |
49 | 49 |
50 return pResult; | 50 return pResult; |
51 } | 51 } |
52 | 52 |
53 | 53 |
54 void xs_db_node_free(t_xs_sldb_node *pNode) | 54 void xs_db_node_free(t_xs_sldb_node *pNode) |
55 { | 55 { |
56 if (pNode) free(pNode); | 56 if (pNode) g_free(pNode); |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 /* | 60 /* |
61 * Insert given node to db linked list | 61 * Insert given node to db linked list |
62 */ | 62 */ |
63 #define LPREV (pNode->pPrev) | |
64 #define LTHIS (pNode) | |
65 #define LNEXT (pNode->pNext) | |
66 | |
63 void xs_db_node_insert(t_xs_sldb_node *pNode) | 67 void xs_db_node_insert(t_xs_sldb_node *pNode) |
64 { | 68 { |
65 if (xs_dblast) | 69 if (xs_database) |
66 { | 70 { |
67 xs_dblast->pNext = pNode; | 71 /* The first node's pPrev points to last node */ |
68 xs_dblast = pNode; | 72 LPREV = xs_database->pPrev; /* New node's prev = Previous last node */ |
73 xs_database->pPrev->pNext = pNode; /* Previous last node's next = New node */ | |
74 xs_database->pPrev = pNode; /* New last node = New node */ | |
75 LNEXT = NULL; /* But next is NULL! */ | |
69 } else { | 76 } else { |
70 xs_dblast = xs_database = pNode; | 77 xs_database = pNode; /* First node ... */ |
71 pNode->pNext = NULL; | 78 LPREV = pNode; /* ... it's also last */ |
79 LNEXT = NULL; /* But next is NULL! */ | |
72 } | 80 } |
73 } | 81 } |
74 | 82 |
75 | 83 |
76 /* | 84 /* |
99 gint iStartNode, iEndNode, iQNode, r, i; | 107 gint iStartNode, iEndNode, iQNode, r, i; |
100 gboolean iFound; | 108 gboolean iFound; |
101 t_xs_sldb_node *pResult; | 109 t_xs_sldb_node *pResult; |
102 | 110 |
103 /* Check the database pointers */ | 111 /* Check the database pointers */ |
104 if ((xs_database == NULL) || (xs_dbindex == NULL)) | 112 if (!xs_database || !xs_dbindex) |
105 return NULL; | 113 return NULL; |
106 | 114 |
107 /* Look-up via index using binary search */ | 115 /* Look-up via index using binary search */ |
108 pResult = NULL; | 116 pResult = NULL; |
109 iStartNode = 0; | 117 iStartNode = 0; |
323 gint i; | 331 gint i; |
324 | 332 |
325 XSDEBUG("sldb_init()\n"); | 333 XSDEBUG("sldb_init()\n"); |
326 | 334 |
327 /* Read the database */ | 335 /* Read the database */ |
328 if (xs_cfg.songlenDBPath == NULL) | 336 if (!xs_cfg.songlenDBPath) |
329 return -10; | 337 return -10; |
330 | 338 |
331 if (xs_db_read(xs_cfg.songlenDBPath) < 0) | 339 if (xs_db_read(xs_cfg.songlenDBPath) < 0) |
332 return -9; | 340 return -9; |
333 | 341 |
345 /* Check number of nodes */ | 353 /* Check number of nodes */ |
346 if (xs_dbnodes > 0) | 354 if (xs_dbnodes > 0) |
347 { | 355 { |
348 /* Allocate memory for index-table */ | 356 /* Allocate memory for index-table */ |
349 xs_dbindex = (t_xs_sldb_node **) g_malloc(sizeof(t_xs_sldb_node *) * xs_dbnodes); | 357 xs_dbindex = (t_xs_sldb_node **) g_malloc(sizeof(t_xs_sldb_node *) * xs_dbnodes); |
350 if (xs_dbindex == NULL) return -6; | 358 if (!xs_dbindex) return -6; |
351 | 359 |
352 /* Get node-pointers to table */ | 360 /* Get node-pointers to table */ |
353 i = 0; | 361 i = 0; |
354 pCurr = xs_database; | 362 pCurr = xs_database; |
355 while (pCurr) | 363 while (pCurr) |
383 pNext = pCurr->pNext; | 391 pNext = pCurr->pNext; |
384 xs_db_node_free(pCurr); | 392 xs_db_node_free(pCurr); |
385 pCurr = pNext; | 393 pCurr = pNext; |
386 } | 394 } |
387 | 395 |
396 xs_database = NULL; | |
397 | |
388 /* Free memory allocated for indexes */ | 398 /* Free memory allocated for indexes */ |
389 if (xs_dbindex) | 399 if (xs_dbindex) |
390 free(xs_dbindex); | 400 { |
401 g_free(xs_dbindex); | |
402 xs_dbindex = NULL; | |
403 } | |
391 } | 404 } |
392 | 405 |
393 | 406 |
394 /* | 407 /* |
395 * Compute md5hash of given SID-file | 408 * Compute md5hash of given SID-file |
396 */ | 409 */ |
397 typedef struct { | 410 typedef struct { |
398 guint8 magicID[4]; /* "PSID" magic identifier */ | 411 gchar magicID[4]; /* "PSID" magic identifier */ |
399 guint16 version, /* Version number */ | 412 guint16 version, /* Version number */ |
400 dataOffset, /* Start of actual c64 data in file */ | 413 dataOffset, /* Start of actual c64 data in file */ |
401 loadAddress, /* Loading address */ | 414 loadAddress, /* Loading address */ |
402 initAddress, /* Initialization address */ | 415 initAddress, /* Initialization address */ |
403 playAddress, /* Play one frame */ | 416 playAddress, /* Play one frame */ |
438 { | 451 { |
439 return fread(s, sizeof(gchar), l, f); | 452 return fread(s, sizeof(gchar), l, f); |
440 } | 453 } |
441 | 454 |
442 | 455 |
443 gint xs_get_sid_hash(gchar *fileName, t_xs_md5hash hash) | 456 gint xs_get_sid_hash(gchar *pcFilename, t_xs_md5hash hash) |
444 { | 457 { |
445 FILE *inFile; | 458 FILE *inFile; |
446 t_xs_md5state inState; | 459 t_xs_md5state inState; |
447 t_xs_psidv1_header psidH; | 460 t_xs_psidv1_header psidH; |
448 t_xs_psidv2_header psidH2; | 461 t_xs_psidv2_header psidH2; |
449 guint8 *songData, ib8[2], i8; | 462 guint8 *songData, ib8[2], i8; |
450 gint iIndex, iRes, songDataLen; | 463 gint iIndex, iRes, songDataLen; |
451 | 464 |
452 /* Try to open the file */ | 465 /* Try to open the file */ |
453 if ((inFile = fopen(fileName, "rb")) == NULL) | 466 if ((inFile = fopen(pcFilename, "rb")) == NULL) |
454 return -1; | 467 return -1; |
455 | 468 |
456 /* Read PSID header in */ | 469 /* Read PSID header in */ |
457 rd_str(inFile, psidH.magicID, sizeof(psidH.magicID)); | 470 rd_str(inFile, psidH.magicID, sizeof(psidH.magicID)); |
458 if ((psidH.magicID[0] != 'P') || (psidH.magicID[1] != 'S') || | 471 if ((psidH.magicID[0] != 'P') || (psidH.magicID[1] != 'S') || |
497 | 510 |
498 /* Read data to buffer */ | 511 /* Read data to buffer */ |
499 iRes = fread(songData, sizeof(guint8), songDataLen, inFile); | 512 iRes = fread(songData, sizeof(guint8), songDataLen, inFile); |
500 fclose(inFile); | 513 fclose(inFile); |
501 | 514 |
502 if (iRes != songDataLen) return -9; | 515 if (iRes != songDataLen) |
516 { | |
517 g_free(songData); | |
518 return -9; | |
519 } | |
503 | 520 |
504 /* Initialize and start MD5-hash calculation */ | 521 /* Initialize and start MD5-hash calculation */ |
505 xs_md5_init(&inState); | 522 xs_md5_init(&inState); |
506 if (psidH.loadAddress == 0) | 523 if (psidH.loadAddress == 0) |
507 /* COULD SOMEONE EXPLAIN WHY DO WE NEED THIS +2 STRIP???? */ | 524 /* COULD SOMEONE EXPLAIN WHY DO WE NEED THIS +2 STRIP???? */ |
508 xs_md5_append(&inState, songData+2, iRes-2); | 525 xs_md5_append(&inState, songData+2, iRes-2); |
509 else | 526 else |
510 xs_md5_append(&inState, songData, iRes); | 527 xs_md5_append(&inState, songData, iRes); |
511 | 528 |
512 free(songData); | 529 g_free(songData); |
513 | 530 |
514 /* Append header data to hash */ | 531 /* Append header data to hash */ |
515 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); } | 532 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); } |
516 | 533 |
517 XSADDHASH(psidH.initAddress) | 534 XSADDHASH(psidH.initAddress) |
550 return 0; | 567 return 0; |
551 } | 568 } |
552 | 569 |
553 | 570 |
554 /* | 571 /* |
555 * Get song length | 572 * Get song lengths |
556 */ | 573 */ |
557 gint32 xs_songlen_get(gchar *fileName, gint subTune) | 574 t_xs_sldb_node * xs_songlen_get(gchar *pcFilename) |
558 { | 575 { |
559 t_xs_sldb_node *dbNode; | 576 t_xs_sldb_node *pResult; |
560 t_xs_md5hash dbHash; | 577 t_xs_md5hash dbHash; |
561 gint32 iResult; | 578 |
562 | 579 pResult = NULL; |
563 iResult = -1; | |
564 | 580 |
565 if (xs_cfg.songlenDBEnable) | 581 if (xs_cfg.songlenDBEnable) |
566 { | 582 { |
567 /* Get the hash and then look up from db */ | 583 /* Get the hash and then look up from db */ |
568 if (xs_get_sid_hash(fileName, dbHash) == 0) | 584 if (xs_get_sid_hash(pcFilename, dbHash) == 0) |
569 { | 585 { |
570 dbNode = xs_db_get(dbHash); | 586 pResult = xs_db_get(dbHash); |
571 | 587 } |
572 if (dbNode && (subTune >= 1) && (subTune <= dbNode->nLengths)) | |
573 { | |
574 /* Get the length */ | |
575 iResult = dbNode->sLengths[subTune - 1]; | |
576 | |
577 /* Take off few last seconds */ | |
578 if (iResult > 1) | |
579 iResult -= 1; | |
580 } | |
581 } | |
582 } | 588 } |
583 | 589 |
584 return iResult; | 590 return pResult; |
585 } | 591 } |
586 | |
587 |