# HG changeset patch # User Matti Hamalainen # Date 1103621103 0 # Node ID 608f31f6c095e6095660e859024935e2489ba856 # Parent 7bb9e20e30924f77d7610065fac834a20a231abb Raw cleanup. diff -r 7bb9e20e3092 -r 608f31f6c095 src/xmms-sid.c --- a/src/xmms-sid.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xmms-sid.c Tue Dec 21 09:25:03 2004 +0000 @@ -62,22 +62,6 @@ /* - * Structure defining methods/functions of each player - */ -typedef struct { - gint plrIdent; - gboolean (*plrIsOurFile)(gchar *); - gboolean (*plrInit)(t_xs_status *); - void (*plrClose)(t_xs_status *); - gboolean (*plrInitSong)(t_xs_status *); - guint (*plrFillBuffer)(t_xs_status *, gchar *, guint); - gboolean (*plrLoadSID)(t_xs_status *, gchar *); - void (*plrDeleteSID)(t_xs_status *); - t_xs_tune* (*plrGetSIDInfo)(gchar *); -} t_xs_player; - - -/* * List of players and links to their functions */ t_xs_player xs_playerlist[] = { @@ -107,23 +91,20 @@ /* * Global variables */ -struct t_xs_cfg xs_cfg; -t_xs_status xs_status; -t_xs_player *xs_player = NULL; -static pthread_t xs_decode_thread; -static pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; -static GtkWidget *xs_subctrl = NULL; -static GtkObject *xs_subctrl_adj = NULL; -static t_xs_tune *xs_fileinfotune = NULL; -static t_xs_stil_node *xs_fileinfostil = NULL; +t_xs_status xs_status; +XS_MUTEX(xs_status); +static pthread_t xs_decode_thread; +static GtkWidget *xs_subctrl = NULL; +static GtkObject *xs_subctrl_adj = NULL; +XS_MUTEX(xs_subctrl); void xs_subctrl_close(void); void xs_subctrl_update(void); /* - * Re-initialize some settings + * Initialization functions */ void xs_reinit(void) { @@ -153,7 +134,7 @@ if (xs_playerlist[iPlayer].plrInit(&xs_status)) { isInitialized = TRUE; - xs_player = (t_xs_player *) &xs_playerlist[iPlayer]; + xs_status.sidPlayer = (t_xs_player *) &xs_playerlist[iPlayer]; } } iPlayer++; @@ -167,7 +148,7 @@ if (xs_playerlist[iPlayer].plrInit(&xs_status)) { isInitialized = TRUE; - xs_player = (t_xs_player *) &xs_playerlist[iPlayer]; + xs_status.sidPlayer = (t_xs_player *) &xs_playerlist[iPlayer]; } else iPlayer++; } @@ -176,14 +157,14 @@ /* Initialize song-length database */ xs_songlen_close(); - if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0)) + if (xs_cfg.songlenDBEnable && (xs_songlen_init() != 0)) { XSERR("Error initializing song-length database!\n"); } /* Initialize STIL database */ xs_stil_close(); - if (xs_cfg.stilDBEnable && (xs_stil_init() < 0)) + if (xs_cfg.stilDBEnable && (xs_stil_init() != 0)) { XSERR("Error initializing STIL database!\n"); } @@ -218,11 +199,11 @@ /* Stop playing, free structures */ xs_stop(); - xs_tune_free(xs_status.pTune); - xs_status.pTune = NULL; + xs_tuneinfo_free(xs_status.tuneInfo); + xs_status.tuneInfo = NULL; - xs_player->plrDeleteSID(&xs_status); - xs_player->plrClose(&xs_status); + xs_status.sidPlayer->plrDeleteSID(&xs_status); + xs_status.sidPlayer->plrClose(&xs_status); xs_songlen_close(); xs_stil_close(); @@ -237,14 +218,14 @@ gint xs_is_our_file(gchar *pcFilename) { gchar *pcExt; - assert(xs_player); + assert(xs_status.sidPlayer); /* Check the filename */ if (pcFilename == NULL) return FALSE; /* Try to detect via detection routine, if required */ - if (xs_cfg.detectMagic && xs_player->plrIsOurFile(pcFilename)) + if (xs_cfg.detectMagic && xs_status.sidPlayer->plrIsOurFile(pcFilename)) return TRUE; /* Detect just by checking filename extension */ @@ -274,18 +255,18 @@ void *xs_play_loop(void *argPointer) { t_xs_status myStatus; - t_xs_tune *myTune; + t_xs_tuneinfo *myTune; gboolean audioOpen = FALSE, doPlay = FALSE; guint audioGot; gint songLength; gchar audioBuffer[XS_BUFSIZE]; /* Initialize */ - pthread_mutex_lock(&xs_mutex); - XSDEBUG("entering play thread\n"); + XSDEBUG("entering player thread\n"); + XS_MUTEX_LOCK(xs_status); memcpy(&myStatus, &xs_status, sizeof(t_xs_status)); - myTune = xs_status.pTune; - pthread_mutex_unlock(&xs_mutex); + myTune = xs_status.tuneInfo; + XS_MUTEX_UNLOCK(xs_status); /* @@ -294,27 +275,31 @@ doPlay = TRUE; while (xs_status.isPlaying && doPlay) { - pthread_mutex_lock(&xs_mutex); + XS_MUTEX_LOCK(xs_status); myStatus.currSong = xs_status.currSong; - pthread_mutex_unlock(&xs_mutex); + XS_MUTEX_UNLOCK(xs_status); + XS_MUTEX_LOCK(xs_subctrl); xs_subctrl_update(); + XS_MUTEX_UNLOCK(xs_subctrl); XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); songLength = myTune->subTunes[myStatus.currSong - 1].tuneLength; /* Check minimum playtime */ + XS_MUTEX_LOCK(xs_cfg); if (xs_cfg.playMinTimeEnable) { if (songLength < xs_cfg.playMinTime) songLength = xs_cfg.playMinTime; } + XS_MUTEX_UNLOCK(xs_cfg); /* Initialize song */ - if (!xs_player->plrInitSong(&myStatus)) + if (!myStatus.sidPlayer->plrInitSong(&myStatus)) { XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n", - myTune->tuneFilename, myStatus.currSong); + myTune->sidFilename, myStatus.currSong); goto xs_err_exit; } @@ -333,9 +318,10 @@ { XSERR("Couldn't open XMMS audio output (fmt=%x, freq=%i, nchan=%i)!\n", myStatus.audioFormat, myStatus.audioFrequency, myStatus.audioChannels); - pthread_mutex_lock(&xs_mutex); + + XS_MUTEX_LOCK(xs_status); xs_status.isError = TRUE; - pthread_mutex_unlock(&xs_mutex); + XS_MUTEX_UNLOCK(xs_status); goto xs_err_exit; } @@ -347,7 +333,7 @@ while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == myStatus.currSong)) { /* Render audio data */ - audioGot = xs_player->plrFillBuffer(&myStatus, audioBuffer, XS_BUFSIZE); + audioGot = myStatus.sidPlayer->plrFillBuffer(&myStatus, audioBuffer, XS_BUFSIZE); /* I <3 visualice/haujobb */ xs_plugin_ip.add_vis_pcm( @@ -366,6 +352,7 @@ xs_plugin_ip.output->write_audio(audioBuffer, audioGot); /* Check if we have played enough */ + XS_MUTEX_LOCK(xs_cfg); if (xs_cfg.playMaxTimeEnable) { if (xs_cfg.playMaxTimeUnknown) @@ -378,6 +365,7 @@ myStatus.isPlaying = FALSE; } } + XS_MUTEX_UNLOCK(xs_cfg); if (songLength > 0) { @@ -411,9 +399,9 @@ /* Exit the playing thread */ XSDEBUG("exiting thread, bye.\n"); - pthread_mutex_lock(&xs_mutex); + XS_MUTEX_LOCK(xs_status); xs_status.isPlaying = FALSE; - pthread_mutex_unlock(&xs_mutex); + XS_MUTEX_UNLOCK(xs_status); pthread_exit(NULL); } @@ -426,17 +414,19 @@ */ void xs_play_file(gchar *pcFilename) { + assert(xs_status.sidPlayer); + XSDEBUG("play '%s'\n", pcFilename); /* Get tune information */ - if ((xs_status.pTune = xs_player->plrGetSIDInfo(pcFilename)) == NULL) + if ((xs_status.tuneInfo = xs_status.sidPlayer->plrGetSIDInfo(pcFilename)) == NULL) return; /* Initialize the tune */ - if (!xs_player->plrLoadSID(&xs_status, pcFilename)) + if (!xs_status.sidPlayer->plrLoadSID(&xs_status, pcFilename)) { - xs_tune_free(xs_status.pTune); - xs_status.pTune = NULL; + xs_tuneinfo_free(xs_status.tuneInfo); + xs_status.tuneInfo = NULL; return; } @@ -445,15 +435,15 @@ /* Set general status information */ xs_status.isPlaying = TRUE; xs_status.isError = FALSE; - xs_status.currSong = xs_status.pTune->startTune; + xs_status.currSong = xs_status.tuneInfo->startTune; /* Start the playing thread! */ if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0) { XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno)); - xs_tune_free(xs_status.pTune); - xs_status.pTune = NULL; - xs_player->plrDeleteSID(&xs_status); + xs_tuneinfo_free(xs_status.tuneInfo); + xs_status.tuneInfo = NULL; + xs_status.sidPlayer->plrDeleteSID(&xs_status); } XSDEBUG("systems should be up?\n"); @@ -479,16 +469,16 @@ { /* Stop playing */ XSDEBUG("stopping...\n"); - pthread_mutex_lock(&xs_mutex); + XS_MUTEX_LOCK(xs_status); xs_status.isPlaying = FALSE; - pthread_mutex_unlock(&xs_mutex); + XS_MUTEX_UNLOCK(xs_status); pthread_join(xs_decode_thread, NULL); } /* Free tune information */ - xs_player->plrDeleteSID(&xs_status); - xs_tune_free(xs_status.pTune); - xs_status.pTune = NULL; + xs_status.sidPlayer->plrDeleteSID(&xs_status); + xs_tuneinfo_free(xs_status.tuneInfo); + xs_status.tuneInfo = NULL; /* Update subtune control */ xs_subctrl_update(); @@ -506,104 +496,100 @@ /* + * Set or change sub-tune + */ +void xs_set_subtune(int n) +{ + XS_MUTEX_LOCK(xs_status); + + if (xs_status.tuneInfo && xs_status.isPlaying) + { + if ((n >= 1) && (n <= xs_status.tuneInfo->nsubTunes)) + xs_status.currSong = n; + } + + XS_MUTEX_UNLOCK(xs_status); + + xs_subctrl_update(); +} + + +void xs_change_subtune(int n) +{ + XS_MUTEX_LOCK(xs_status); + + if (xs_status.tuneInfo && xs_status.isPlaying) + { + n += xs_status.currSong; + + if ((n >= 1) && (n <= xs_status.tuneInfo->nsubTunes)) + xs_status.currSong = n; + } + + XS_MUTEX_UNLOCK(xs_status); + + xs_subctrl_update(); +} + + +/* * Pop-up subtune selector */ -#define LUW(x...) lookup_widget(xs_fileinfowin, ## x) +void xs_subctrl_setsong(void) +{ + xs_set_subtune(GTK_ADJUSTMENT(xs_subctrl_adj)->value); +} + + +void xs_subctrl_prevsong(void) +{ + xs_change_subtune(-1); +} + + +void xs_subctrl_nextsong(void) +{ + xs_change_subtune( 1); +} + void xs_subctrl_update(void) { GtkAdjustment *tmpAdj; gboolean isEnabled; + XS_MUTEX_LOCK(xs_status); + /* Check if control window exists, we are currently playing and have a tune */ if (xs_subctrl) { - if (xs_status.pTune && xs_status.isPlaying) + if (xs_status.tuneInfo && xs_status.isPlaying) { + XS_MUTEX_LOCK(xs_subctrl); tmpAdj = GTK_ADJUSTMENT(xs_subctrl_adj); tmpAdj->value = xs_status.currSong; tmpAdj->lower = 1; - tmpAdj->upper = xs_status.pTune->nsubTunes; + tmpAdj->upper = xs_status.tuneInfo->nsubTunes; gtk_adjustment_value_changed(tmpAdj); + XS_MUTEX_UNLOCK(xs_subctrl); } else xs_subctrl_close(); } - if (xs_fileinfowin) - { - /* Check if we are currently playing and have a tune */ - if (xs_status.pTune && xs_status.isPlaying && (xs_status.pTune->nsubTunes > 1)) - { - tmpAdj = gtk_range_get_adjustment(GTK_RANGE(LUW("fileinfo_subctrl_adj"))); - - tmpAdj->value = xs_status.currSong; - tmpAdj->lower = 1; - tmpAdj->upper = xs_status.pTune->nsubTunes; - gtk_adjustment_value_changed(tmpAdj); - isEnabled = TRUE; - } else - isEnabled = FALSE; - - /* Enable or disable subtune-control in fileinfo window */ - gtk_widget_set_sensitive(LUW("fileinfo_subctrl_prev"), isEnabled); - gtk_widget_set_sensitive(LUW("fileinfo_subctrl_adj"), isEnabled); - gtk_widget_set_sensitive(LUW("fileinfo_subctrl_next"), isEnabled); - } -} - - -void xs_fileinfo_setsong(void) -{ - pthread_mutex_lock(&xs_mutex); - xs_status.currSong = gtk_range_get_adjustment(GTK_RANGE(LUW("fileinfo_subctrl_adj")))->value; - pthread_mutex_unlock(&xs_mutex); -} - - -void xs_subctrl_setsong(void) -{ - pthread_mutex_lock(&xs_mutex); - xs_status.currSong = GTK_ADJUSTMENT(xs_subctrl_adj)->value; - pthread_mutex_unlock(&xs_mutex); -} - - -void xs_subctrl_prevsong(void) -{ - if (xs_status.pTune && xs_status.isPlaying) - { - pthread_mutex_lock(&xs_mutex); - if (xs_status.currSong > 1) - xs_status.currSong--; - pthread_mutex_unlock(&xs_mutex); - } - - xs_subctrl_update(); -} - - -void xs_subctrl_nextsong(void) -{ - if (xs_status.pTune && xs_status.isPlaying) - { - pthread_mutex_lock(&xs_mutex); - if (xs_status.currSong < xs_status.pTune->nsubTunes) - xs_status.currSong++; - pthread_mutex_unlock(&xs_mutex); - } - - xs_subctrl_update(); + XS_MUTEX_UNLOCK(xs_status); } void xs_subctrl_close(void) { + XS_MUTEX_LOCK(xs_subctrl); if (xs_subctrl) { gtk_widget_destroy(xs_subctrl); xs_subctrl = NULL; } + XS_MUTEX_UNLOCK(xs_subctrl); } @@ -620,8 +606,14 @@ { GtkWidget *frame25, *hbox15, *subctrl_prev, *subctrl_current, *subctrl_next; - if (!xs_status.pTune || !xs_status.isPlaying || - xs_subctrl || (xs_status.pTune->nsubTunes <= 1)) return; + XS_MUTEX_LOCK(xs_subctrl); + + if (!xs_status.tuneInfo || !xs_status.isPlaying || + xs_subctrl || (xs_status.tuneInfo->nsubTunes <= 1)) + { + XS_MUTEX_UNLOCK(xs_subctrl); + return; + } /* Create the pop-up window */ xs_subctrl = gtk_window_new (GTK_WINDOW_DIALOG); @@ -656,7 +648,7 @@ gtk_widget_set_name (subctrl_prev, "subctrl_prev"); gtk_box_pack_start (GTK_BOX (hbox15), subctrl_prev, FALSE, FALSE, 0); - xs_subctrl_adj = gtk_adjustment_new (xs_status.currSong, 1, xs_status.pTune->nsubTunes, 1, 1, 0); + xs_subctrl_adj = gtk_adjustment_new (xs_status.currSong, 1, xs_status.tuneInfo->nsubTunes, 1, 1, 0); gtk_signal_connect (GTK_OBJECT (xs_subctrl_adj), "value_changed", GTK_SIGNAL_FUNC (xs_subctrl_setsong), NULL); @@ -681,6 +673,8 @@ GTK_SIGNAL_FUNC (xs_subctrl_keypress), NULL); gtk_widget_show_all(xs_subctrl); + + XS_MUTEX_UNLOCK(xs_subctrl); } @@ -696,16 +690,22 @@ void xs_seek(gint iTime) { /* Check status */ - if (!xs_status.pTune || !xs_status.isPlaying) return; + XS_MUTEX_LOCK(xs_status); + if (!xs_status.tuneInfo || !xs_status.isPlaying) + { + XS_MUTEX_UNLOCK(xs_status); + return; + } - /* Act according to settings */ + /* Act according to settings */ + XS_MUTEX_LOCK(xs_cfg); switch (xs_cfg.subsongControl) { case XS_SSC_SEEK: if (iTime < xs_status.lastTime) - xs_subctrl_prevsong(); + xs_change_subtune(-1); else if (iTime > xs_status.lastTime) - xs_subctrl_nextsong(); + xs_change_subtune(1); break; case XS_SSC_POPUP: @@ -715,18 +715,14 @@ /* If we have song-position patch, check settings */ #ifdef HAVE_SONG_POSITION case XS_SSC_PATCH: - pthread_mutex_lock(&xs_mutex); - - if ((iTime > 0) && (iTime <= xs_status.pTune->nsubTunes)) + if ((iTime > 0) && (iTime <= xs_status.tuneInfo->nsubTunes)) xs_status.currSong = iTime; - - pthread_mutex_unlock(&xs_mutex); break; #endif + } - default: - break; - } + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_status); } @@ -740,18 +736,30 @@ gint xs_get_time(void) { /* If errorflag is set, return -2 to signal it to XMMS's idle callback */ + XS_MUTEX_LOCK(xs_status); + if (xs_status.isError) + { + XS_MUTEX_UNLOCK(xs_status); return -2; + } /* If there is no tune, return -1 */ - if (!xs_status.pTune) + if (!xs_status.tuneInfo) + { + XS_MUTEX_UNLOCK(xs_status); return -1; + } /* If tune has ended, return -1 */ if (!xs_status.isPlaying) + { + XS_MUTEX_UNLOCK(xs_status); return -1; + } /* Let's see what we do */ + XS_MUTEX_LOCK(xs_cfg); switch (xs_cfg.subsongControl) { case XS_SSC_SEEK: xs_status.lastTime = (xs_plugin_ip.output->output_time() / 1000); @@ -759,13 +767,14 @@ #ifdef HAVE_SONG_POSITION case XS_SSC_PATCH: - pthread_mutex_lock(&xs_mutex); - set_song_position(xs_status.currSong, 1, xs_status.pTune->nsubTunes); - pthread_mutex_unlock(&xs_mutex); + set_song_position(xs_status.currSong, 1, xs_status.tuneInfo->nsubTunes); break; #endif } + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_status); + /* Return output time reported by audio output plugin */ return xs_plugin_ip.output->output_time(); } @@ -779,11 +788,11 @@ */ void xs_get_song_info(gchar *songFilename, gchar **songTitle, gint *songLength) { - t_xs_tune *pInfo; + t_xs_tuneinfo *pInfo; gint tmpInt; /* Get tune information from emulation engine */ - pInfo = xs_player->plrGetSIDInfo(songFilename); + pInfo = xs_status.sidPlayer->plrGetSIDInfo(songFilename); if (!pInfo) return; /* Get sub-tune information, if available */ @@ -799,50 +808,54 @@ } /* Free tune information */ - xs_tune_free(pInfo); + xs_tuneinfo_free(pInfo); } -/* - * Allocate a new tune structure +/* Allocate a new tune information structure */ -t_xs_tune *xs_tune_new(gchar *pcFilename, gint nsubTunes, gint startTune, - gchar *tuneName, gchar *tuneComposer, gchar *tuneCopyright) +t_xs_tuneinfo *xs_tuneinfo_new(gchar *pcFilename, gint nsubTunes, gint startTune, + gchar *sidName, gchar *sidComposer, gchar *sidCopyright, + gint loadAddr, gint initAddr, gint playAddr, gint dataFileLen) { - t_xs_tune *pResult; + t_xs_tuneinfo *pResult; - pResult = (t_xs_tune *) g_malloc0(sizeof(t_xs_tune)); + pResult = (t_xs_tuneinfo *) g_malloc0(sizeof(t_xs_tuneinfo)); if (!pResult) return NULL; - pResult->tuneFilename = g_strdup(pcFilename); - if (!pResult->tuneFilename) + pResult->sidFilename = g_strdup(pcFilename); + if (!pResult->sidFilename) { g_free(pResult); return NULL; } - pResult->tuneName = g_strdup(tuneName); - pResult->tuneComposer = g_strdup(tuneComposer); - pResult->tuneCopyright = g_strdup(tuneCopyright); + pResult->sidName = g_strdup(sidName); + pResult->sidComposer = g_strdup(sidComposer); + pResult->sidCopyright = g_strdup(sidCopyright); pResult->nsubTunes = nsubTunes; pResult->startTune = startTune; + + pResult->loadAddr = loadAddr; + pResult->initAddr = initAddr; + pResult->playAddr = playAddr; + pResult->dataFileLen = dataFileLen; return pResult; } -/* - * Free tune information +/* Free given tune information structure */ -void xs_tune_free(t_xs_tune *pTune) +void xs_tuneinfo_free(t_xs_tuneinfo *pTune) { gint i; if (!pTune) return; - g_free(pTune->tuneFilename); pTune->tuneFilename = NULL; - g_free(pTune->tuneName); pTune->tuneName = NULL; - g_free(pTune->tuneComposer); pTune->tuneComposer = NULL; - g_free(pTune->tuneCopyright); pTune->tuneCopyright = NULL; + g_free(pTune->sidFilename); pTune->sidFilename = NULL; + g_free(pTune->sidName); pTune->sidName = NULL; + g_free(pTune->sidComposer); pTune->sidComposer = NULL; + g_free(pTune->sidCopyright); pTune->sidCopyright = NULL; for (i = 0; i < pTune->nsubTunes; i++) { @@ -856,3 +869,7 @@ g_free(pTune); } + +void xs_fileinfo_ok(void) +{ +} diff -r 7bb9e20e3092 -r 608f31f6c095 src/xmms-sid.h --- a/src/xmms-sid.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xmms-sid.h Tue Dec 21 09:25:03 2004 +0000 @@ -22,10 +22,6 @@ #ifndef _XMMS_SID_H #define _XMMS_SID_H -#ifdef __cplusplus -extern "C" { -#endif - #ifdef HAVE_CONFIG_H #include #endif @@ -37,65 +33,125 @@ #endif #include +#include #include -/* - * Some defines +#ifdef __cplusplus +extern "C" { +#endif + +/* Some defines */ #define DEBUG + #undef HAVE_HARDSID_BUILDER /* HardSID-support is not working and is untested */ -/* - * Generals - */ #define XS_BUFSIZE (4096) /* Size for some buffers */ +#define XS_SIDBUF_SIZE (80*1024) /* Size of data buffer used for SID-tune + MD5 hash calculation. If this is too small, + the computed hash will be incorrect. + Largest SID files I've seen are ~70kB. + */ + +#define XS_SIDBUF_DYNAMIC /* If not defined, static buffer is used. + Probably faster than allocating/deallocating + from heap, but fails on systems with limited + stack space. + */ + +#define XS_STIL_MAXENTRY (128) /* Max number of sub-songs in STIL/SLDB node */ + + #define XS_CONFIG_IDENT "XMMS-SID" /* Configuration file identifier */ #define XS_CONFIG_FILE "/.xmms/xmms-sid" /* Use this configfile if autocyrpe fails */ -#define XS_STIL_MAXENTRY (128) /* Max number of sub-songs in STIL/SLDB node */ - #define XS_MIN_OVERSAMPLE (2) /* Minimum oversampling factor */ #define XS_MAX_OVERSAMPLE (8) /* Maximum oversampling factor */ -extern InputPlugin xs_plugin_ip; /* XMMS-SID plugin structure */ + +/* Macros for mutexes and threads. These exist to be able to + * easily change from pthreads to glib threads, etc, if necessary. + */ +#define XS_MPP(M) M ## _mutex +#ifdef DEBUG +#define XS_MUTEX(M) pthread_mutex_t XS_MPP(M) = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; int M ## _qq; +#else +#define XS_MUTEX(M) pthread_mutex_t XS_MPP(M) = PTHREAD_MUTEX_INITIALIZER +#endif +#define XS_MUTEX_H(M) extern pthread_mutex_t XS_MPP(M); extern int M ## _qq; +#define XS_MUTEX_LOCK(M) { M ## _qq = pthread_mutex_lock(&XS_MPP(M)); if (M ## _qq) XSDEBUG("XS_MUTEX_LOCK(" #M ") == %i\n", M ## _qq); } +#define XS_MUTEX_UNLOCK(M) { M ## _qq = pthread_mutex_unlock(&XS_MPP(M)); if (M ## _qq) XSDEBUG("XS_MUTEX_UNLOCK(" #M ") == %i\n", M ## _qq); } + +/* Shorthands for linked lists + */ +#define LPREV (pNode->pPrev) +#define LTHIS (pNode) +#define LNEXT (pNode->pNext) +/* Plugin-wide typedefs + */ typedef struct { gint tuneSpeed; gint tuneLength; gchar *tuneTitle; -} t_xs_subtune; - - -typedef struct { - gchar *tuneFilename, - *tuneName, - *tuneComposer, - *tuneCopyright; - gint nsubTunes, startTune; - t_xs_subtune subTunes[XS_STIL_MAXENTRY]; -} t_xs_tune; +} t_xs_subtuneinfo; typedef struct { - gint audioFrequency, + gchar *sidFilename, + *sidName, + *sidComposer, + *sidCopyright; + gint loadAddr, + initAddr, + playAddr, + dataFileLen; + gint nsubTunes, startTune; + t_xs_subtuneinfo subTunes[XS_STIL_MAXENTRY]; +} t_xs_tuneinfo; + + +struct t_xs_status; + +typedef struct { + gint plrIdent; + gboolean (*plrIsOurFile)(gchar *); + gboolean (*plrInit)(struct t_xs_status *); + void (*plrClose)(struct t_xs_status *); + gboolean (*plrInitSong)(struct t_xs_status *); + guint (*plrFillBuffer)(struct t_xs_status *, gchar *, guint); + gboolean (*plrLoadSID)(struct t_xs_status *, gchar *); + void (*plrDeleteSID)(struct t_xs_status *); + t_xs_tuneinfo* (*plrGetSIDInfo)(gchar *); +} t_xs_player; + + +typedef struct t_xs_status { + gint audioFrequency, /* Audio settings */ audioFormat, audioChannels, audioBitsPerSample; - void *player; + void *sidEngine; /* SID-emulation internal engine data */ + t_xs_player *sidPlayer; /* Selected player engine */ gboolean isError, isPlaying; - gint currSong, + gint currSong, /* Current sub-tune */ lastTime; - t_xs_tune *pTune; + t_xs_tuneinfo *tuneInfo; } t_xs_status; -extern t_xs_status xs_status; +/* Global variables + */ +extern InputPlugin xs_plugin_ip; + +extern t_xs_status xs_status; +XS_MUTEX_H(xs_status); -/* - * Plugin function prototypes + +/* Plugin function prototypes */ void xs_init(void); void xs_reinit(void); @@ -109,16 +165,16 @@ void xs_get_song_info(gchar *, gchar **, gint *); void xs_fileinfo(gchar *); void xs_about(void); +void xs_set_subtune(gint); -t_xs_tune *xs_tune_new(gchar *, gint, gint, gchar *, gchar *, gchar *); -void xs_tune_free(t_xs_tune *); +t_xs_tuneinfo *xs_tuneinfo_new(gchar *, gint, gint, gchar *, gchar *, gchar *, gint, gint, gint, gint); +void xs_tuneinfo_free(t_xs_tuneinfo *); -/* - * Debugging and error handling macros +/* Debugging and error handling macros */ #ifdef DEBUG -#define XSDEBUG(x...) { fprintf(stderr, "XS[%s:%d]: ", __FILE__, (int) __LINE__); fprintf(stderr, ## x); } +#define XSDEBUG(x...) { fprintf(stderr, "XS[%s:%s:%d]: ", __FILE__, __FUNCTION__, (int) __LINE__); fprintf(stderr, ## x); } #else #define XSDEBUG(x...) /* foo */ #endif diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_config.c --- a/src/xs_config.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_config.c Tue Dec 21 09:25:03 2004 +0000 @@ -145,21 +145,10 @@ static const gint xs_widtable_max = (sizeof(xs_widtable) / sizeof(t_xs_wid_item)); -/* - * Reset the filter settings - */ -void xs_reset_filters(void) -{ - /* Reset filter values (copied from libsidplay1's headers) */ - XS_MUTEX_LOCK(xs_cfg); - - xs_cfg.filterFs = 400.0f; - xs_cfg.filterFm = 60.0f; - xs_cfg.filterFt = 0.05f; - - XS_MUTEX_UNLOCK(xs_cfg); -} - +/* libSIDPlay1 default filter values (copied from libsidplay1's headers) */ +#define XS_SIDPLAY1_FS (400.0f) +#define XS_SIDPLAY1_FM (60.0f) +#define XS_SIDPLAY1_FT (0.05f) /* * Get the configuration (from file or default) @@ -179,8 +168,11 @@ xs_cfg.audioFrequency = 44100; xs_cfg.mos8580 = FALSE; + xs_cfg.emulateFilters = TRUE; - xs_reset_filters(); + xs_cfg.filterFs = XS_SIDPLAY1_FS; + xs_cfg.filterFm = XS_SIDPLAY1_FM; + xs_cfg.filterFt = XS_SIDPLAY1_FT; #ifdef HAVE_SIDPLAY2 xs_cfg.playerEngine = XS_ENG_SIDPLAY2; @@ -463,15 +455,17 @@ */ void xs_cfg_filter_reset(void) { - XS_MUTEX_LOCK(xs_cfg); - - xs_reset_filters(); + gtk_adjustment_set_value( + gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_fs"))), + XS_SIDPLAY1_FS); - gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_fs"))), xs_cfg.filterFs); - gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_fm"))), xs_cfg.filterFm); - gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_ft"))), xs_cfg.filterFt); + gtk_adjustment_set_value( + gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_fm"))), + XS_SIDPLAY1_FM); - XS_MUTEX_UNLOCK(xs_cfg); + gtk_adjustment_set_value( + gtk_range_get_adjustment(GTK_RANGE(LUW("cfg_emu_filt_ft"))), + XS_SIDPLAY1_FT); } diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_fileinfo.c --- a/src/xs_fileinfo.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_fileinfo.c Tue Dec 21 09:25:03 2004 +0000 @@ -29,10 +29,17 @@ #include "xs_glade.h" static GtkWidget *xs_fileinfowin = NULL; +static t_xs_stil_node *xs_fileinfostil = NULL; +static t_xs_tuneinfo *xs_fileinfotune = NULL; #define LUW(x...) lookup_widget(xs_fileinfowin, ## x) +void xs_fileinfo_setsong(void) +{ +} + + void xs_fileinfo_ok(void) { gtk_widget_destroy(xs_fileinfowin); @@ -95,7 +102,7 @@ /* Free old info, if set */ if (xs_fileinfotune) - xs_tune_free(xs_fileinfotune); + xs_tuneinfo_free(xs_fileinfotune); /* Get new tune information */ if ((xs_fileinfotune = xs_player->plrGetSIDInfo(pcFilename)) == NULL) @@ -174,9 +181,6 @@ /* Set the subtune information */ xs_fileinfo_subtune(NULL, tmpMenu); - /* Update subtune controls */ - xs_subctrl_update(); - /* Show the window */ gtk_widget_show(xs_fileinfowin); } diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_init.c --- a/src/xs_init.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_init.c Tue Dec 21 09:25:03 2004 +0000 @@ -46,7 +46,7 @@ NULL, /* Send data to Visualization plugin */ NULL, NULL, /* FILLED BY XMMS */ xs_get_song_info, /* Get song title and length */ - xs_fileinfo, /* Show file-information dialog */ + NULL, /*xs_fileinfo, Show file-information dialog */ NULL /* FILLED BY XMMS */ }; diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_length.c --- a/src/xs_length.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_length.c Tue Dec 21 09:25:03 2004 +0000 @@ -21,6 +21,7 @@ */ #include "xs_length.h" #include "xs_support.h" +#include "xs_config.h" #include #include #include @@ -553,3 +554,86 @@ return pResult; } + + +/* + * These should be moved out of this module some day ... + */ +static t_xs_sldb *xs_sldb_db = NULL; +XS_MUTEX(xs_sldb_db); + +gint xs_songlen_init(void) +{ + XS_MUTEX_LOCK(xs_cfg); + + if (!xs_cfg.songlenDBPath) + { + XS_MUTEX_UNLOCK(xs_cfg); + return -1; + } + + XS_MUTEX_LOCK(xs_sldb_db); + + /* Check if already initialized */ + if (xs_sldb_db) xs_sldb_free(xs_sldb_db); + + /* Allocate database */ + xs_sldb_db = (t_xs_sldb *) g_malloc0(sizeof(t_xs_sldb)); + if (!xs_sldb_db) + { + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_sldb_db); + return -2; + } + + /* Read the database */ + if (xs_sldb_read(xs_sldb_db, xs_cfg.songlenDBPath) != 0) + { + xs_sldb_free(xs_sldb_db); + xs_sldb_db = NULL; + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_sldb_db); + return -3; + } + + /* Create index */ + if (xs_sldb_index(xs_sldb_db) != 0) + { + xs_sldb_free(xs_sldb_db); + xs_sldb_db = NULL; + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_sldb_db); + return -4; + } + + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_sldb_db); + return 0; +} + + +void xs_songlen_close(void) +{ + XS_MUTEX_LOCK(xs_sldb_db); + xs_sldb_free(xs_sldb_db); + xs_sldb_db = NULL; + XS_MUTEX_UNLOCK(xs_sldb_db); +} + + +t_xs_sldb_node * xs_songlen_get(gchar *pcFilename) +{ + t_xs_sldb_node *pResult; + + XS_MUTEX_LOCK(xs_sldb_db); + + if (xs_cfg.songlenDBEnable && xs_sldb_db) + pResult = xs_sldb_get(xs_sldb_db, pcFilename); + else + pResult = NULL; + + XS_MUTEX_UNLOCK(xs_sldb_db); + + return pResult; +} + diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_length.h --- a/src/xs_length.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_length.h Tue Dec 21 09:25:03 2004 +0000 @@ -36,6 +36,10 @@ t_xs_sldb_node * xs_sldb_get(t_xs_sldb *, gchar *); +gint xs_songlen_init(void); +void xs_songlen_close(void); +t_xs_sldb_node * xs_songlen_get(gchar *); + #ifdef __cplusplus } #endif diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_sidplay.h --- a/src/xs_sidplay.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_sidplay.h Tue Dec 21 09:25:03 2004 +0000 @@ -3,10 +3,10 @@ * Get all SID-tune information (for all sub-tunes) * including name, length, etc. */ -t_xs_tune * TFUNCTION(gchar *pcFilename) +t_xs_tuneinfo * TFUNCTION(gchar *pcFilename) { t_xs_sldb_node *tuneLength = NULL; - t_xs_tune *pResult; + t_xs_tuneinfo *pResult; TTUNEINFO tuneInfo; TTUNE *testTune; gboolean haveInfo = TRUE; @@ -35,7 +35,7 @@ tuneLength = xs_songlen_get(pcFilename); /* Allocate tuneinfo structure */ - pResult = xs_tune_new(pcFilename, + pResult = xs_tuneinfo_new(pcFilename, tuneInfo.songs, tuneInfo.startSong, tuneInfo.infoString[0], tuneInfo.infoString[1], tuneInfo.infoString[2], tuneInfo.loadAddr, tuneInfo.initAddr, tuneInfo.playAddr, diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_sidplay1.cc --- a/src/xs_sidplay1.cc Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_sidplay1.cc Tue Dec 21 09:25:03 2004 +0000 @@ -23,13 +23,11 @@ #ifdef HAVE_SIDPLAY1 -extern "C" { #include "xs_sidplay1.h" #include #include "xs_config.h" #include "xs_length.h" #include "xs_title.h" -} #include #include @@ -73,32 +71,32 @@ */ gboolean xs_sidplay1_init(t_xs_status *myStatus) { - t_xs_sidplay1 *myPlayer; + t_xs_sidplay1 *myEngine; assert(myStatus); /* Allocate internal structures */ - myPlayer = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1)); - if (!myPlayer) return FALSE; + myEngine = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1)); + if (!myEngine) return FALSE; /* Initialize engine */ - myPlayer->currEng = new emuEngine(); - if (!myPlayer->currEng) + myEngine->currEng = new emuEngine(); + if (!myEngine->currEng) { XSERR("Could not initialize libSIDPlay1 emulation engine\n"); - g_free(myPlayer); + g_free(myEngine); return FALSE; } /* Verify endianess */ - if (!myPlayer->currEng->verifyEndianess()) + if (!myEngine->currEng->verifyEndianess()) { XSERR("Endianess verification failed\n"); - delete myPlayer->currEng; - g_free(myPlayer); + delete myEngine->currEng; + g_free(myEngine); return FALSE; } - myStatus->player = myPlayer; + myStatus->sidEngine = myEngine; return TRUE; } @@ -108,56 +106,56 @@ */ void xs_sidplay1_close(t_xs_status *myStatus) { - t_xs_sidplay1 *myPlayer; + t_xs_sidplay1 *myEngine; assert(myStatus); /* Free internals */ - myPlayer = (t_xs_sidplay1 *) myStatus->player; - if (myPlayer->currEng) + myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; + if (myEngine->currEng) { - delete myPlayer->currEng; - myPlayer->currEng = NULL; + delete myEngine->currEng; + myEngine->currEng = NULL; } - g_free(myPlayer); - myStatus->player = NULL; + g_free(myEngine); + myStatus->sidEngine = NULL; } gboolean xs_sidplay1_initsong(t_xs_status *myStatus) { - t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player; + t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; - if (!myPlayer) return FALSE; + if (!myEngine) return FALSE; - if (!myPlayer->currTune) + if (!myEngine->currTune) { XSERR("Tune was NULL\n"); return FALSE; } - if (!myPlayer->currTune->getStatus()) + if (!myEngine->currTune->getStatus()) { XSERR("Tune status check failed\n"); return FALSE; } return sidEmuInitializeSong( - *myPlayer->currEng, - *myPlayer->currTune, + *myEngine->currEng, + *myEngine->currTune, myStatus->currSong); } guint xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize) { - t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player; + t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; - if (!myPlayer) return FALSE; + if (!myEngine) return FALSE; sidEmuFillBuffer( - *myPlayer->currEng, - *myPlayer->currTune, + *myEngine->currEng, + *myEngine->currTune, audioBuffer, audioBufSize); @@ -167,7 +165,7 @@ gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFilename) { - t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player; + t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; sidTune *newTune; assert(myStatus); @@ -177,28 +175,28 @@ if (!newTune) return FALSE; /* Get current configuration */ - myPlayer->currEng->getConfig(myPlayer->currConfig); + myEngine->currEng->getConfig(myEngine->currConfig); /* Configure channels and stuff */ switch (myStatus->audioChannels) { case XS_CHN_AUTOPAN: - myPlayer->currConfig.channels = SIDEMU_STEREO; - myPlayer->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING; - myPlayer->currConfig.volumeControl = SIDEMU_FULLPANNING; + myEngine->currConfig.channels = SIDEMU_STEREO; + myEngine->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING; + myEngine->currConfig.volumeControl = SIDEMU_FULLPANNING; break; case XS_CHN_STEREO: - myPlayer->currConfig.channels = SIDEMU_STEREO; - myPlayer->currConfig.autoPanning = SIDEMU_NONE; - myPlayer->currConfig.volumeControl = SIDEMU_NONE; + myEngine->currConfig.channels = SIDEMU_STEREO; + myEngine->currConfig.autoPanning = SIDEMU_NONE; + myEngine->currConfig.volumeControl = SIDEMU_NONE; break; case XS_CHN_MONO: default: - myPlayer->currConfig.channels = SIDEMU_MONO; - myPlayer->currConfig.autoPanning = SIDEMU_NONE; - myPlayer->currConfig.volumeControl = SIDEMU_NONE; + myEngine->currConfig.channels = SIDEMU_MONO; + myEngine->currConfig.autoPanning = SIDEMU_NONE; + myEngine->currConfig.volumeControl = SIDEMU_NONE; break; } @@ -206,19 +204,19 @@ /* Memory mode settings */ switch (xs_cfg.memoryMode) { case XS_MPU_BANK_SWITCHING: - myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING; + myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; break; case XS_MPU_TRANSPARENT_ROM: - myPlayer->currConfig.memoryMode = MPU_TRANSPARENT_ROM; + myEngine->currConfig.memoryMode = MPU_TRANSPARENT_ROM; break; case XS_MPU_PLAYSID_ENVIRONMENT: - myPlayer->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; + myEngine->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; break; default: - myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING; + myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; break; } @@ -226,37 +224,37 @@ /* Clockspeed settings */ switch (xs_cfg.clockSpeed) { case XS_CLOCK_NTSC: - myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; + myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; break; case XS_CLOCK_PAL: default: - myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; + myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; break; } /* Configure rest of the emulation */ - myPlayer->currConfig.mos8580 = xs_cfg.mos8580; - myPlayer->currConfig.emulateFilter = xs_cfg.emulateFilters; - myPlayer->currConfig.filterFs = xs_cfg.filterFs; - myPlayer->currConfig.filterFm = xs_cfg.filterFm; - myPlayer->currConfig.filterFt = xs_cfg.filterFt; + myEngine->currConfig.mos8580 = xs_cfg.mos8580; + myEngine->currConfig.emulateFilter = xs_cfg.emulateFilters; + myEngine->currConfig.filterFs = xs_cfg.filterFs; + myEngine->currConfig.filterFm = xs_cfg.filterFm; + myEngine->currConfig.filterFt = xs_cfg.filterFt; - myPlayer->currConfig.bitsPerSample = myStatus->audioBitsPerSample; - myPlayer->currConfig.frequency = myStatus->audioFrequency; + myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample; + myEngine->currConfig.frequency = myStatus->audioFrequency; switch (myStatus->audioBitsPerSample) { case XS_RES_8BIT: switch (myStatus->audioFormat) { case FMT_S8: - myPlayer->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; + myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; break; case FMT_U8: default: myStatus->audioFormat = FMT_U8; - myPlayer->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; + myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; break; } break; @@ -267,7 +265,7 @@ case FMT_U16_LE: case FMT_U16_BE: myStatus->audioFormat = FMT_U16_NE; - myPlayer->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; + myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; break; case FMT_S16_NE: @@ -275,21 +273,21 @@ case FMT_S16_BE: default: myStatus->audioFormat = FMT_S16_NE; - myPlayer->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; + myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; break; } break; } /* Now set the emulator configuration */ - if (!myPlayer->currEng->setConfig(myPlayer->currConfig)) + if (!myEngine->currEng->setConfig(myEngine->currConfig)) { XSERR("Emulator engine configuration failed!\n"); return FALSE; } /* Initialize status information */ - myPlayer->currTune = newTune; + myEngine->currTune = newTune; return TRUE; } @@ -300,16 +298,16 @@ */ void xs_sidplay1_deletesid(t_xs_status *myStatus) { - t_xs_sidplay1 *myPlayer; + t_xs_sidplay1 *myEngine; assert(myStatus); - myPlayer = (t_xs_sidplay1 *) myStatus->player; - if (!myPlayer) return; + myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; + if (!myEngine) return; - if (myPlayer->currTune) + if (myEngine->currTune) { - delete myPlayer->currTune; - myPlayer->currTune = NULL; + delete myEngine->currTune; + myEngine->currTune = NULL; } } diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_sidplay1.h --- a/src/xs_sidplay1.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_sidplay1.h Tue Dec 21 09:25:03 2004 +0000 @@ -3,6 +3,10 @@ #include "xmms-sid.h" +#ifdef __cplusplus +extern "C" { +#endif + gboolean xs_sidplay1_isourfile(gchar *); void xs_sidplay1_close(t_xs_status *); gboolean xs_sidplay1_init(t_xs_status *); @@ -10,6 +14,9 @@ guint xs_sidplay1_fillbuffer(t_xs_status *, gchar *, guint); gboolean xs_sidplay1_loadsid(t_xs_status *, gchar *); void xs_sidplay1_deletesid(t_xs_status *); -t_xs_tune* xs_sidplay1_getsidinfo(gchar *); +t_xs_tuneinfo* xs_sidplay1_getsidinfo(gchar *); +#ifdef __cplusplus +} +#endif #endif /* _XS_SIDPLAY1_H */ diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_sidplay2.cc --- a/src/xs_sidplay2.cc Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_sidplay2.cc Tue Dec 21 09:25:03 2004 +0000 @@ -23,14 +23,12 @@ #ifdef HAVE_SIDPLAY2 -extern "C" { #include "xs_sidplay2.h" #include -#include #include "xs_config.h" #include "xs_support.h" #include "xs_length.h" -} +#include "xs_title.h" #include #ifdef HAVE_RESID_BUILDER @@ -79,17 +77,17 @@ */ gboolean xs_sidplay2_init(t_xs_status *myStatus) { - t_xs_sidplay2 *myPlayer; + t_xs_sidplay2 *myEngine; assert(myStatus); /* Allocate internal structures */ - myPlayer = (t_xs_sidplay2 *) g_malloc0(sizeof(t_xs_sidplay2)); - if (!myPlayer) return FALSE; + myEngine = (t_xs_sidplay2 *) g_malloc0(sizeof(t_xs_sidplay2)); + if (!myEngine) return FALSE; /* Initialize the engine */ - myPlayer->currEng = new sidplay2; - if (!myPlayer->currEng) + myEngine->currEng = new sidplay2; + if (!myEngine->currEng) { XSERR("Could not initialize libSIDPlay2 emulation engine\n"); return FALSE; @@ -103,9 +101,9 @@ ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx and is made by a fag - ReSID builder"); /* Create the builder -- WHAT IS THIS MEANT FOR??? */ - tmpb->create(myPlayer->currEng->info().maxsids); + tmpb->create(myEngine->currEng->info().maxsids); - myPlayer->currBuilder = (sidbuilder *) tmpb; + myEngine->currBuilder = (sidbuilder *) tmpb; } #endif #ifdef HAVE_HARDSID_BUILDER @@ -114,25 +112,25 @@ } #endif - if (!myPlayer->currBuilder) + if (!myEngine->currBuilder) { XSERR("Could not initialize SIDBuilder object.\n"); return FALSE; } - XSDEBUG("%s\n", myPlayer->currBuilder->credits()); + XSDEBUG("%s\n", myEngine->currBuilder->credits()); /* Create the sidtune */ - myPlayer->currTune = new SidTune(0); - if (!myPlayer->currTune) + myEngine->currTune = new SidTune(0); + if (!myEngine->currTune) { XSERR("Could not initialize SIDTune object.\n"); return FALSE; } /* OK */ - myStatus->player = myPlayer; + myStatus->sidEngine = myEngine; return TRUE; } @@ -142,50 +140,50 @@ */ void xs_sidplay2_close(t_xs_status *myStatus) { - t_xs_sidplay2 *myPlayer; + t_xs_sidplay2 *myEngine; assert(myStatus); /* Free internals */ - myPlayer = (t_xs_sidplay2 *) myStatus->player; + myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - if (myPlayer->currBuilder) + if (myEngine->currBuilder) { - delete myPlayer->currBuilder; - myPlayer->currBuilder = NULL; + delete myEngine->currBuilder; + myEngine->currBuilder = NULL; } - if (myPlayer->currEng) + if (myEngine->currEng) { - delete myPlayer->currEng; - myPlayer->currEng = NULL; + delete myEngine->currEng; + myEngine->currEng = NULL; } - if (myPlayer->currTune) + if (myEngine->currTune) { - delete myPlayer->currTune; - myPlayer->currTune = NULL; + delete myEngine->currTune; + myEngine->currTune = NULL; } xs_sidplay2_deletesid(myStatus); - g_free(myPlayer); - myStatus->player = NULL; + g_free(myEngine); + myStatus->sidEngine = NULL; } gboolean xs_sidplay2_initsong(t_xs_status *myStatus) { - t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; + t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - if (!myPlayer) return FALSE; + if (!myEngine) return FALSE; - if (!myPlayer->currTune->selectSong(myStatus->currSong)) + if (!myEngine->currTune->selectSong(myStatus->currSong)) { XSERR("ENGINE selectSong() failed\n"); return FALSE; } - if (myPlayer->currEng->load(myPlayer->currTune) < 0) + if (myEngine->currEng->load(myEngine->currTune) < 0) { XSERR("ENGINE load() failed\n"); return FALSE; @@ -197,38 +195,38 @@ guint xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize) { - t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; + t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - return myPlayer->currEng->play(audioBuffer, audioBufSize); + return myEngine->currEng->play(audioBuffer, audioBufSize); } gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFilename) { - t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; + t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; assert(myStatus); /* Try to get the tune */ if (!pcFilename) return FALSE; - if (!myPlayer->currTune->load(pcFilename)) return FALSE; + if (!myEngine->currTune->load(pcFilename)) return FALSE; /* Get current configuration */ - myPlayer->currConfig = myPlayer->currEng->config(); + myEngine->currConfig = myEngine->currEng->config(); /* Configure channels and stuff */ switch (myStatus->audioChannels) { case XS_CHN_AUTOPAN: - myPlayer->currConfig.playback = sid2_stereo; + myEngine->currConfig.playback = sid2_stereo; break; case XS_CHN_STEREO: - myPlayer->currConfig.playback = sid2_stereo; + myEngine->currConfig.playback = sid2_stereo; break; case XS_CHN_MONO: default: - myPlayer->currConfig.playback = sid2_mono; + myEngine->currConfig.playback = sid2_mono; break; } @@ -236,20 +234,20 @@ /* Memory mode settings */ switch (xs_cfg.memoryMode) { case XS_MPU_BANK_SWITCHING: - myPlayer->currConfig.environment = sid2_envBS; + myEngine->currConfig.environment = sid2_envBS; break; case XS_MPU_TRANSPARENT_ROM: - myPlayer->currConfig.environment = sid2_envTP; + myEngine->currConfig.environment = sid2_envTP; break; case XS_MPU_PLAYSID_ENVIRONMENT: - myPlayer->currConfig.environment = sid2_envPS; + myEngine->currConfig.environment = sid2_envPS; break; case XS_MPU_REAL: default: - myPlayer->currConfig.environment = sid2_envR; + myEngine->currConfig.environment = sid2_envR; break; } @@ -257,64 +255,64 @@ /* Clockspeed settings */ switch (xs_cfg.clockSpeed) { case XS_CLOCK_NTSC: - myPlayer->currConfig.clockSpeed = myPlayer->currConfig.clockDefault = SID2_CLOCK_NTSC; + myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault = SID2_CLOCK_NTSC; break; case XS_CLOCK_PAL: default: - myPlayer->currConfig.clockSpeed = myPlayer->currConfig.clockDefault = SID2_CLOCK_PAL; + myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault = SID2_CLOCK_PAL; break; } /* Configure rest of the emulation */ - myPlayer->currConfig.sidEmulation = myPlayer->currBuilder; - myPlayer->currConfig.clockForced = xs_cfg.forceSpeed; - myPlayer->currConfig.optimisation = (xs_cfg.sid2OptLevel) ? 1 : 0; - myPlayer->currConfig.sidDefault = myPlayer->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581; - myPlayer->currConfig.sidSamples = TRUE; // FIXME FIX ME, make configurable! - myPlayer->currConfig.precision = myStatus->audioBitsPerSample; - myPlayer->currConfig.frequency = myStatus->audioFrequency; + myEngine->currConfig.sidEmulation = myEngine->currBuilder; + myEngine->currConfig.clockForced = xs_cfg.forceSpeed; + myEngine->currConfig.optimisation = (xs_cfg.sid2OptLevel) ? 1 : 0; + myEngine->currConfig.sidDefault = myEngine->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581; + myEngine->currConfig.sidSamples = TRUE; // FIXME FIX ME, make configurable! + myEngine->currConfig.precision = myStatus->audioBitsPerSample; + myEngine->currConfig.frequency = myStatus->audioFrequency; switch (myStatus->audioBitsPerSample) { case XS_RES_8BIT: myStatus->audioFormat = FMT_U8; - myPlayer->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; + myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; break; case XS_RES_16BIT: switch (myStatus->audioFormat) { case FMT_U16_LE: - myPlayer->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; + myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; break; case FMT_U16_BE: - myPlayer->currConfig.sampleFormat = SID2_BIG_UNSIGNED; + myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; break; case FMT_U16_NE: myStatus->audioFormat = FMT_U16_NE; #ifdef WORDS_BIGENDIAN - myPlayer->currConfig.sampleFormat = SID2_BIG_UNSIGNED; + myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; #else - myPlayer->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; + myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; #endif break; case FMT_S16_LE: - myPlayer->currConfig.sampleFormat = SID2_LITTLE_SIGNED; + myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; break; case FMT_S16_BE: - myPlayer->currConfig.sampleFormat = SID2_BIG_SIGNED; + myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; break; default: myStatus->audioFormat = FMT_S16_NE; #ifdef WORDS_BIGENDIAN - myPlayer->currConfig.sampleFormat = SID2_BIG_SIGNED; + myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; #else - myPlayer->currConfig.sampleFormat = SID2_LITTLE_SIGNED; + myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; #endif break; @@ -324,7 +322,7 @@ /* Now set the emulator configuration */ - if (myPlayer->currEng->config(myPlayer->currConfig) < 0) + if (myEngine->currEng->config(myEngine->currConfig) < 0) { XSERR("Emulator engine configuration failed!\n"); return FALSE; @@ -348,8 +346,7 @@ /* * Return song information */ -#define TFUNCTION1 xs_sidplay2_filetitle -#define TFUNCTION2 xs_sidplay2_getsidinfo +#define TFUNCTION xs_sidplay2_getsidinfo #define TTUNEINFO SidTuneInfo #define TTUNE SidTune #include "xs_sidplay.h" diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_sidplay2.h --- a/src/xs_sidplay2.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_sidplay2.h Tue Dec 21 09:25:03 2004 +0000 @@ -3,6 +3,10 @@ #include "xmms-sid.h" +#ifdef __cplusplus +extern "C" { +#endif + gboolean xs_sidplay2_isourfile(gchar *); void xs_sidplay2_close(t_xs_status *); gboolean xs_sidplay2_init(t_xs_status *); @@ -10,6 +14,9 @@ guint xs_sidplay2_fillbuffer(t_xs_status *, gchar *, guint); gboolean xs_sidplay2_loadsid(t_xs_status *, gchar *); void xs_sidplay2_deletesid(t_xs_status *); -t_xs_tune* xs_sidplay2_getsidinfo(gchar *); +t_xs_tuneinfo* xs_sidplay2_getsidinfo(gchar *); +#ifdef __cplusplus +} +#endif #endif /* _XS_SIDPLAY2_H */ diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_stil.c --- a/src/xs_stil.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_stil.c Tue Dec 21 09:25:03 2004 +0000 @@ -21,6 +21,7 @@ */ #include "xs_stil.h" #include "xs_support.h" +#include "xs_config.h" #include #include #include @@ -383,24 +384,100 @@ } -/* Get from STIL database +/* + * These should be moved out of this module some day ... */ -t_xs_stil_node * xs_stildb_get(t_xs_stildb *db, gchar *hvscPath, gchar *pcFilename) +static t_xs_stildb *xs_stildb_db = NULL; +XS_MUTEX(xs_stildb_db); + +gint xs_stil_init(void) { + XS_MUTEX_LOCK(xs_cfg); + + if (!xs_cfg.stilDBPath) + { + XS_MUTEX_UNLOCK(xs_cfg); + return -1; + } + + XS_MUTEX_LOCK(xs_stildb_db); + + /* Check if already initialized */ + if (xs_stildb_db) xs_stildb_free(xs_stildb_db); + + /* Allocate database */ + xs_stildb_db = (t_xs_stildb *) g_malloc0(sizeof(t_xs_stildb)); + if (!xs_stildb_db) + { + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_stildb_db); + return -2; + } + + /* Read the database */ + if (xs_stildb_read(xs_stildb_db, xs_cfg.stilDBPath) != 0) + { + xs_stildb_free(xs_stildb_db); + xs_stildb_db = NULL; + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_stildb_db); + return -3; + } + + /* Create index */ + if (xs_stildb_index(xs_stildb_db) != 0) + { + xs_stildb_free(xs_stildb_db); + xs_stildb_db = NULL; + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_stildb_db); + return -4; + } + + XS_MUTEX_UNLOCK(xs_cfg); + XS_MUTEX_UNLOCK(xs_stildb_db); + return 0; +} + + +void xs_stil_close(void) +{ + XS_MUTEX_LOCK(xs_stildb_db); + xs_stildb_free(xs_stildb_db); + xs_stildb_db = NULL; + XS_MUTEX_UNLOCK(xs_stildb_db); +} + + +t_xs_stil_node * xs_stil_get(gchar *pcFilename) +{ + t_xs_stil_node *pResult; gchar *tmpFilename; - /* Remove postfixed directory separator from HVSC-path */ - tmpFilename = xs_strrchr(hvscPath, '/'); - if (tmpFilename && (tmpFilename[1] == 0)) - tmpFilename[0] = 0; + XS_MUTEX_LOCK(xs_stildb_db); + XS_MUTEX_LOCK(xs_cfg); + + if (xs_cfg.hvscPath) + { + /* Remove postfixed directory separator from HVSC-path */ + tmpFilename = xs_strrchr(xs_cfg.hvscPath, '/'); + if (tmpFilename && (tmpFilename[1] == 0)) + tmpFilename[0] = 0; - /* Remove HVSC location-prefix from filename */ - tmpFilename = strstr(pcFilename, hvscPath); - if (tmpFilename) - tmpFilename += strlen(hvscPath); - else - tmpFilename = pcFilename; + /* Remove HVSC location-prefix from filename */ + tmpFilename = strstr(pcFilename, xs_cfg.hvscPath); + if (tmpFilename) + tmpFilename += strlen(xs_cfg.hvscPath); + else + tmpFilename = pcFilename; + } else + tmpFilename = pcFilename; + + pResult = xs_stildb_get_node(xs_stildb_db, tmpFilename); - return xs_stildb_get_node(db, pcFilename); + XS_MUTEX_UNLOCK(xs_stildb_db); + XS_MUTEX_UNLOCK(xs_cfg); + + return pResult; } diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_stil.h --- a/src/xs_stil.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_stil.h Tue Dec 21 09:25:03 2004 +0000 @@ -39,6 +39,10 @@ t_xs_stil_node * xs_stildb_get(t_xs_stildb *, gchar *, gchar *); +gint xs_stil_init(void); +void xs_stil_close(void); +t_xs_stil_node * xs_stil_get(gchar *); + #ifdef __cplusplus } #endif diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_support.c --- a/src/xs_support.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_support.c Tue Dec 21 09:25:03 2004 +0000 @@ -93,7 +93,7 @@ /* Concatenates a given string into string pointed by *ppResult. */ -gint th_pstrcat(gchar **ppResult, const gchar *pStr) +gint xs_pstrcat(gchar **ppResult, const gchar *pStr) { /* Check the string pointers */ if (!ppResult || !pStr) return -1; diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_title.c --- a/src/xs_title.c Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_title.c Tue Dec 21 09:25:03 2004 +0000 @@ -45,8 +45,8 @@ gchar *xs_make_titlestring(gchar *pcFilename, gint iSubTune, gint iSidModel, - gchar *formatString, gchar *infoString0, - gchar *infoString1, gchar *infoString2) + const gchar *formatString, const gchar *infoString0, + const gchar *infoString1, const gchar *infoString2) { gchar *tmpFilename, *tmpFilePath, *tmpFileExt, *pcStr, *pcResult, tmpStr[VBUFSIZE], tmpBuf[VBUFSIZE]; diff -r 7bb9e20e3092 -r 608f31f6c095 src/xs_title.h --- a/src/xs_title.h Sun Dec 19 16:57:01 2004 +0000 +++ b/src/xs_title.h Tue Dec 21 09:25:03 2004 +0000 @@ -10,7 +10,7 @@ /* * Functions */ -gchar *xs_make_titlestring(gchar *, gint, gint, gchar *, gchar *, gchar *, gchar *); +gchar *xs_make_titlestring(gchar *, gint, gint, const gchar *, const gchar *, const gchar *, const gchar *); #ifdef __cplusplus }