Mercurial > hg > xmms-sid
diff src/xmms-sid.cc @ 40:1788f4ce6a44
Numerous changes towards 0.8
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 19 Jun 2003 22:38:01 +0000 |
parents | 15250dd0c326 |
children | 0f00ebab063d |
line wrap: on
line diff
--- a/src/xmms-sid.cc Thu Jun 19 20:49:01 2003 +0000 +++ b/src/xmms-sid.cc Thu Jun 19 22:38:01 2003 +0000 @@ -19,7 +19,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +extern "C" { #include <pthread.h> #include <stdlib.h> #include <string.h> @@ -27,30 +27,44 @@ #include <errno.h> #include <xmms/plugin.h> #include <xmms/util.h> +#include <xmms/titlestring.h> #include "xmms-sid.h" +#include "xs_support.h" #include "xs_config.h" #include "xs_length.h" -#include "xs_title.h" +} -extern "C++" { +#ifdef HAVE_SIDPLAY1 #include <sidplay/player.h> #include <sidplay/myendian.h> #include <sidplay/fformat.h> -} +#endif + +#ifdef HAVE_SIDPLAY2 +#include <sidplay/sidplay2.h> +#endif /* * Global variables */ +#ifdef HAVE_SIDPLAY1 static struct emuConfig xs_emuConf; static emuEngine xs_emuEngine; +typedef sidTune t_xs_tune; +#endif + +#ifdef HAVE_SIDPLAY2 +#endif + static pthread_t xs_decode_thread; struct t_xs_cfg xs_cfg; struct { - int s_error, s_playing, s_songs, s_allownext; - sidTune *s_tune; - gchar *s_fname; + gboolean isError, isPlaying, allowNext; + gint currSong, nSongs; + t_xs_tune *currTune; + gchar *currFilename; } xs_status; pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -66,29 +80,31 @@ /* Initialize and get configuration */ memset(&xs_cfg, 0, sizeof(xs_cfg)); - xs_get_configure(); + xs_read_configuration(); - xs_status.s_error = 0; - xs_status.s_playing = 0; - xs_status.s_songs = 0; - xs_status.s_allownext = 1; // Initialize to TRUE to allow first song - xs_status.s_tune = NULL; - xs_status.s_fname = NULL; + xs_status.isError = FALSE; + xs_status.isPlaying = FALSE; + xs_status.nSongs = 0; + xs_status.currSong = 0; + xs_status.allowNext = TRUE; // Initialize to TRUE to allow first song + xs_status.currTune = NULL; + xs_status.currFilename = NULL; - /* Try to initialize libSIDPlay */ - if (!xs_emuEngine) + + /* Try to initialize libSIDPlay(s) */ +#ifdef HAVE_SIDPLAY1 + if (!xs_emuEngine || !xs_emuEngine.verifyEndianess()) { - XSERR("Couldn't start SIDPlay emulator engine!\n"); + XSERR("Couldn't start SIDPlay1 emulator engine!\n"); return; } +#endif - if (!xs_emuEngine.verifyEndianess()) - { - XSERR("Wrong hardware endianess (SIDPlay error)!\n"); - return; - } +#ifdef HAVE_SIDPLAY2 +#endif /* Read song-length database */ + if (xs_cfg.songlenDBEnable) if (xs_songlen_init() < 0) { XSERR("Error initializing song-length database!\n"); @@ -112,6 +128,13 @@ /* Stop playing */ xs_plugin_ip.stop(); + /* Shutdown libSIDPlay(s) */ +#ifdef HAVE_SIDPLAY1 +#endif + +#ifdef HAVE_SIDPLAY2 +#endif + /* Close sub-song control window */ /* Free allocated memory */ @@ -135,8 +158,8 @@ /* Try to detect via libSIDPlay's detection routine, if required */ if (xs_cfg.detectMagic) { - sidTune *testTune = new sidTune(fileName); - +#ifdef HAVE_SIDPLAY1 + t_xs_tune *testTune = new sidTune(fileName); if (!testTune) return FALSE; if (!testTune->getStatus()) { @@ -146,9 +169,11 @@ delete testTune; return TRUE; +#endif +#ifdef HAVE_SIDPLAY2 +#endif } - /* Detect just by checking filename extension */ pcExt = strrchr(fileName, '.'); if (pcExt) @@ -170,152 +195,15 @@ */ static void *xs_play_loop(void *argPointer) { - guchar plr_data[XS_BUFSIZE]; - struct sidTuneInfo plr_sidInf; - gchar *plr_tune_title = NULL; - gint plr_fxlen; - enum AFormat plr_fmt; - gint plr_tune_num; - gint32 plr_tune_len; - - /* Don't allow next song to be set yet */ pthread_mutex_lock(&xs_mutex); - xs_status.s_allownext = 0; + xs_status.allowNext = FALSE; pthread_mutex_unlock(&xs_mutex); - /* Check tune number */ - plr_tune_num = xs_status.s_playing; - if (plr_tune_num <= 0) - plr_tune_num = 1; - -XSDEBUG("xs_play_loop(%d, %d)\n", plr_tune_num, xs_status.s_playing); - - /* Get song information */ - xs_status.s_tune->getInfo(plr_sidInf); - plr_tune_len = xs_songlen_get(xs_status.s_fname, plr_tune_num); - plr_tune_title = xs_filetitle_get(&plr_sidInf, plr_tune_num); - -XSDEBUG("title='%s', len=%d\n", plr_tune_title, plr_tune_len); - - - /* Initialize audio output */ - // FIXME FIXME: FMT_S16_XXX -- different architechtures?? - // the patch may break something ... - plr_fmt = (xs_emuConf.bitsPerSample == 16) ? FMT_S16_NE : FMT_U8; - - - if (!xs_plugin_ip.output->open_audio(plr_fmt, xs_emuConf.frequency, xs_emuConf.channels)) - { - pthread_mutex_lock(&xs_mutex); - xs_status.s_error = 1; - if (plr_tune_title) g_free(plr_tune_title); - if (xs_status.s_tune) delete xs_status.s_tune; - xs_status.s_allownext = 1; - pthread_mutex_unlock(&xs_mutex); - return NULL; - } - - - /* Initialize the SIDPlay-emulator for song */ - if (!sidEmuInitializeSong(xs_emuEngine, *xs_status.s_tune, plr_tune_num)) - { - XSERR("Couldn't initialize SIDPlay emulator engine! This may be a problem with your sound settings, or possibly a bug in XMMS-SID.\n"); - pthread_mutex_lock(&xs_mutex); - xs_status.s_error = 1; - pthread_mutex_unlock(&xs_mutex); - goto pl_cleanup; - } - - - /* Set song title information */ - xs_plugin_ip.set_info( - plr_tune_title, - (plr_tune_len * 1000), - (1000 * (plr_sidInf.songSpeed ? plr_sidInf.songSpeed : (plr_sidInf.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50)), - xs_emuConf.frequency, - xs_emuConf.channels); - - - /* Run playing loop: loop as long as xs_playing is same as current tune number */ - while (xs_status.s_playing == plr_tune_num) - { - plr_fxlen = XS_BUFSIZE; - - /* Run emulator to fill output buffer with audio data */ - sidEmuFillBuffer(xs_emuEngine, *xs_status.s_tune, plr_data, plr_fxlen); - - /* If Max Playtime option set, check playtime */ - if (xs_cfg.playUseMaxTime) - { - if ((xs_plugin_ip.output->output_time() / 1000) >= xs_cfg.playMaxTime) - { - pthread_mutex_lock(&xs_mutex); - xs_status.s_playing = 0; - pthread_mutex_unlock(&xs_mutex); - } - } - - /* Check playtime against database */ - if (xs_cfg.playMethod == XMMS_SID_PMETHOD_DATABASE) - { - if ((xs_plugin_ip.output->output_time() / 1000) >= plr_tune_len) - { - pthread_mutex_lock(&xs_mutex); - xs_status.s_playing = 0; - pthread_mutex_unlock(&xs_mutex); - } - - } -#if 0 - else - - /* Check for silence */ - if (xs_cfg.playMethod == XMMS_SID_PMETHOD_MAXSILENCE) - { - } - - /* Add static noise */ - - /* Muffle waveform (low-pass filter) */ - -#endif - - - /* Send audio data to visualization plugin */ - xs_plugin_ip.add_vis_pcm(xs_plugin_ip.output->written_time(), - plr_fmt, xs_emuConf.channels, plr_fxlen, plr_data); - - /* Wait for a while */ - while ((xs_status.s_playing == plr_tune_num) && (xs_plugin_ip.output->buffer_free() < plr_fxlen)) - xmms_usleep(10000); - - - /* If playing, send final audio data to output plugin */ - if (xs_status.s_playing == plr_tune_num) - xs_plugin_ip.output->write_audio(plr_data, plr_fxlen); - - } /* End of playerloop */ - - -pl_cleanup: - XSDEBUG("cleaning up...\n"); - - /* Cleanup & shutdown */ - xs_plugin_ip.output->close_audio(); - - if (plr_tune_title) g_free(plr_tune_title); - - pthread_mutex_lock(&xs_mutex); - xs_status.s_playing = 0; - if (xs_status.s_tune) delete xs_status.s_tune; - xs_status.s_allownext = 1; - pthread_mutex_unlock(&xs_mutex); - - XSDEBUG("exiting thread, bye.\n"); - return NULL; + XSDEBUG("exiting thread, bye.\n"); + return NULL; } @@ -324,20 +212,29 @@ */ void xs_play_file(char *fileName) { - sidTune *newTune; + t_xs_tune *newTune; struct sidTuneInfo sidInf; - XSDEBUG("request to start '%s'\n", fileName); + XSDEBUG("request to load '%s'\n", fileName); + - /* Wait until the previous song has finished for sure */ - if (!xs_status.s_allownext) - pthread_join(xs_decode_thread, NULL); + /* Initialize audio output */ + XSDEBUG("opening audio output plugin...\n"); + if (!xs_plugin_ip.output->open_audio( + ((xs_cfg.fmtBitsPerSample == 16) ? FMT_S16_NE : FMT_U8), xs_cfg.fmtFrequency, + ((xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2))) + { + XSERR("Couldn't open audio output plugin!\n"); + delete newTune; + return; + } + /* Try to get the tune */ newTune = new sidTune(fileName); if (newTune == NULL) return; - XSDEBUG("tune ok, status %i\n", xs_status.s_playing); + XSDEBUG("tune ok, configuring SIDPlay engine\n"); /* Get current configuration */ @@ -347,19 +244,19 @@ /* Configure channels and stuff */ switch (xs_cfg.fmtChannels) { - case XMMS_SID_CHN_AUTOPAN: + case XS_CHN_AUTOPAN: xs_emuConf.channels = SIDEMU_STEREO; xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; xs_emuConf.volumeControl = SIDEMU_FULLPANNING; break; - case XMMS_SID_CHN_STEREO: + case XS_CHN_STEREO: xs_emuConf.channels = SIDEMU_STEREO; xs_emuConf.autoPanning = SIDEMU_NONE; xs_emuConf.volumeControl = SIDEMU_NONE; break; - case XMMS_SID_CHN_MONO: + case XS_CHN_MONO: xs_emuConf.channels = SIDEMU_MONO; xs_emuConf.autoPanning = SIDEMU_NONE; xs_emuConf.volumeControl = SIDEMU_NONE; @@ -374,15 +271,15 @@ /* Memory mode settings */ switch (xs_cfg.memoryMode) { - case XMMS_SID_MPU_BANK_SWITCHING: + case XS_MPU_BANK_SWITCHING: xs_emuConf.memoryMode = MPU_BANK_SWITCHING; break; - case XMMS_SID_MPU_TRANSPARENT_ROM: + case XS_MPU_TRANSPARENT_ROM: xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM; break; - case XMMS_SID_MPU_PLAYSID_ENVIRONMENT: + case XS_MPU_PLAYSID_ENVIRONMENT: xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; break; @@ -395,11 +292,11 @@ /* Clockspeed settings */ switch (xs_cfg.clockSpeed) { - case XMMS_SID_CLOCK_PAL: + case XS_CLOCK_PAL: xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL; break; - case XMMS_SID_CLOCK_NTSC: + case XS_CLOCK_NTSC: xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC; break; @@ -415,7 +312,7 @@ xs_emuConf.frequency = xs_cfg.fmtFrequency; xs_emuConf.sampleFormat = SIDEMU_SIGNED_PCM; xs_emuConf.mos8580 = xs_cfg.mos8580; - xs_emuConf.emulateFilter = xs_cfg.emulateFilter; + xs_emuConf.emulateFilter = xs_cfg.emulateFilters; xs_emuConf.filterFs = xs_cfg.filterFs; xs_emuConf.filterFm = xs_cfg.filterFm; xs_emuConf.filterFt = xs_cfg.filterFt; @@ -429,14 +326,15 @@ /* Initialize status information */ - XSDEBUG("starting thread!\n"); + XSDEBUG("initializing and starting playing thread!\n"); - pthread_mutex_lock(&xs_mutex); - xs_status.s_error = 0; - xs_status.s_playing = sidInf.startSong; - xs_status.s_songs = sidInf.songs; - xs_status.s_tune = newTune; - pthread_mutex_unlock(&xs_mutex); + xs_status.isError = FALSE; + xs_status.isPlaying = TRUE; + xs_status.allowNext = TRUE; + xs_status.currSong = sidInf.startSong; + xs_status.nSongs = sidInf.songs; + xs_status.currTune = newTune; + /* Start the playing thread! */ if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0) @@ -455,13 +353,18 @@ void xs_stop(void) { /* If playing, stop. */ - if (xs_status.s_playing) + XSDEBUG("request to stop.\n"); + + if (xs_status.isPlaying) { + XSDEBUG("stopping...\n"); pthread_mutex_lock(&xs_mutex); - xs_status.s_playing = 0; + xs_status.isPlaying = 0; pthread_mutex_unlock(&xs_mutex); pthread_join(xs_decode_thread, NULL); + + xs_plugin_ip.output->close_audio(); } } @@ -482,12 +385,14 @@ void xs_seek(int iTime) { #ifdef HAVE_SONG_POSITION - if ((iTime > 0) && (iTime <= xs_songs)) + pthread_mutex_lock(&xs_mutex); + + if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying) { - pthread_mutex_lock(&xs_mutex); - xs_status.s_playing = iTime; - pthread_mutex_unlock(&xs_mutex); + xs_status.currSong = iTime; } + + pthread_mutex_unlock(&xs_mutex); #endif } @@ -497,16 +402,19 @@ */ int xs_get_time(void) { - if (xs_status.s_error) + pthread_mutex_lock(&xs_mutex); + if (xs_status.isError) return -2; - if (!xs_status.s_playing) + if (!xs_status.isPlaying) return -1; #ifdef HAVE_SONG_POSITION - set_song_position(xs_status.s_playing, 1, xs_status.s_songs); + set_song_position(xs_status.currSong, 1, xs_status.nSongs); #endif + pthread_mutex_unlock(&xs_mutex); + return xs_plugin_ip.output->output_time(); } @@ -517,7 +425,7 @@ void xs_get_song_info(char *songFilename, char **songTitle, int *songLength) { struct sidTuneInfo sidInf; - sidTune *testTune = new sidTune(songFilename); + t_xs_tune *testTune = new sidTune(songFilename); /* Check if the tune exists and is readable */ if (!testTune) return; @@ -532,9 +440,108 @@ delete testTune; /* Get titlestring */ - *songTitle = xs_filetitle_get(&sidInf, sidInf.startSong); + *songTitle = NULL; - /* Get song length (in seconds), negative if no known length */ - *songLength = xs_songlen_get(songFilename, sidInf.startSong); + /* Get song length (in milliseconds), negative if no known length */ + *songLength = xs_songlen_get(songFilename, sidInf.startSong) * 1000; } + +/* + * Create the SID-tune description string from the tune's information + * formatted by the user-specified format-string. + */ +gchar *xs_filetitle_get(gchar *pcFilename, void *pfInfo, gint iSubTune) +{ + gint i, j, iLength; + gchar *pcResult; + struct sidTuneInfo *finfo = (struct sidTuneInfo *) pfInfo; +#ifdef HAVE_XMMSEXTRA + TitleInput *ptInput; +#endif + + // FIXME FIXME: get STIL-info + + +#ifdef HAVE_XMMSEXTRA + /* Check if the titles are overridden or not */ + if (!xs_cfg.titleOverride) + { + /* Use generic XMMS titles */ + /* XMMS_NEW_TITLEINPUT(ptInput); + * We duplicate and add typecast to the code here due to XMMS's braindead headers + */ + ptInput = (TitleInput *) g_malloc0(sizeof(TitleInput)); + ptInput->__size = XMMS_TITLEINPUT_SIZE; + ptInput->__version = XMMS_TITLEINPUT_VERSION; + + /* Create the input fields */ + ptInput->file_name = pcFilename; + ptInput->file_ext = pcFilename; + ptInput->file_path = pcFilename; + + ptInput->track_name = finfo->nameString; + ptInput->track_number = iSubTune; + ptInput->album_name = NULL; + ptInput->performer = finfo->authorString; + xs_strcalloc(&ptInput->date, ""); + ptInput->year = 0; + xs_strcalloc(&ptInput->genre, "SID-tune"); + ptInput->comment = finfo->copyrightString; + + /* Create the string */ + pcResult = xmms_get_titlestring(xmms_get_gentitle_format(), ptInput); + + /* Dispose all allocated memory */ + g_free(ptInput->date); + g_free(ptInput->genre); + g_free(ptInput); + } else { +#endif + /* Check the info strings */ + if (finfo->numberOfInfoStrings != 3) + { + if (finfo->numberOfInfoStrings < 1) + return 0; + + return g_strdup(finfo->infoString[0]); + } + + /* Check the format-string for NULL */ + if (xs_cfg.titleFormat == NULL) + return g_strdup_printf("%s - %s", finfo->nameString, finfo->authorString); + + /* Construct the final result info */ + for (j = i = 0; i < strlen(xs_cfg.titleFormat); i++) + { + if (xs_cfg.titleFormat[i] == '%') + { + switch (xs_cfg.titleFormat[++i]) { + case '1': + xs_strpcat(&pcResult, &j, finfo->authorString); + break; + + case '2': + xs_strpcat(&pcResult, &j, finfo->nameString); + break; + + case '3': + xs_strpcat(&pcResult, &j, finfo->copyrightString); + break; + + case '4': + xs_strpcat(&pcResult, &j, finfo->formatString); + break; + } /* case */ + } else + pcResult[j++] = xs_cfg.titleFormat[i]; + } + + pcResult[j] = 0; +#ifdef HAVE_XMMSEXTRA + } +#endif + + return pcResult; +} +