# HG changeset patch # User Matti Hamalainen # Date 1056281880 0 # Node ID 0d1df20745dd73f3327173e1d25bfe0456888421 # Parent 8207e95e04678d148c5622815e0f9bc31e123f48 Started to rewrite STIL-support diff -r 8207e95e0467 -r 0d1df20745dd src/xmms-sid.h --- a/src/xmms-sid.h Sun Jun 22 11:37:05 2003 +0000 +++ b/src/xmms-sid.h Sun Jun 22 11:38:00 2003 +0000 @@ -40,12 +40,15 @@ #define XS_BUFSIZE (4096) /* Size for some buffers */ #define XS_CONFIG_IDENT "XMMS-SID" /* Configuration file identifier */ -#define XS_CONFIG_FILE "/.xmms/config" +#define XS_CONFIG_FILE "/.xmms/xmms-sid" /* Use this configfile if autocyrpe fails */ + +#define XS_STIL_MAXENTRY (48) /* Max number of sub-songs in STIL/SLDB node */ -#define XS_MIN_OVERSAMPLE (2) -#define XS_MAX_OVERSAMPLE (8) +#define XS_MIN_OVERSAMPLE (2) /* Minimum oversampling factor */ +#define XS_MAX_OVERSAMPLE (8) /* Maximum oversampling factor */ -extern InputPlugin xs_plugin_ip; + +extern InputPlugin xs_plugin_ip; /* XMMS-SID plugin structure */ /* diff -r 8207e95e0467 -r 0d1df20745dd src/xs_length.c --- a/src/xs_length.c Sun Jun 22 11:37:05 2003 +0000 +++ b/src/xs_length.c Sun Jun 22 11:38:00 2003 +0000 @@ -32,27 +32,27 @@ /* * Pointer to database in memory */ -static t_xs_dbentry *xs_database = NULL, *xs_dblast = NULL; -static t_xs_dbentry **xs_dbindex = NULL; +static t_xs_sldb_node *xs_database = NULL, *xs_dblast = NULL; +static t_xs_sldb_node **xs_dbindex = NULL; static gint xs_dbnodes = 0; /* * Hash-database handling functions */ -t_xs_dbentry *xs_db_node_new(void) +t_xs_sldb_node *xs_db_node_new(void) { - t_xs_dbentry *pResult; + t_xs_sldb_node *pResult; /* Allocate memory for new node */ - pResult = (t_xs_dbentry *) g_malloc0(sizeof(t_xs_dbentry)); + pResult = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node)); if (pResult == NULL) return NULL; return pResult; } -void xs_db_node_free(t_xs_dbentry *pNode) +void xs_db_node_free(t_xs_sldb_node *pNode) { if (pNode) free(pNode); } @@ -61,7 +61,7 @@ /* * Insert given node to db linked list */ -void xs_db_node_insert(t_xs_dbentry *pNode) +void xs_db_node_insert(t_xs_sldb_node *pNode) { if (xs_dblast) { @@ -95,10 +95,10 @@ /* * Get song length from database */ -t_xs_dbentry * xs_db_get(t_xs_md5hash pHash) +t_xs_sldb_node * xs_db_get(t_xs_md5hash pHash) { gint iStartNode, iEndNode, iQNode, iFound, r, i; - t_xs_dbentry *pResult; + t_xs_sldb_node *pResult; /* Check the database pointers */ if ((xs_database == NULL) || (xs_dbindex == NULL)) @@ -205,7 +205,7 @@ gchar inLine[XS_BUFSIZE]; guint lineNum, linePos; gboolean iOK; - t_xs_dbentry *tmpNode; + t_xs_sldb_node *tmpNode; /* Try to open the file */ if ((inFile = fopen(dbFilename, "ra")) == NULL) @@ -280,7 +280,7 @@ iOK = FALSE; } - /* Add an entry to db in memory */ + /* Add an node to db in memory */ if (iOK) xs_db_node_insert(tmpNode); else @@ -309,8 +309,8 @@ gint xs_db_cmp(const void *pNode1, const void *pNode2) { /* We assume here that we never ever get NULL-pointers or similar */ - return xs_db_cmphash((*(t_xs_dbentry **) pNode1)->md5Hash, - (*(t_xs_dbentry **) pNode2)->md5Hash); + return xs_db_cmphash((*(t_xs_sldb_node **) pNode1)->md5Hash, + (*(t_xs_sldb_node **) pNode2)->md5Hash); } @@ -319,7 +319,7 @@ */ gint xs_songlen_init(void) { - t_xs_dbentry *pCurr; + t_xs_sldb_node *pCurr; gint i; /* Read the database */ @@ -342,7 +342,7 @@ if (xs_dbnodes > 0) { /* Allocate memory for index-table */ - xs_dbindex = (t_xs_dbentry **) g_malloc(sizeof(t_xs_dbentry *) * xs_dbnodes); + xs_dbindex = (t_xs_sldb_node **) g_malloc(sizeof(t_xs_sldb_node *) * xs_dbnodes); if (xs_dbindex == NULL) return -6; /* Get node-pointers to table */ @@ -355,7 +355,7 @@ } /* Sort the indexes */ - qsort(xs_dbindex, xs_dbnodes, sizeof(t_xs_dbentry *), xs_db_cmp); + qsort(xs_dbindex, xs_dbnodes, sizeof(t_xs_sldb_node *), xs_db_cmp); } /* OK */ @@ -368,7 +368,7 @@ */ void xs_songlen_close(void) { - t_xs_dbentry *pCurr, *pNext; + t_xs_sldb_node *pCurr, *pNext; /* Free the memory allocated for database */ pCurr = xs_database; @@ -550,7 +550,7 @@ */ gint32 xs_songlen_get(gchar *fileName, gint subTune) { - t_xs_dbentry *dbEntry; + t_xs_sldb_node *dbNode; t_xs_md5hash dbHash; gint32 iResult; @@ -561,10 +561,10 @@ /* Get the hash and then look up from db */ if (xs_get_sid_hash(fileName, dbHash) == 0) { - dbEntry = xs_db_get(dbHash); + dbNode = xs_db_get(dbHash); - if (dbEntry && (subTune >= 0) && (subTune < dbEntry->nLengths)) - iResult = dbEntry->sLengths[subTune - 1]; + if (dbNode && (subTune >= 0) && (subTune < dbNode->nLengths)) + iResult = dbNode->sLengths[subTune - 1]; } } #if 0 diff -r 8207e95e0467 -r 0d1df20745dd src/xs_length.h --- a/src/xs_length.h Sun Jun 22 11:37:05 2003 +0000 +++ b/src/xs_length.h Sun Jun 22 11:38:00 2003 +0000 @@ -11,15 +11,14 @@ /* * Defines and typedefs */ -#define XS_STIL_MAXENTRY (48) -typedef struct dbnode { +typedef struct _t_xs_sldb_node { t_xs_md5hash md5Hash; /* 128-bit MD5 hash-digest */ gint nLengths; /* Number of lengths */ gint32 sLengths[XS_STIL_MAXENTRY]; /* Lengths in seconds */ - struct dbnode *pNext; -} t_xs_dbentry; + struct _t_xs_sldb_node *pNext; +} t_xs_sldb_node; /* diff -r 8207e95e0467 -r 0d1df20745dd src/xs_stil.c --- a/src/xs_stil.c Sun Jun 22 11:37:05 2003 +0000 +++ b/src/xs_stil.c Sun Jun 22 11:38:00 2003 +0000 @@ -24,560 +24,3 @@ #include "xmms-sid.h" #include #include -#include -#include -#include -#include -#include - - -/* Variables and constants */ -#define XMMS_SID_MAX_BUFSIZE 2048 -struct T_sid_stil_info xs_stil_info; - -/* - * Utility routines - */ -int xs_strcalloc(gchar **result, gchar *str) -{ - if ((result == NULL) || (str == NULL)) return -1; - - if (*result != NULL) g_free(*result); - - *result = (gchar *) g_malloc(strlen(str)+1); - - if (*result == NULL) return -2; - - strcpy(*result, str); - - return 0; -} - - -int xs_strcat(gchar **result, gchar *str) -{ - if ((result == NULL) || (str == NULL)) return -1; - - *result = (gchar *) g_realloc(*result, strlen(*result) + strlen(str) + 1); - - if (*result == NULL) return -2; - - strcat(*result, str); - - return 0; -} - - -/* - * Make lowercase, strip evt. extension - */ -static gchar * uncase_strip_fn(gchar *str) -{ - gchar *res; - gint i, l; - - l = str ? strlen(str) : 0; - - res = strrchr(str, '/'); - - if (res) res = strrchr(res, '.'); - - if (res) l = (res - str); - - res = g_new(gchar, l + 1); - - for (i = 0; i < l; i++) { - res[i] = tolower(str[i]); - } - - res[i] = '\0'; - - return res; -} - - -static gchar * xs_get_hvscname(gchar *fname) -{ - gchar *p, *q, *r; - - p = xs_cfg.stilpath; - - q = r = fname; - - while (*p == *q) { - if (*q == '/') r = q + 1; - p++; q++; - } - - return r; -} - - -/* - * Get line (string) from given file to given buffer. - * Takes care of winDOS CR/LF and *NIX LF formats. - */ -void stil_get_line(gchar *buf, gint bufsize, FILE *f) -{ - gint i; - - /* Get the string */ - fgets(buf, bufsize-1, f); - - /* The file may be in DOS CR-LF format, - so check for the line endings and - remove the \n and \r accordingly - */ - i = strlen(buf); - if (i > 0) { - if (buf[i-2] == '\r') - buf[i-2] = '\0'; - else - buf[i-1] = '\0'; - } -} - - -/* - xs_token_skipsp(buf, j); - token2 = xs_token_getcopy(buf, j, ')'); -*/ -gint stil_token_skipsp(gchar *buf, gint i) -{ - gint len = strlen(buf); - - while ((i < len) && ((buf[i] == 32) || (buf[i] == '\t'))) i++; - - return i; -} - - -gchar * stil_token_get(gchar *buf, gint i, gchar c) -{ - gint j, len = strlen(buf); - gchar *res; - - /* Find out the end place */ - j = i; - while ((buf[j] != c) && (j < len)) j++; - - /* Malloc some memory */ - len = (j - i); - res = (gchar *) g_malloc(len+1); - if (res == NULL) return NULL; - - /* Return the token */ - strncpy(res, &buf[i], len); - res[len] = '\0'; - - return res; -} - - -/* - * Clear the informations - */ -void xs_stil_clearone(T_sid_stil_subtune *tune) -{ - xs_strcalloc(&tune->title, "\0"); - xs_strcalloc(&tune->name, "\0"); - xs_strcalloc(&tune->artist, "\0"); - xs_strcalloc(&tune->comment, "\0"); -} - -void xs_stil_clear(void) -{ - int i; - - for (i = 0; i < XMMS_SID_STIL_MAXENTRY; i++) - xs_stil_clearone(&xs_stil_info.subtune[i]); -} - - -/* - * Simple string-list handling functions - */ -typedef struct { - gint nitems; - gchar * * items; -} T_stringlist; - - -int sl_insert(T_stringlist *list, gchar *str) -{ - gchar *res; - - /* Check the list pointer */ - if (list == NULL) return -1; - if (str == NULL) return -2; - - /* Increase the space in pointer list */ - list->nitems++; - - list->items = (gchar * *) g_realloc(list->items, (sizeof(gchar **) * list->nitems)); - if (list->items == NULL) return -3; - - /* Allocate space for the string */ - res = (gchar *) g_malloc(strlen(str) + 1); - if (res == NULL) return -4; - - /* Put the data in */ - strcpy(res, str); - list->items[(list->nitems - 1)] = res; - - /* Return number of items */ - return (list->nitems); -} - - -gchar * sl_getitem(T_stringlist *list, gint n) -{ - /* Check the list pointer */ - if (list == NULL) return NULL; - if (list->items == NULL) return NULL; - - /* Check the argument */ - if ((n >= 0) && (n < list->nitems)) return (list->items[n]); - - return NULL; -} - - -int sl_clear(T_stringlist *list) -{ - /* Check the list pointer */ - if (list == NULL) return -1; - - /* Clear the variables */ - list->nitems = 0; - list->items = NULL; - - return 0; -} - - -int sl_free(T_stringlist *list) -{ - gint i; - - /* Check the list pointer */ - if (list == NULL) return -1; - - /* Check the items */ - if (list->items != NULL) - { - /* Free all strings in list, if any */ - for (i = 0; i < list->nitems; i++) - { - if (list->items[i] != NULL) - free(list->items[i]); - } - - /* Free the list itself */ - free(list->items); - } - - /* Clear the data */ - list->nitems = 0; - list->items = NULL; - - return 0; -} - - -/* - * "Submit" all gathered "lists" to given tunedef - */ -void xs_stil_submit(T_sid_stil_subtune *tune, T_stringlist *iartist, - T_stringlist *icomment, T_stringlist *iname, T_stringlist *ititle) -{ - gchar *tmpstr; - gint i, ok; - - /* Clear the data */ - xs_stil_clearone(tune); - - /* "Submit" lists to tunedata */ - if ((iartist->nitems > 1) || - (icomment->nitems > 1) || - (iname->nitems > 1) || - (ititle->nitems > 1)) - { - /* Multiple items per category */ - i = 0; - ok = 1; - while (ok) { - /* Clear the flag */ - ok = 0; - - /* Get items from lists */ - tmpstr = sl_getitem(iartist, i); - if (tmpstr != NULL) { - xs_strcat(&tune->comment, "\nArtist: "); - xs_strcat(&tune->comment, tmpstr); - ok = 1; - } - - tmpstr = sl_getitem(icomment, i); - if (tmpstr != NULL) { - xs_strcat(&tune->comment, "\nComment: "); - xs_strcat(&tune->comment, tmpstr); - ok = 1; - } - - tmpstr = sl_getitem(iname, i); - if (tmpstr != NULL) { - xs_strcat(&tune->comment, "\nName: "); - xs_strcat(&tune->comment, tmpstr); - ok = 1; - } - - tmpstr = sl_getitem(ititle, i); - if (tmpstr != NULL) { - xs_strcat(&tune->comment, "\nTitle: "); - xs_strcat(&tune->comment, tmpstr); - ok = 1; - } - - /* Next one */ - i++; - } - } else - { - /* Only one item or none */ - tmpstr = sl_getitem(iartist, 0); - if (tmpstr != NULL) xs_strcalloc(&tune->artist, tmpstr); - - tmpstr = sl_getitem(icomment, 0); - if (tmpstr != NULL) xs_strcalloc(&tune->comment, tmpstr); - - tmpstr = sl_getitem(iname, 0); - if (tmpstr != NULL) xs_strcalloc(&tune->name, tmpstr); - - tmpstr = sl_getitem(ititle, 0); - if (tmpstr != NULL) xs_strcalloc(&tune->title, tmpstr); - } - - /* Free the lists */ - sl_free(iartist); - sl_free(icomment); - sl_free(iname); - sl_free(ititle); -} - - -/* - * Parse all STIL data for one song (subsongs, etc) - */ -int xs_stil_parse_entry(FILE *stilf, gchar *buf, gint bufsize) -{ - T_stringlist iartist, icomment, iname, ititle; - gchar *token1, *token2, *tmpbuf; - gint ntune, found, found2; - gint i, j; - - XSDEBUG("token '%s':\n", buf); - - /* Clear and initialize variables */ - ntune = 0; - - sl_clear(&iartist); - sl_clear(&icomment); - sl_clear(&iname); - sl_clear(&ititle); - - tmpbuf = NULL; - - /* Ok, it was found! Now get and parse the data */ - found = ntune = 0; - - while ((!feof(stilf)) && (found == 0)) { - /* Get line from file */ - stil_get_line(buf, bufsize, stilf); - -nreadln: - - /* Check for empty (end of STIL record) */ - if (buf[0] == '\0') found = 1; else - - { - /* Skip whitespaces and get first token */ - j = 0; - token1 = (gchar *) (buf); - - /* Check for data types and act accordingly */ - if (token1[0] == '(') { - j = stil_token_skipsp(buf, j+1); - if (buf[j] == '#') { - token2 = stil_token_get(buf, j+1, ')'); - i = atoi(token2); - - if ((i >= 1) || (i < XMMS_SID_STIL_MAXENTRY)) { - - xs_stil_submit(&xs_stil_info.subtune[ntune], - &iartist, - &icomment, - &iname, - &ititle); - - ntune = i; - - XSDEBUG("tune_num: '%d'\n", ntune); - } - - g_free(token2); - } - } else - - if (!strncmp(token1, "COMMENT:", 8)) { - j = stil_token_skipsp(buf, j + 8); - token1 = (gchar *) (buf + j); - - if (xs_strcalloc(&tmpbuf, token1)) return -4; - - found2 = 0; - while ((!feof(stilf)) && (found2 == 0)) { - - /* Read next entry line */ - j = 0; - stil_get_line(buf, bufsize, stilf); - - /* Check if the comment continues? */ - if (strncmp(" ", buf, 9) != 0) { - found2 = 1; - } else { - - /* Get the comment line and parse it */ - j = stil_token_skipsp(buf, j + 9); - token1 = (gchar *) (buf + j); - - /* Cat to the end */ - if (xs_strcat(&tmpbuf, " ") < 0) return -4; - if (xs_strcat(&tmpbuf, token1) < 0) return -4; - - } /* if..else */ - } /* while */ - - - /* Insert the result */ - XSDEBUG("comment: '%s'\n", tmpbuf); - sl_insert(&icomment, tmpbuf); - - if (tmpbuf != NULL) free(tmpbuf); - tmpbuf = NULL; - - goto nreadln; /* EVIL GOTO! */ - } else - - if (!strncmp(token1, " TITLE:", 8)) { - j = stil_token_skipsp(buf, j + 8); - token1 = (gchar *) (buf + j); - - XSDEBUG("title : '%s'\n", token1); - sl_insert(&ititle, token1); - } else - - if (!strncmp(token1, " ARTIST:", 8)) { - j = stil_token_skipsp(buf, j + 8); - token1 = (gchar *) (buf + j); - - XSDEBUG("artist : '%s'\n", token1); - sl_insert(&iartist, token1); - } else - - if (!strncmp(token1, " NAME:", 8)) { - j = stil_token_skipsp(buf, j + 8); - token1 = (gchar *) (buf + j); - - XSDEBUG("name : '%s'\n", token1); - sl_insert(&iname, token1); - } - } - - } /* while */ - - - /* Submit the last entry */ - xs_stil_submit(&xs_stil_info.subtune[ntune], - &iartist, - &icomment, - &iname, - &ititle); - - - XSDEBUG("end of tunedef.\n"); - return 0; -} - - -/* - * Main routine for searching the STIL-database file - */ -int xs_stil_get(gchar *sidfn) -{ - FILE *stilf; - gchar *e, *a, *buf; - guint bufsize; - gint found, i, result; - struct stat stilst; - - - /* Clear the STIL info */ - xs_stil_clear(); - - /* Check the given STIL database filename */ - if ((!xs_cfg.stilpath || !xs_cfg.stilpath[0])) return -1; - - /* Check if the STIL database file exists */ - if (stat(xs_cfg.stilpath, &stilst) < 0) return -1; - - /* Try to allocate the temporary buffer */ - bufsize = (XMMS_SID_MAX_BUFSIZE + 1); - buf = (gchar *) g_malloc(bufsize); - if (buf == NULL) return -2; - - - /* Try to open the STIL database file */ - stilf = fopen(xs_cfg.stilpath, "r"); - if (!stilf) return -3; - - /* -- */ - e = uncase_strip_fn(xs_get_hvscname(sidfn)); - XSDEBUG("sfn = '%s'\n", e); - - result = found = 0; - - while ((!feof(stilf)) && (found == 0)) { - - stil_get_line(buf, bufsize, stilf); - - /* Ignore everything else until a filename is found */ - if (buf[0] == '/') { - - /* Check against our sidname */ - a = uncase_strip_fn((gchar *) (buf+1)); - i = strcmp(a, e); - g_free(a); - - /* Parse entry if found */ - if (!i) { - result = xs_stil_parse_entry(stilf, buf, bufsize); - found = 1; - } - - } /* if (buf[0]... */ - - } /* while */ - - /* Shutdown & close */ - g_free(e); - g_free(buf); - - if (!fclose(stilf)) return -3; - - /* Successful return ?? */ - if ((found) && (result >= 0)) - return 0; - else - return 1; -}