diff src/xmms-sid.c @ 87:94497283affa

Various fixes and improvements
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 05 Oct 2003 10:38:03 +0000
parents b6966a2447bc
children f9063960f04e
line wrap: on
line diff
--- a/src/xmms-sid.c	Sat Oct 04 08:21:01 2003 +0000
+++ b/src/xmms-sid.c	Sun Oct 05 10:38:03 2003 +0000
@@ -44,8 +44,14 @@
 #ifdef HAVE_SIDPLAY2
 #include "xs_sidplay2.h"
 #endif
+#ifdef HAVE_NANOSID
+#include "xs_nanosid.h"
+#endif
 
 
+/*
+ * Structure defining methods/functions of each player
+ */
 typedef struct {
 	gint		plrIdent;
 	gboolean	(*plrIsOurFile)(gchar *);
@@ -54,20 +60,22 @@
 	gboolean	(*plrInitSong)(t_xs_status *);
 	gboolean	(*plrFillBuffer)(t_xs_status *, gchar *, gint);
 	gboolean	(*plrLoadSID)(t_xs_status *, gchar *);
-	gint		(*plrGetTuneSpeed)(t_xs_status *);
 	void		(*plrDeleteSID)(t_xs_status *);
-	void		(*plrGetSIDInfo)(gchar *, gchar **, gint *);
+	t_xs_tune*	(*plrGetSIDInfo)(gchar *);
 } t_xs_player;
 
 
+/*
+ * List of players and links to their functions
+ */
 t_xs_player xs_playerlist[] = {
 #ifdef HAVE_SIDPLAY1
 	{ XS_ENG_SIDPLAY1,
 		xs_sidplay1_isourfile,
 		xs_sidplay1_init, xs_sidplay1_close,
 		xs_sidplay1_initsong, xs_sidplay1_fillbuffer,
-		xs_sidplay1_loadsid, xs_sidplay1_gettunespeed,
-		xs_sidplay1_deletesid, xs_sidplay1_getsidinfo
+		xs_sidplay1_loadsid, xs_sidplay1_deletesid,
+		xs_sidplay1_getsidinfo
 	},
 #endif
 #ifdef HAVE_SIDPLAY2
@@ -75,8 +83,8 @@
 		xs_sidplay2_isourfile,
 		xs_sidplay2_init, xs_sidplay2_close,
 		xs_sidplay2_initsong, xs_sidplay2_fillbuffer,
-		xs_sidplay2_loadsid, xs_sidplay2_gettunespeed,
-		xs_sidplay2_deletesid, xs_sidplay2_getsidinfo
+		xs_sidplay2_loadsid, xs_sidplay2_deletesid,
+		xs_sidplay2_getsidinfo
 	},
 #endif
 #ifdef HAVE_NANOSID
@@ -84,8 +92,8 @@
 		xs_nanosid_isourfile,
 		xs_nanosid_init, xs_nanosid_close,
 		xs_nanosid_initsong, xs_nanosid_fillbuffer,
-		xs_nanosid_loadsid, xs_nanosid_gettunespeed,
-		xs_nanosid_deletesid, xs_nanosid_getsidinfo
+		xs_nanosid_loadsid, xs_nanosid_deletesid,
+		xs_nanosid_getsidinfo
 	},
 #endif
 };
@@ -120,10 +128,9 @@
 
  /* Initialize status */
  memset(&xs_status, 0, sizeof(xs_status));
- xs_status.allowNext = TRUE;
 
  /* Try to initialize emulator engine */
- XSDEBUG("initializing emulator engine...\n");
+ XSDEBUG("initializing emulator engine #%i...\n", xs_cfg.playerEngine);
 
  iPlayer = 0;
  isInitialized = FALSE;
@@ -137,9 +144,10 @@
  			xs_player = (t_xs_player *) &xs_playerlist[iPlayer];
  			}
  		}
- 	iPlayer++;
+	iPlayer++;
  	}
 
+ XSDEBUG("init#1: %s, %i\n", (isInitialized) ? "OK" : "FAILED", iPlayer);
 
  iPlayer = 0;
  while ((iPlayer < xs_nplayerlist) && !isInitialized)
@@ -148,10 +156,11 @@
 		{
 		isInitialized = TRUE;
 		xs_player = (t_xs_player *) &xs_playerlist[iPlayer];
- 		}
-	iPlayer++;
+ 		} else
+ 		iPlayer++;
  	}
  
+ XSDEBUG("init#2: %s, %i\n", (isInitialized) ? "OK" : "FAILED", iPlayer);
 
  /* Read song-length database */
  if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0))
@@ -174,9 +183,12 @@
 {
  XSDEBUG("xs_close(): shutting down...\n");
 
- /* Stop playing */
+ /* Stop playing, free structures */
  xs_stop();
 
+ xs_tune_free(xs_status.pTune);
+ xs_status.pTune = NULL;
+ 
  xs_player->plrDeleteSID(&xs_status);
  xs_player->plrClose(&xs_status);
 
@@ -184,6 +196,7 @@
  xs_songlen_close();
 
 // FIXME FIXME: STIL-entries
+
  XSDEBUG("shutdown finished.\n");
 }
 
@@ -191,21 +204,21 @@
 /*
  * Check whether the given file is handled by this plugin
  */
-gint xs_is_our_file(gchar *pcFileName)
+gint xs_is_our_file(gchar *pcFilename)
 {
  char *pcExt;
  assert(xs_player);
 
  /* Check the filename */
- if (pcFileName == NULL)
+ 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_player->plrIsOurFile(pcFilename))
  	return TRUE;
 
  /* Detect just by checking filename extension */
- pcExt = strrchr(pcFileName, '.');
+ pcExt = strrchr(pcFilename, '.');
  if (pcExt)
 	{
 	pcExt++;
@@ -235,15 +248,16 @@
 void *xs_play_loop(void *argPointer)
 {
  t_xs_status myStatus;
+ t_xs_tune *myTune;
  gboolean audioOpen, doPlay;
- gint audioFreq, audioChannels, songLength, audioFmt;
+ gint mySong, audioFreq, audioChannels, songLength, audioFmt;
  gchar audioBuffer[XS_BUFSIZE];
 
  /* Initialize */
  pthread_mutex_lock(&xs_mutex);
  XSDEBUG("entering play thread\n");
- xs_status.isPlaying = TRUE;
  memcpy(&myStatus, &xs_status, sizeof(t_xs_status));
+ myTune = xs_status.pTune;
  pthread_mutex_unlock(&xs_mutex);
 
  /* Copy and check audio options here (they might change in config while running) */
@@ -263,30 +277,27 @@
  while (xs_status.isPlaying && doPlay)
  {
  pthread_mutex_lock(&xs_mutex);
- myStatus.currSong = xs_status.currSong;
- myStatus.isPlaying = TRUE;
- xs_status.allowNext = TRUE;
+ mySong = xs_status.currSong;
+ songLength = myTune->subTunes[mySong - 1].tuneLength;
  pthread_mutex_unlock(&xs_mutex);
 
- XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong);
+ XSDEBUG("subtune #%i selected, initializing...\n", mySong);
 
 
  /* Initialize song */
  if (!xs_player->plrInitSong(&myStatus))
 	{
 	XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n",
-		myStatus.currFileName, myStatus.currSong);
+		myTune->tuneFilename, mySong);
 	goto err_exit;
 	}
 
 
  /* Get song information for current subtune */
- songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong);
-
  xs_plugin_ip.set_info(
- 	myStatus.currFileName,
+ 	myTune->subTunes[mySong - 1].tuneTitle,
  	(songLength > 0) ? (songLength * 1000) : -1,
- 	1000 * xs_player->plrGetTuneSpeed(&xs_status),
+ 	(myTune->subTunes[mySong - 1].tuneSpeed > 0) ? (myTune->subTunes[mySong - 1].tuneSpeed * 1000) : -1,
 	audioFreq,
 	audioChannels);
 
@@ -306,7 +317,7 @@
  /*
   * Play the subtune
   */
- while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == myStatus.currSong))
+ while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == mySong))
 	{
 	/* Render audio data */
 	xs_player->plrFillBuffer(&myStatus, audioBuffer, XS_BUFSIZE);
@@ -318,12 +329,12 @@
 
 	/* Wait a little */
 	while (xs_status.isPlaying &&
-		(xs_status.currSong == myStatus.currSong) &&
+		(xs_status.currSong == mySong) &&
 		(xs_plugin_ip.output->buffer_free() < XS_BUFSIZE))
 		xmms_usleep(10000);
 
 	/* Output audio */
-	if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong))
+	if (xs_status.isPlaying && (xs_status.currSong == mySong))
 		xs_plugin_ip.output->write_audio(audioBuffer, XS_BUFSIZE);
 
 	/* Check if we have played enough */
@@ -373,16 +384,7 @@
  XSDEBUG("exiting thread, bye.\n");
 
  pthread_mutex_lock(&xs_mutex);
- xs_player->plrDeleteSID(&myStatus);
-
- if (xs_status.currFileName)
- 	{
-	g_free(xs_status.currFileName);
-	xs_status.currFileName = NULL;
-	}
-                                 
  xs_status.isPlaying = FALSE;
- xs_status.allowNext = TRUE;
  pthread_mutex_unlock(&xs_mutex);
  pthread_exit(NULL);
 }
@@ -391,30 +393,37 @@
 /*
  * Start playing the given file
  */
-void xs_play_file(gchar *pcFileName)
+void xs_play_file(gchar *pcFilename)
 {
- while (!xs_status.allowNext) usleep(5000);
+ XSDEBUG("play '%s'\n", pcFilename);
  
- pthread_mutex_lock(&xs_mutex);
- xs_status.allowNext = FALSE;
- pthread_mutex_unlock(&xs_mutex);
-
- fprintf(stderr, "\n\n");
- XSDEBUG("play '%s'\n", pcFileName);
- 
- /* Initialize the tune */
- if (!xs_player->plrLoadSID(&xs_status, pcFileName))
+ /* Get tune information */
+ if ((xs_status.pTune = xs_player->plrGetSIDInfo(pcFilename)) == NULL)
  	return;
 
+ XSDEBUG("tuneinfo %p\n", xs_status.pTune);
+
+ /* Initialize the tune */
+ if (!xs_player->plrLoadSID(&xs_status, pcFilename))
+ 	{
+ 	xs_tune_free(xs_status.pTune);
+ 	xs_status.pTune = NULL;
+ 	return;
+ 	}
+
+ XSDEBUG("load ok\n");
+ 
  /* Set general status information */
- xs_status.isPlaying	= FALSE;
+ xs_status.isPlaying	= TRUE;
  xs_status.isError	= FALSE;
- xs_status.currFileName	= g_strdup(pcFileName);
+ xs_status.currSong	= xs_status.pTune->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);
 	}
 
@@ -427,11 +436,10 @@
  */
 void xs_stop(void)
 {
- /* If playing, stop. */
  XSDEBUG("STOP_REQ\n");
-
  if (xs_status.isPlaying)
 	{
+	/* Stop playing */
 	XSDEBUG("stopping...\n");
 	pthread_mutex_lock(&xs_mutex);
 	xs_status.isPlaying = FALSE;
@@ -439,11 +447,15 @@
 	pthread_join(xs_decode_thread, NULL);
 	}
 
+ /* Free tune information */
+ xs_player->plrDeleteSID(&xs_status);
+ xs_tune_free(xs_status.pTune);
+ xs_status.pTune = NULL;
 }
 
 
 /*
- * Pause the playing
+ * Pause/unpause the playing
  */
 void xs_pause(short pauseState)
 {
@@ -457,10 +469,12 @@
  */
 void xs_seek(gint iTime)
 {
+ if (!xs_status.pTune) return;
+
  if (xs_cfg.subsongControl == XS_SSC_POPUP)
- {
- /* User wants to use the pop-up */
- }
+	{
+	/* User wants to use the pop-up */
+	}
 
  /* If we have song-position patch, check settings */
 #ifdef HAVE_SONG_POSITION
@@ -468,9 +482,9 @@
  	{
 	pthread_mutex_lock(&xs_mutex);
 
-	if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying)
+	if ((iTime > 0) && (iTime <= xs_status.pTune->nsubTunes) && xs_status.isPlaying)
 		xs_status.currSong = iTime;
-
+	
 	pthread_mutex_unlock(&xs_mutex);
 	}
 #endif
@@ -486,6 +500,10 @@
  if (xs_status.isError)
 	return -2;
 
+ /* If there is no tune, return -1 */
+ if (!xs_status.pTune)
+ 	return -1;
+ 
  /* If tune has ended, return -1 */
  if (!xs_status.isPlaying)
 	return -1;
@@ -495,7 +513,7 @@
  if (xs_cfg.subsongControl == XS_SSC_PATCH)
  	{
 	pthread_mutex_lock(&xs_mutex);
-	set_song_position(xs_status.currSong, 1, xs_status.nSongs);
+	set_song_position(xs_status.currSong, 1, xs_status.pTune->nsubTunes);
 	pthread_mutex_unlock(&xs_mutex);
 	}
 #endif
@@ -508,7 +526,77 @@
 /*
  * Return song information
  */
-void xs_get_song_info(gchar *songFileName, gchar **songTitle, gint *songLength)
+void xs_get_song_info(gchar *songFilename, gchar **songTitle, gint *songLength)
+{
+ t_xs_tune *pInfo;
+ gint tmpInt;
+ 
+ pInfo = xs_player->plrGetSIDInfo(songFilename);
+ if (!pInfo) return;
+
+ if ((pInfo->startTune >= 0) && (pInfo->startTune <= pInfo->nsubTunes))
+ 	{
+	(*songTitle) = g_strdup(pInfo->subTunes[pInfo->startTune - 1].tuneTitle);
+
+	tmpInt = pInfo->subTunes[pInfo->startTune - 1].tuneLength;
+	if (tmpInt < 0)
+		(*songLength) = -1;
+		else
+		(*songLength) = (tmpInt * 1000);
+	}
+	
+ xs_tune_free(pInfo);
+}
+
+
+/*
+ * Allocate a new tune structure
+ */
+t_xs_tune *xs_tune_new(gchar *pcFilename, gint nsubTunes, gint startTune)
 {
- xs_player->plrGetSIDInfo(songFileName, songTitle, songLength);
+ t_xs_tune *pResult;
+ 
+ pResult = (t_xs_tune *) g_malloc0(sizeof(t_xs_tune));
+ if (!pResult) return NULL;
+ 
+ pResult->tuneFilename = g_strdup(pcFilename);
+ if (!pResult->tuneFilename)
+ 	{
+ 	g_free(pResult);
+ 	return NULL;
+ 	}
+ 
+ pResult->nsubTunes = nsubTunes;
+ pResult->startTune = startTune;
+ 
+ return pResult;
 }
+
+
+/*
+ * Free tune information
+ */
+void xs_tune_free(t_xs_tune *pTune)
+{
+ gint i;
+ if (!pTune) return;
+
+ if (pTune->tuneFilename)
+ 	{
+ 	g_free(pTune->tuneFilename);
+ 	pTune->tuneFilename = NULL;
+ 	}
+ 
+ for (i = 0; i < pTune->nsubTunes; i++)
+ 	{
+ 	if (pTune->subTunes[i].tuneTitle)
+ 		{
+ 		g_free(pTune->subTunes[i].tuneTitle);
+ 		pTune->subTunes[i].tuneTitle = NULL;
+ 		}
+ 	}
+ 
+ g_free(pTune);
+}
+
+