# HG changeset patch # User Matti Hamalainen # Date 1063174864 0 # Node ID 2b32c75729ce280122666ccc24202c2688033461 # Parent ec31a68bbc2c410357d980ca99d179e1aba06fce Started modularizing, separated sidplay1 things into a "wrapper" module. Removed non-generic stuff from xmms-sid.cc, removed C++ references and renamed to xmms-sid.c diff -r ec31a68bbc2c -r 2b32c75729ce src/Makefile.am --- a/src/Makefile.am Sun Jul 13 14:36:00 2003 +0000 +++ b/src/Makefile.am Wed Sep 10 06:21:04 2003 +0000 @@ -10,7 +10,8 @@ # Plugin sources libxmmssid_la_SOURCES = \ - xmms-sid.cc xmms-sid.h \ + xmms-sid.c xmms-sid.h \ + xs_sidplay1.cc xs_sidplay1.h \ xs_init.c \ xs_about.c \ xs_support.c xs_support.h \ diff -r ec31a68bbc2c -r 2b32c75729ce src/xmms-sid.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xmms-sid.c Wed Sep 10 06:21:04 2003 +0000 @@ -0,0 +1,405 @@ +/* + XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS) + + Main source file + + Written by Matti "ccr" Hamalainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include +#include +#include +#include +#include + +#include + +#include "xmms-sid.h" +#include "xs_support.h" +#include "xs_config.h" +#include "xs_length.h" +#include "xs_interface.h" +#include "xs_glade.h" + +/* + * Include player engines + */ +#include "xs_sidplay1.h" +#include "xs_sidplay2.h" + + +/* + * Global variables + */ +static GtkWidget *xs_ctrlwin = NULL; +static pthread_t xs_decode_thread; +static pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; +struct t_xs_cfg xs_cfg; + + +/* + * Create sub-song control window + */ +void xs_ctrlwin_open(void) +{ + /* Create sub-song control window */ + if (xs_ctrlwin != NULL) + { + if (xs_cfg.alwaysRaise) + gdk_window_raise(xs_ctrlwin->window); + return; + } + + xs_ctrlwin = create_xs_ctrlwin(); + gtk_widget_show(xs_ctrlwin); +} + + +/* + * Initialize XMMS-SID + */ +void xs_init(void) +{ + XSDEBUG("xs_init()\n"); + + /* Initialize and get configuration */ + memset(&xs_cfg, 0, sizeof(xs_cfg)); + + xs_read_configuration(); + + /* Initialize status */ + memset(&xs_status, 0, sizeof(xs_status)); + xs_status.allowNext = TRUE; // Initialize to TRUE to allow first song + + /* Try to initialize emulator engine(s) */ + XSDEBUG("initializing emulator engine(s)...\n"); + + + + + /* Read song-length database */ + if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0)) + { + XSERR("Error initializing song-length database!\n"); + } + + /* Initialize STIL structures */ + +// xs_ctrlwin_open(); + +// FIXME FIXME FIx ME + + XSDEBUG("OK\n"); +} + + +/* + * Shut down XMMS-SID + */ +void xs_close(void) +{ + XSDEBUG("xs_close(): shutting down...\n"); + + /* Stop playing */ + xs_stop(); + + /* Shutdown libSIDPlay(s) */ + + + + + + + /* Close sub-song control window */ + + /* Free allocated memory */ + xs_songlen_close(); + +// FIXME FIXME: STIL-entries + XSDEBUG("shutdown finished.\n"); +} + + +/* + * Main playing thread loop + */ +void *xs_play_loop(void *argPointer) +{ + t_xs_status myStatus; + t_xs_tuneinfo tuneInfo; + gboolean audioOpen; + gint audioFreq, audioChannels, songLength; + enum AFormat audioFmt; + gchar audioBuffer[XS_BUFSIZE]; + gchar *tmpStr; + + + pthread_mutex_lock(&xs_mutex); + XSDEBUG("entering play thread\n"); + + /* No idea, if this is really required here, but better be + * careful since we're dealing with EVIL threads ... + */ + if (!xs_status.allowNext) + { + pthread_mutex_unlock(&xs_mutex); + pthread_exit(NULL); + } + + /* Don't allow next song to be set yet */ + xs_status.allowNext = FALSE; + xs_status.isPlaying = TRUE; + memcpy(&myStatus, &xs_status, sizeof(t_xs_status)); + pthread_mutex_unlock(&xs_mutex); + + + /* Copy and check audio options here (they might change in config while running) */ +#ifdef HAVE_UNSIGNEDPCM + audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_U16_NE : FMT_U8; +#else + audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_S16_NE : FMT_S8; +#endif + audioFreq = xs_cfg.fmtFrequency; + audioChannels = (xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2; + audioOpen = FALSE; + + /* + * Main player loop: while not stopped, loop here - play subtunes + */ + while (xs_status.isPlaying) + { + pthread_mutex_lock(&xs_mutex); + myStatus.currSong = xs_status.currSong; + myStatus.isPlaying = TRUE; + pthread_mutex_unlock(&xs_mutex); + + XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); + + + /* Get song length for current subtune */ + songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong); + + /* Initialize song */ +#ifdef HAVE_SIDPLAY1 + if ((myStatus.currTune == NULL) || !myStatus.currTune->getStatus() || + !sidEmuInitializeSong(xs_emuEngine, *myStatus.currTune, myStatus.currSong)) +#endif +#ifdef HAVE_SIDPLAY2 + if () +#endif + { + XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n", + myStatus.currFileName, myStatus.currSong); + goto err_exit; + } + + myStatus.currTune->getInfo(tuneInfo); + + + /* Set information for current sub-tune */ + tmpStr = xs_filetitle_get(myStatus.currFileName, &tuneInfo, myStatus.currSong); + + xs_plugin_ip.set_info(tmpStr, (songLength > 0) ? songLength * 1000 : -1, + 1000 * (tuneInfo.songSpeed ? tuneInfo.songSpeed : (tuneInfo.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50), + audioFreq, audioChannels); + g_free(tmpStr); + + /* Open the audio output */ + if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels)) + { + XSERR("Couldn't open XMMS audio output!\n"); + pthread_mutex_lock(&xs_mutex); + xs_status.isError = TRUE; + pthread_mutex_unlock(&xs_mutex); + goto err_exit; + } + + audioOpen = TRUE; + + /* + * Play the subtune + */ + while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == myStatus.currSong)) + { + /* Render audio data */ +#ifdef HAVE_SIDPLAY1 + sidEmuFillBuffer(xs_emuEngine, *myStatus.currTune, audioBuffer, XS_BUFSIZE); +#endif +#ifdef HAVE_SIDPLAY2 +#endif + + /* I <3 visualice/haujobb */ + xs_plugin_ip.add_vis_pcm( + xs_plugin_ip.output->written_time(), + audioFmt, audioChannels, XS_BUFSIZE, audioBuffer); + + /* Wait a little */ + while (xs_status.isPlaying && + (xs_status.currSong == myStatus.currSong) && + (xs_plugin_ip.output->buffer_free() < XS_BUFSIZE)) + xmms_usleep(10000); + + /* Output audio */ + if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong)) + xs_plugin_ip.output->write_audio(audioBuffer, XS_BUFSIZE); + + /* Check if we have played enough */ + if (xs_cfg.playMaxTimeEnable) + { + if (xs_cfg.playMaxTimeUnknown) + { + if ((songLength == -1) && + (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000))) + myStatus.isPlaying = FALSE; + } else { + if (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000)) + myStatus.isPlaying = FALSE; + } + } + + if (songLength > 0) + { + if (xs_plugin_ip.output->output_time() >= (songLength * 1000)) + myStatus.isPlaying = FALSE; + } + } + + XSDEBUG("subtune ended/stopped\n"); + + /* Close audio */ + if (audioOpen) + { + XSDEBUG("close audio #1\n"); + xs_plugin_ip.output->close_audio(); + audioOpen = FALSE; + } + + /* Now determine if we continue by selecting other subtune or something */ + if (!myStatus.isPlaying) xs_status.isPlaying = FALSE; + } + + /* When exiting, delete data */ +err_exit: + pthread_mutex_lock(&xs_mutex); + xs_status.isPlaying = FALSE; + pthread_mutex_unlock(&xs_mutex); + + if (audioOpen) + { + XSDEBUG("close audio #2\n"); + xs_plugin_ip.output->close_audio(); + } + + if (myStatus.currTune != NULL) + { + delete myStatus.currTune; + myStatus.currTune = NULL; + } + + g_free(myStatus.currFileName); + + /* Exit the playing thread */ + XSDEBUG("exiting thread, bye.\n"); + + /* Last thing we do is set allowNext to TRUE to flag + * that we have ended all action in the thread + */ + pthread_mutex_lock(&xs_mutex); + xs_status.allowNext = TRUE; + pthread_mutex_unlock(&xs_mutex); + + pthread_exit(NULL); +} + + +/* + * Start playing the given file + */ +void xs_play_file(char *pcFileName) +{ +} + + +/* + * Stop playing + */ +void xs_stop(void) +{ + /* If playing, stop. */ + XSDEBUG("STOP_REQ\n"); + if (xs_status.isPlaying || !xs_status.allowNext) + { + XSDEBUG("stopping...\n"); + pthread_mutex_lock(&xs_mutex); + xs_status.isPlaying = FALSE; + pthread_mutex_unlock(&xs_mutex); + pthread_join(xs_decode_thread, NULL); + } +} + + +/* + * Pause the playing + */ +void xs_pause(short pauseState) +{ + xs_plugin_ip.output->pause(pauseState); +} + + +/* + * Set the time-seek position + * (the playing thread will do the "seeking" aka song-change) + */ +void xs_seek(gint iTime) +{ + /* If we have song-position patch, check settings */ +#ifdef HAVE_SONG_POSITION + pthread_mutex_lock(&xs_mutex); + + if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying) + xs_status.currSong = iTime; + + pthread_mutex_unlock(&xs_mutex); +#endif +} + + +/* + * Return the playing "position/time" + */ +gint xs_get_time(void) +{ + /* If errorflag is set, return -2 to signal it to XMMS's idle callback */ + if (xs_status.isError) + return -2; + + /* If tune has ended, return -1 */ + if (xs_status.allowNext && !xs_status.isPlaying) + return -1; + + /* Obsolete? */ +#ifdef HAVE_SONG_POSITION + pthread_mutex_lock(&xs_mutex); + set_song_position(xs_status.currSong, 1, xs_status.nSongs); + pthread_mutex_unlock(&xs_mutex); +#endif + + /* Else, return output time reported by audio output plugin */ + return xs_plugin_ip.output->output_time(); +} + + diff -r ec31a68bbc2c -r 2b32c75729ce src/xmms-sid.cc --- a/src/xmms-sid.cc Sun Jul 13 14:36:00 2003 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,836 +0,0 @@ -/* - XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS) - - Main source file - - Written by Matti "ccr" Hamalainen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include -#include -#include -#include -#include - -extern "C" { -#include -#include -#include -#include "xs_interface.h" -#include "xs_glade.h" -} - -#include "xmms-sid.h" -#include "xs_support.h" -#include "xs_config.h" -#include "xs_length.h" - - -#ifdef HAVE_SIDPLAY1 -#include -#include -#include -#endif - -#ifdef HAVE_SIDPLAY2 -#include -#endif - - -/* - * Global variables - */ -#ifdef HAVE_SIDPLAY1 -typedef sidTune t_xs_tune; -typedef struct sidTuneInfo t_xs_tuneinfo; -#endif - -#ifdef HAVE_SIDPLAY2 -typedef SidTune t_xs_tune; -typedef struct SidTuneInfo t_xs_tuneinfo; -#endif - -#ifdef HAVE_SIDPLAY1 - struct emuConfig xs_emuConf; - emuEngine xs_emuEngine; -#endif -#ifdef HAVE_SIDPLAY2 - struct sid2_config_t xs_emuConf; - sidplay2 xs_emuEngine; -#endif - -typedef struct { - gboolean isError, isPlaying, allowNext; - gint currSong, nSongs; - t_xs_tune *currTune; - gchar *currFileName; -} t_xs_status; - -static GtkWidget *xs_ctrlwin = NULL; -static pthread_t xs_decode_thread; -static pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; -struct t_xs_cfg xs_cfg; -t_xs_status xs_status; - - -gchar *xs_filetitle_get(gchar *, t_xs_tuneinfo *, gint); - - -/* - * Create sub-song control window - */ -void xs_ctrlwin_open(void) -{ - /* Create sub-song control window */ - if (xs_ctrlwin != NULL) - { - if (xs_cfg.alwaysRaise) - gdk_window_raise(xs_ctrlwin->window); - return; - } - - xs_ctrlwin = create_xs_ctrlwin(); - gtk_widget_show(xs_ctrlwin); -} - - -/* - * Initialize XMMS-SID - */ -void xs_init(void) -{ - XSDEBUG("xs_init()\n"); - - /* Initialize and get configuration */ - memset(&xs_cfg, 0, sizeof(xs_cfg)); - - xs_read_configuration(); - - /* Initialize status */ - memset(&xs_status, 0, sizeof(xs_status)); - xs_status.allowNext = TRUE; // Initialize to TRUE to allow first song - - /* Try to initialize emulator engine(s) */ - XSDEBUG("initializing emulator engine(s)...\n"); - -#ifdef HAVE_SIDPLAY1 - if (!xs_emuEngine || !xs_emuEngine.verifyEndianess()) - { - XSERR("Couldn't initialize SIDPlay1 emulator engine!\n"); - return; - } -#endif - - /* Read song-length database */ - if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0)) - { - XSERR("Error initializing song-length database!\n"); - } - - /* Initialize STIL structures */ - -// xs_ctrlwin_open(); - -// FIXME FIXME FIx ME - - XSDEBUG("OK\n"); -} - - -/* - * Shut down XMMS-SID - */ -void xs_close(void) -{ - XSDEBUG("xs_close(): shutting down...\n"); - - /* Stop playing */ - xs_stop(); - - /* Shutdown libSIDPlay(s) */ -#ifdef HAVE_SIDPLAY1 -#endif - -#ifdef HAVE_SIDPLAY2 -#endif - - /* Close sub-song control window */ - - /* Free allocated memory */ - xs_songlen_close(); - -// FIXME FIXME: STIL-entries - XSDEBUG("shutdown finished.\n"); -} - - -/* - * Check whether the given file is handled by this plugin - */ -gint xs_is_our_file(gchar *pcFileName) -{ - char *pcExt; - t_xs_tune *testTune; - - /* Check the filename */ - if (pcFileName == NULL) - return FALSE; - - /* Try to detect via libSIDPlay's detection routine, if required */ - if (xs_cfg.detectMagic) - { - testTune = new t_xs_tune(pcFileName); - if (testTune == NULL) return FALSE; - if (testTune->getStatus()) - { - delete testTune; - return TRUE; - } - - /* We DON'T fall back to filename extension checking ... */ - delete testTune; - return FALSE; - } - - /* Detect just by checking filename extension */ - pcExt = xs_strrchr(pcFileName, '.'); - if (pcExt) - { - pcExt++; - if (!g_strcasecmp(pcExt, "psid")) return TRUE; - if (!g_strcasecmp(pcExt, "sid")) return TRUE; - if (!g_strcasecmp(pcExt, "dat")) return TRUE; - if (!g_strcasecmp(pcExt, "inf")) return TRUE; - if (!g_strcasecmp(pcExt, "info")) return TRUE; - } - - return FALSE; -} - - -/* - * Main playing thread loop - */ -void *xs_play_loop(void *argPointer) -{ - t_xs_status myStatus; - t_xs_tuneinfo tuneInfo; - gboolean audioOpen; - gint audioFreq, audioChannels, songLength; - enum AFormat audioFmt; - gchar audioBuffer[XS_BUFSIZE]; - gchar *tmpStr; - - - pthread_mutex_lock(&xs_mutex); - XSDEBUG("entering play thread\n"); - - /* No idea, if this is really required here, but better be - * careful since we're dealing with EVIL threads ... - */ - if (!xs_status.allowNext) - { - pthread_mutex_unlock(&xs_mutex); - pthread_exit(NULL); - } - - /* Don't allow next song to be set yet */ - xs_status.allowNext = FALSE; - xs_status.isPlaying = TRUE; - memcpy(&myStatus, &xs_status, sizeof(t_xs_status)); - pthread_mutex_unlock(&xs_mutex); - - - /* Copy and check audio options here (they might change in config while running) */ -#ifdef HAVE_UNSIGNEDPCM - audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_U16_NE : FMT_U8; -#else - audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_S16_NE : FMT_S8; -#endif - audioFreq = xs_cfg.fmtFrequency; - audioChannels = (xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2; - audioOpen = FALSE; - - /* - * Main player loop: while not stopped, loop here - play subtunes - */ - while (xs_status.isPlaying) - { - pthread_mutex_lock(&xs_mutex); - myStatus.currSong = xs_status.currSong; - myStatus.isPlaying = TRUE; - pthread_mutex_unlock(&xs_mutex); - - XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); - - - /* Get song length for current subtune */ - songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong); - - /* Initialize song */ -#ifdef HAVE_SIDPLAY1 - if ((myStatus.currTune == NULL) || !myStatus.currTune->getStatus() || - !sidEmuInitializeSong(xs_emuEngine, *myStatus.currTune, myStatus.currSong)) -#endif -#ifdef HAVE_SIDPLAY2 - if () -#endif - { - XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n", - myStatus.currFileName, myStatus.currSong); - goto err_exit; - } - - myStatus.currTune->getInfo(tuneInfo); - - - /* Set information for current sub-tune */ - tmpStr = xs_filetitle_get(myStatus.currFileName, &tuneInfo, myStatus.currSong); - - xs_plugin_ip.set_info(tmpStr, (songLength > 0) ? songLength * 1000 : -1, - 1000 * (tuneInfo.songSpeed ? tuneInfo.songSpeed : (tuneInfo.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50), - audioFreq, audioChannels); - g_free(tmpStr); - - /* Open the audio output */ - if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels)) - { - XSERR("Couldn't open XMMS audio output!\n"); - pthread_mutex_lock(&xs_mutex); - xs_status.isError = TRUE; - pthread_mutex_unlock(&xs_mutex); - goto err_exit; - } - - audioOpen = TRUE; - - /* - * Play the subtune - */ - while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == myStatus.currSong)) - { - /* Render audio data */ -#ifdef HAVE_SIDPLAY1 - sidEmuFillBuffer(xs_emuEngine, *myStatus.currTune, audioBuffer, XS_BUFSIZE); -#endif -#ifdef HAVE_SIDPLAY2 -#endif - - /* I <3 visualice/haujobb */ - xs_plugin_ip.add_vis_pcm( - xs_plugin_ip.output->written_time(), - audioFmt, audioChannels, XS_BUFSIZE, audioBuffer); - - /* Wait a little */ - while (xs_status.isPlaying && - (xs_status.currSong == myStatus.currSong) && - (xs_plugin_ip.output->buffer_free() < XS_BUFSIZE)) - xmms_usleep(10000); - - /* Output audio */ - if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong)) - xs_plugin_ip.output->write_audio(audioBuffer, XS_BUFSIZE); - - /* Check if we have played enough */ - if (xs_cfg.playMaxTimeEnable) - { - if (xs_cfg.playMaxTimeUnknown) - { - if ((songLength == -1) && - (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000))) - myStatus.isPlaying = FALSE; - } else { - if (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000)) - myStatus.isPlaying = FALSE; - } - } - - if (songLength > 0) - { - if (xs_plugin_ip.output->output_time() >= (songLength * 1000)) - myStatus.isPlaying = FALSE; - } - } - - XSDEBUG("subtune ended/stopped\n"); - - /* Close audio */ - if (audioOpen) - { - XSDEBUG("close audio #1\n"); - xs_plugin_ip.output->close_audio(); - audioOpen = FALSE; - } - - /* Now determine if we continue by selecting other subtune or something */ - if (!myStatus.isPlaying) xs_status.isPlaying = FALSE; - } - - /* When exiting, delete data */ -err_exit: - pthread_mutex_lock(&xs_mutex); - xs_status.isPlaying = FALSE; - pthread_mutex_unlock(&xs_mutex); - - if (audioOpen) - { - XSDEBUG("close audio #2\n"); - xs_plugin_ip.output->close_audio(); - } - - if (myStatus.currTune != NULL) - { - delete myStatus.currTune; - myStatus.currTune = NULL; - } - - g_free(myStatus.currFileName); - - /* Exit the playing thread */ - XSDEBUG("exiting thread, bye.\n"); - - /* Last thing we do is set allowNext to TRUE to flag - * that we have ended all action in the thread - */ - pthread_mutex_lock(&xs_mutex); - xs_status.allowNext = TRUE; - pthread_mutex_unlock(&xs_mutex); - - pthread_exit(NULL); -} - - -/* - * Start playing the given file - */ -void xs_play_file(char *pcFileName) -{ - t_xs_tune *newTune; - t_xs_tuneinfo tuneInfo; - - /* Can we set the next tune? */ - XSDEBUG("request to play '%s'\n", pcFileName); - - /* Try to get the tune */ - newTune = new t_xs_tune(pcFileName); - if (newTune == NULL) return; - -#ifdef HAVE_SIDPLAY1 - /* Get current configuration */ - xs_emuEngine.getConfig(xs_emuConf); - - /* Configure channels and stuff */ - switch (xs_cfg.fmtChannels) { - - case XS_CHN_AUTOPAN: - xs_emuConf.channels = SIDEMU_STEREO; - xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; - xs_emuConf.volumeControl = SIDEMU_FULLPANNING; - break; - - case XS_CHN_STEREO: - xs_emuConf.channels = SIDEMU_STEREO; - xs_emuConf.autoPanning = SIDEMU_NONE; - xs_emuConf.volumeControl = SIDEMU_NONE; - break; - - case XS_CHN_MONO: - default: - xs_emuConf.channels = SIDEMU_MONO; - xs_emuConf.autoPanning = SIDEMU_NONE; - xs_emuConf.volumeControl = SIDEMU_NONE; - break; - } - - - /* Memory mode settings */ - switch (xs_cfg.memoryMode) { - case XS_MPU_BANK_SWITCHING: - xs_emuConf.memoryMode = MPU_BANK_SWITCHING; - break; - - case XS_MPU_TRANSPARENT_ROM: - xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM; - break; - - case XS_MPU_PLAYSID_ENVIRONMENT: - xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; - break; - - default: - xs_emuConf.memoryMode = MPU_BANK_SWITCHING; - break; - } - - - /* Clockspeed settings */ - switch (xs_cfg.clockSpeed) { - case XS_CLOCK_NTSC: - xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC; - break; - - case XS_CLOCK_PAL: - default: - xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL; - break; - } - - - /* Configure rest of the emulation */ - xs_emuConf.bitsPerSample = xs_cfg.fmtBitsPerSample; - xs_emuConf.frequency = xs_cfg.fmtFrequency; -#ifdef HAVE_UNSIGNEDPCM - xs_emuConf.sampleFormat = SIDEMU_UNSIGNED_PCM; -#else - xs_emuConf.sampleFormat = SIDEMU_SIGNED_PCM; -#endif - xs_emuConf.mos8580 = xs_cfg.mos8580; - xs_emuConf.emulateFilter = xs_cfg.emulateFilters; - xs_emuConf.filterFs = xs_cfg.filterFs; - xs_emuConf.filterFm = xs_cfg.filterFm; - xs_emuConf.filterFt = xs_cfg.filterFt; - - /* Now set the emulator configuration */ - xs_emuEngine.setConfig(xs_emuConf); -#endif - - -#ifdef HAVE_SIDPLAY2 - /* Get current configuration */ - xs_emuConf = xs_emuEngine.config(); - - /* Configure channels and stuff */ - switch (xs_cfg.fmtChannels) { - - case XS_CHN_AUTOPAN: - xs_emuConf.playback = sid2_stereo; - break; - - case XS_CHN_STEREO: - xs_emuConf.playback = sid2_stereo; - break; - - case XS_CHN_MONO: - default: - xs_emuConf.playback = sid2_mono; - break; - } - - - /* Memory mode settings */ - switch (xs_cfg.memoryMode) { - case XS_MPU_BANK_SWITCHING: - xs_emuConf.environment = sid2_envBS; - break; - - case XS_MPU_TRANSPARENT_ROM: - xs_emuConf.environment = sid2_envTP; - break; - - case XS_MPU_PLAYSID_ENVIRONMENT: - xs_emuConf.environment = sid2_envPS; - break; - - case XS_MPU_REAL: - default: - xs_emuConf.environment = sid2_envR; - break; - } - - - /* Clockspeed settings */ - switch (xs_cfg.clockSpeed) { - case XS_CLOCK_NTSC: - xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_NTSC; - break; - - case XS_CLOCK_PAL: - default: - xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_PAL; - break; - } - - - /* Configure rest of the emulation */ - xs_emuConf.precision = xs_cfg.fmtBitsPerSample; - xs_emuConf.frequency = xs_cfg.fmtFrequency; - xs_emuConf.clockForced = xs_cfg.forceSpeed; - xs_emuConf.optimisation = (xs_cfg.optimiseLevel) ? 1 : 0; - xs_emuConf.sidDefault = xs_emuConf.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581; - xs_emuConf.sidSamples = TRUE; // FIXME FIX ME, make configurable! - -#ifdef HAVE_UNSIGNEDPCM -#ifdef WORDS_BIGENDIAN - xs_emuConf.sampleFormat = SID2_BIG_UNSIGNED; -#else - xs_emuConf.sampleFormat = SID2_LITTLE_UNSIGNED; -#endif -#else -#ifdef WORDS_BIGENDIAN - xs_emuConf.sampleFormat = SID2_BIG_SIGNED; -#else - xs_emuConf.sampleFormat = SID2_LITTLE_SIGNED; -#endif -#endif - - /* Now set the emulator configuration */ - xs_emuEngine.config(xs_emuConf); -#endif - - - /* Initialize status information */ - XSDEBUG("starting playing thread!\n"); - - newTune->getInfo(tuneInfo); - - xs_status.isPlaying = TRUE; - xs_status.isError = FALSE; - xs_status.currSong = tuneInfo.startSong; - xs_status.nSongs = tuneInfo.songs; - xs_status.currTune = newTune; - xs_status.currFileName = g_strdup(pcFileName); - - /* 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)); - delete newTune; - } - - XSDEBUG("systems should be up?\n"); - - /* Exit */ -} - - -/* - * Stop playing - */ -void xs_stop(void) -{ - /* If playing, stop. */ - XSDEBUG("STOP_REQ\n"); - if (xs_status.isPlaying || !xs_status.allowNext) - { - XSDEBUG("stopping...\n"); - pthread_mutex_lock(&xs_mutex); - xs_status.isPlaying = FALSE; - pthread_mutex_unlock(&xs_mutex); - pthread_join(xs_decode_thread, NULL); - } -} - - -/* - * Pause the playing - */ -void xs_pause(short pauseState) -{ - xs_plugin_ip.output->pause(pauseState); -} - - -/* - * Set the time-seek position - * (the playing thread will do the "seeking" aka song-change) - */ -void xs_seek(gint iTime) -{ - /* If we have song-position patch, check settings */ -#ifdef HAVE_SONG_POSITION - pthread_mutex_lock(&xs_mutex); - - if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying) - xs_status.currSong = iTime; - - pthread_mutex_unlock(&xs_mutex); -#endif -} - - -/* - * Return the playing "position/time" - */ -gint xs_get_time(void) -{ - /* If errorflag is set, return -2 to signal it to XMMS's idle callback */ - if (xs_status.isError) - return -2; - - /* If tune has ended, return -1 */ - if (xs_status.allowNext && !xs_status.isPlaying) - return -1; - - /* Obsolete? */ -#ifdef HAVE_SONG_POSITION - pthread_mutex_lock(&xs_mutex); - set_song_position(xs_status.currSong, 1, xs_status.nSongs); - pthread_mutex_unlock(&xs_mutex); -#endif - - /* Else, return output time reported by audio output plugin */ - return xs_plugin_ip.output->output_time(); -} - - -/* - * Return song information - */ -void xs_get_song_info(gchar *songFileName, gchar **songTitle, gint *songLength) -{ - t_xs_tuneinfo tuneInfo; - t_xs_tune *testTune; - gint tmpInt; - - /* Check if the tune exists and is readable */ - testTune = new t_xs_tune(songFileName); - if (testTune == NULL) return; - if (!testTune->getStatus()) - { - delete testTune; - return; - } - - /* Get general tune information */ - testTune->getInfo(tuneInfo); - delete testTune; - - /* Get titlestring */ - *songTitle = xs_filetitle_get(songFileName, &tuneInfo, tuneInfo.startSong); - - /* Get song length (in milliseconds), negative if no known length */ - tmpInt = xs_songlen_get(songFileName, tuneInfo.startSong); - if (tmpInt >= 0) - *songLength = (tmpInt * 1000); - else - *songLength = -1; -} - - -/* - * Create the SID-tune description string from the tune's information - * formatted by the user-specified format-string. - */ -gchar *xs_filetitle_get(gchar *pcFileName, t_xs_tuneinfo *pfInfo, gint iSubTune) -{ - gint j, iLength; - gchar *pcStr, *pcResult; -#ifdef HAVE_XMMSEXTRA - TitleInput *ptInput; -#endif - - /* FIXME FIXME: get STIL-information */ - - - /* Check the info strings */ - if (pfInfo->numberOfInfoStrings < 3) - { - if (pfInfo->numberOfInfoStrings < 1) - return 0; - - return g_strdup(pfInfo->infoString[0]); - } - -#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 = pfInfo->dataFileName; - ptInput->file_ext = g_strdup("sid"); - ptInput->file_path = pfInfo->path; - - ptInput->track_name = pfInfo->infoString[0]; - ptInput->track_number = iSubTune; - ptInput->album_name = NULL; - ptInput->performer = pfInfo->infoString[1]; - ptInput->date = g_strdup((pfInfo->sidModel == SIDTUNE_SIDMODEL_6581) ? "6581" : "8580"); - - ptInput->year = 0; - ptInput->genre = g_strdup("SID-tune"); - ptInput->comment = pfInfo->infoString[2]; - - /* Create the string */ - pcResult = xmms_get_titlestring(xmms_get_gentitle_format(), ptInput); - - /* Dispose all allocated memory */ - g_free(ptInput->file_ext); - g_free(ptInput->date); - g_free(ptInput->genre); - g_free(ptInput); - } - else -#endif - { - /* Estimate the length of the string */ - pcStr = xs_cfg.titleFormat; - iLength = 0; - while (*pcStr) - { - if (*pcStr == '%') - { - switch (*(++pcStr)) { - case '1': iLength += strlen(pfInfo->infoString[1]); break; - case '2': iLength += strlen(pfInfo->infoString[0]); break; - case '3': iLength += strlen(pfInfo->infoString[2]); break; - case '4': iLength += strlen(pfInfo->formatString); break; - case '%': iLength++; - } - } else - iLength++; - - pcStr++; - } - - /* Allocate memory */ - pcResult = (gchar *) g_malloc(iLength + 2); - if (pcResult == NULL) - return g_strdup(pfInfo->infoString[0]); - - /* Create the string */ - pcStr = xs_cfg.titleFormat; - j = 0; - while (*pcStr) - { - if (*pcStr == '%') - { - switch (*(++pcStr)) { - case '1': xs_strpcat(pcResult, &j, pfInfo->infoString[1]); break; - case '2': xs_strpcat(pcResult, &j, pfInfo->infoString[0]); break; - case '3': xs_strpcat(pcResult, &j, pfInfo->infoString[2]); break; - case '4': xs_strpcat(pcResult, &j, pfInfo->formatString); break; - case '%': pcResult[j++] = '%'; break; - } - } else - pcResult[j++] = *pcStr; - - pcStr++; - } - - pcResult[j] = 0; - } - - return pcResult; -} - diff -r ec31a68bbc2c -r 2b32c75729ce src/xs_sidplay1.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xs_sidplay1.cc Wed Sep 10 06:21:04 2003 +0000 @@ -0,0 +1,173 @@ +/* + XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS) + + libSIDPlay v1 support + + Written by Matti "ccr" Hamalainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef HAVE_SIDPLAY1 +#include "xmms-sid.h" + +extern "C" { +#include +} + +#include +#include +#include + + +struct xs_sidplay1 { + struct emuConfig emuConf; + emuEngine emuEngine; + gboolean isError, isPlaying, allowNext; + gint currSong, nSongs; + sidTune *currTune; + gchar *currFileName; +}; + + + +gboolean xs_sidplay1_initsong(struct xs_sidplay1 *myStatus) +{ + return sidEmuInitializeSong(myStatus->emuEngine, myStatus->currTune, myStatus->currSong); +} + + +void xs_sidplay1_fillbuffer(struct xs_sidplay1 *myStatus, gchar *audioBuffer, gint audioBufSize) +{ + sidEmuFillBuffer(myStatus->emuEngine, myStatus->currTune, audioBuffer, audioBufSize); +} + + +gint xs_sidplay1_inittune(gchar *pcFileName) +{ + sidTune *newTune; + sidTuneInfo tuneInfo; + + /* Can we set the next tune? */ + XSDEBUG("request to play '%s'\n", pcFileName); + + /* Try to get the tune */ + newTune = new sidTune(pcFileName); + if (newTune == NULL) return; + + /* Get current configuration */ + xs_emuEngine.getConfig(xs_emuConf); + + /* Configure channels and stuff */ + switch (xs_cfg.fmtChannels) { + + case XS_CHN_AUTOPAN: + xs_emuConf.channels = SIDEMU_STEREO; + xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; + xs_emuConf.volumeControl = SIDEMU_FULLPANNING; + break; + + case XS_CHN_STEREO: + xs_emuConf.channels = SIDEMU_STEREO; + xs_emuConf.autoPanning = SIDEMU_NONE; + xs_emuConf.volumeControl = SIDEMU_NONE; + break; + + case XS_CHN_MONO: + default: + xs_emuConf.channels = SIDEMU_MONO; + xs_emuConf.autoPanning = SIDEMU_NONE; + xs_emuConf.volumeControl = SIDEMU_NONE; + break; + } + + + /* Memory mode settings */ + switch (xs_cfg.memoryMode) { + case XS_MPU_BANK_SWITCHING: + xs_emuConf.memoryMode = MPU_BANK_SWITCHING; + break; + + case XS_MPU_TRANSPARENT_ROM: + xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM; + break; + + case XS_MPU_PLAYSID_ENVIRONMENT: + xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; + break; + + default: + xs_emuConf.memoryMode = MPU_BANK_SWITCHING; + break; + } + + + /* Clockspeed settings */ + switch (xs_cfg.clockSpeed) { + case XS_CLOCK_NTSC: + xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC; + break; + + case XS_CLOCK_PAL: + default: + xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL; + break; + } + + + /* Configure rest of the emulation */ + xs_emuConf.bitsPerSample = xs_cfg.fmtBitsPerSample; + xs_emuConf.frequency = xs_cfg.fmtFrequency; +#ifdef HAVE_UNSIGNEDPCM + xs_emuConf.sampleFormat = SIDEMU_UNSIGNED_PCM; +#else + xs_emuConf.sampleFormat = SIDEMU_SIGNED_PCM; +#endif + xs_emuConf.mos8580 = xs_cfg.mos8580; + xs_emuConf.emulateFilter = xs_cfg.emulateFilters; + xs_emuConf.filterFs = xs_cfg.filterFs; + xs_emuConf.filterFm = xs_cfg.filterFm; + xs_emuConf.filterFt = xs_cfg.filterFt; + + /* Now set the emulator configuration */ + xs_emuEngine.setConfig(xs_emuConf); + + + /* Initialize status information */ + XSDEBUG("starting playing thread!\n"); + + newTune->getInfo(tuneInfo); + + xs_status->isPlaying = TRUE; + xs_status->isError = FALSE; + xs_status->currSong = tuneInfo.startSong; + xs_status->nSongs = tuneInfo.songs; + xs_status->currTune = newTune; + xs_status->currFileName = g_strdup(pcFileName); + + /* 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)); + delete newTune; + } + + XSDEBUG("systems should be up?\n"); + + /* Exit */ +} + + +#endif /* HAVE_SIDPLAY1 */ + diff -r ec31a68bbc2c -r 2b32c75729ce src/xs_sidplay1.h