Mercurial > hg > xmms-sid
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); +} + +