# HG changeset patch # User Matti Hamalainen # Date 1103821325 0 # Node ID 583f5651abffd30eb3d84e714fbafbac19e83f6b # Parent f949b83c3f52d142016574565ade48642ba66d9d Cleanups, moved engine configuration to initialization function. Audio settings "feedback" and oversampling support implemented. diff -r f949b83c3f52 -r 583f5651abff src/xs_sidplay1.cc --- a/src/xs_sidplay1.cc Thu Dec 23 13:29:00 2004 +0000 +++ b/src/xs_sidplay1.cc Thu Dec 23 17:02:05 2004 +0000 @@ -33,6 +33,8 @@ #include #include +/* Maximum audio frequency supported by libSIDPlay v1 */ +#define SIDPLAY1_MAX_FREQ (48000) typedef struct { emuEngine *currEng; @@ -41,14 +43,11 @@ } t_xs_sidplay1; -/* - * We need to 'export' all this pseudo-C++ crap - */ +/* We need to 'export' all this pseudo-C++ crap */ extern "C" { -/* - * Check if we can play the given file +/* Check if we can play the given file */ gboolean xs_sidplay1_isourfile(gchar *pcFilename) { @@ -66,11 +65,11 @@ } -/* - * Initialize SIDPlay1 +/* Initialize SIDPlay1 */ gboolean xs_sidplay1_init(t_xs_status *myStatus) { + gint tmpFreq; t_xs_sidplay1 *myEngine; assert(myStatus); @@ -97,87 +96,11 @@ } myStatus->sidEngine = myEngine; - return TRUE; -} - - -/* - * Close SIDPlay1 - */ -void xs_sidplay1_close(t_xs_status *myStatus) -{ - t_xs_sidplay1 *myEngine; - assert(myStatus); - - /* Free internals */ - myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; - if (myEngine->currEng) - { - delete myEngine->currEng; - myEngine->currEng = NULL; - } - - g_free(myEngine); - myStatus->sidEngine = NULL; -} - - -gboolean xs_sidplay1_initsong(t_xs_status *myStatus) -{ - t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; - - if (!myEngine) return FALSE; - - if (!myEngine->currTune) - { - XSERR("Tune was NULL\n"); - return FALSE; - } - - if (!myEngine->currTune->getStatus()) - { - XSERR("Tune status check failed\n"); - return FALSE; - } - - return sidEmuInitializeSong( - *myEngine->currEng, - *myEngine->currTune, - myStatus->currSong); -} - - -guint xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize) -{ - t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; - - if (!myEngine) return 0; - - sidEmuFillBuffer( - *myEngine->currEng, - *myEngine->currTune, - audioBuffer, - audioBufSize); - - return audioBufSize; -} - - -gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFilename) -{ - t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; - sidTune *newTune; - assert(myStatus); - - /* Try to get the tune */ - if (!pcFilename) return FALSE; - newTune = new sidTune(pcFilename); - if (!newTune) return FALSE; /* Get current configuration */ myEngine->currEng->getConfig(myEngine->currConfig); - /* Configure channels and stuff */ + /* Configure channel parameters */ switch (myStatus->audioChannels) { case XS_CHN_AUTOPAN: @@ -197,16 +120,13 @@ myEngine->currConfig.channels = SIDEMU_MONO; myEngine->currConfig.autoPanning = SIDEMU_NONE; myEngine->currConfig.volumeControl = SIDEMU_NONE; + myStatus->audioChannels = XS_CHN_MONO; break; } /* Memory mode settings */ switch (xs_cfg.memoryMode) { - case XS_MPU_BANK_SWITCHING: - myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; - break; - case XS_MPU_TRANSPARENT_ROM: myEngine->currConfig.memoryMode = MPU_TRANSPARENT_ROM; break; @@ -215,8 +135,10 @@ myEngine->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; break; + case XS_MPU_BANK_SWITCHING: default: myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; + xs_cfg.memoryMode = XS_MPU_BANK_SWITCHING; break; } @@ -230,6 +152,7 @@ case XS_CLOCK_PAL: default: myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; + xs_cfg.clockSpeed = XS_CLOCK_PAL; break; } @@ -241,13 +164,31 @@ myEngine->currConfig.filterFm = xs_cfg.filterFm; myEngine->currConfig.filterFt = xs_cfg.filterFt; - myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample; - myEngine->currConfig.frequency = myStatus->audioFrequency; + + /* Audio parameters sanity checking and setup */ + myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample; + tmpFreq = myStatus->audioFrequency; + + if (myStatus->oversampleEnable) + { + if ((tmpFreq * myStatus->oversampleFactor) > SIDPLAY1_MAX_FREQ) + { + myStatus->oversampleEnable = FALSE; + } else { + tmpFreq = (tmpFreq * myStatus->oversampleFactor); + } + } else { + if (tmpFreq > SIDPLAY1_MAX_FREQ) + tmpFreq = SIDPLAY1_MAX_FREQ; + } + + myEngine->currConfig.frequency = tmpFreq; switch (myStatus->audioBitsPerSample) { case XS_RES_8BIT: switch (myStatus->audioFormat) { case FMT_S8: + myStatus->audioFormat = FMT_S8; myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; break; @@ -260,6 +201,7 @@ break; case XS_RES_16BIT: + default: switch (myStatus->audioFormat) { case FMT_U16_NE: case FMT_U16_LE: @@ -286,15 +228,103 @@ return FALSE; } - /* Initialize status information */ + return TRUE; +} + + +/* Close SIDPlay1 engine + */ +void xs_sidplay1_close(t_xs_status *myStatus) +{ + t_xs_sidplay1 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; + + /* Free internals */ + if (myEngine->currEng) + { + delete myEngine->currEng; + myEngine->currEng = NULL; + } + + g_free(myEngine); + myStatus->sidEngine = NULL; +} + + +/* Initialize current song and sub-tune + */ +gboolean xs_sidplay1_initsong(t_xs_status *myStatus) +{ + t_xs_sidplay1 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; + if (!myEngine) return FALSE; + + if (!myEngine->currTune) + { + XSERR("Tune was NULL\n"); + return FALSE; + } + + if (!myEngine->currTune->getStatus()) + { + XSERR("Tune status check failed\n"); + return FALSE; + } + + return sidEmuInitializeSong( + *myEngine->currEng, + *myEngine->currTune, + myStatus->currSong); +} + + +/* Emulate and render audio data to given buffer + */ +guint xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize) +{ + t_xs_sidplay1 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; + if (!myEngine) return 0; + + sidEmuFillBuffer( + *myEngine->currEng, + *myEngine->currTune, + audioBuffer, + audioBufSize); + + return audioBufSize; +} + + +/* Load a given SID-tune file + */ +gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFilename) +{ + t_xs_sidplay1 *myEngine; + sidTune *newTune; + assert(myStatus); + + myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; + + /* Try to get the tune */ + if (!pcFilename) return FALSE; + + newTune = new sidTune(pcFilename); + if (!newTune) return FALSE; + myEngine->currTune = newTune; return TRUE; } -/* - * Delete INTERNAL information +/* Delete INTERNAL information */ void xs_sidplay1_deletesid(t_xs_status *myStatus) { @@ -312,8 +342,7 @@ } -/* - * Return song information +/* Return song information */ #define TFUNCTION xs_sidplay1_getsidinfo #define TTUNEINFO sidTuneInfo diff -r f949b83c3f52 -r 583f5651abff src/xs_sidplay2.cc --- a/src/xs_sidplay2.cc Thu Dec 23 13:29:00 2004 +0000 +++ b/src/xs_sidplay2.cc Thu Dec 23 17:02:05 2004 +0000 @@ -47,14 +47,11 @@ } t_xs_sidplay2; -/* - * We need to 'export' all this pseudo-C++ crap - */ +/* We need to 'export' all this pseudo-C++ crap */ extern "C" { -/* - * Check if we can play the given file +/* Check if we can play the given file */ gboolean xs_sidplay2_isourfile(gchar *pcFilename) { @@ -72,11 +69,12 @@ } -/* - * Initialize SIDPlay2 + +/* Initialize SIDPlay2 */ gboolean xs_sidplay2_init(t_xs_status *myStatus) { + gint tmpFreq; t_xs_sidplay2 *myEngine; assert(myStatus); @@ -98,7 +96,7 @@ #ifdef HAVE_RESID_BUILDER if (xs_cfg.sid2Builder == XS_BLD_RESID) { - ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx and is made by a fag - ReSID builder"); + ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx - ReSID builder"); /* Create the builder -- WHAT IS THIS MEANT FOR??? */ tmpb->create(myEngine->currEng->info().maxsids); @@ -119,98 +117,8 @@ } XSDEBUG("%s\n", myEngine->currBuilder->credits()); - - - /* Create the sidtune */ - myEngine->currTune = new SidTune(0); - if (!myEngine->currTune) - { - XSERR("Could not initialize SIDTune object.\n"); - return FALSE; - } - - /* OK */ myStatus->sidEngine = myEngine; - return TRUE; -} - - -/* - * Close SIDPlay2 - */ -void xs_sidplay2_close(t_xs_status *myStatus) -{ - t_xs_sidplay2 *myEngine; - assert(myStatus); - - /* Free internals */ - myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - - if (myEngine->currBuilder) - { - delete myEngine->currBuilder; - myEngine->currBuilder = NULL; - } - - if (myEngine->currEng) - { - delete myEngine->currEng; - myEngine->currEng = NULL; - } - - if (myEngine->currTune) - { - delete myEngine->currTune; - myEngine->currTune = NULL; - } - xs_sidplay2_deletesid(myStatus); - - g_free(myEngine); - myStatus->sidEngine = NULL; -} - - -gboolean xs_sidplay2_initsong(t_xs_status *myStatus) -{ - t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - - if (!myEngine) return FALSE; - - if (!myEngine->currTune->selectSong(myStatus->currSong)) - { - XSERR("ENGINE selectSong() failed\n"); - return FALSE; - } - - if (myEngine->currEng->load(myEngine->currTune) < 0) - { - XSERR("ENGINE load() failed\n"); - return FALSE; - } - - return TRUE; -} - - -guint xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize) -{ - t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - - if (!myEngine) return 0; - - return myEngine->currEng->play(audioBuffer, audioBufSize); -} - - -gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFilename) -{ - t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; - assert(myStatus); - - /* Try to get the tune */ - if (!pcFilename) return FALSE; - if (!myEngine->currTune->load(pcFilename)) return FALSE; /* Get current configuration */ myEngine->currConfig = myEngine->currEng->config(); @@ -229,6 +137,7 @@ case XS_CHN_MONO: default: myEngine->currConfig.playback = sid2_mono; + myStatus->audioChannels = XS_CHN_MONO; break; } @@ -250,6 +159,7 @@ case XS_MPU_REAL: default: myEngine->currConfig.environment = sid2_envR; + xs_cfg.memoryMode = XS_MPU_REAL; break; } @@ -263,6 +173,7 @@ case XS_CLOCK_PAL: default: myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault = SID2_CLOCK_PAL; + xs_cfg.clockSpeed = XS_CLOCK_PAL; break; } @@ -271,10 +182,23 @@ 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; + if (xs_cfg.mos8580) + myEngine->currConfig.sidDefault = SID2_MOS8580; + else + myEngine->currConfig.sidDefault = SID2_MOS6581; + + myEngine->currConfig.sidModel = myEngine->currConfig.sidDefault; myEngine->currConfig.sidSamples = TRUE; // FIXME FIX ME, make configurable! - myEngine->currConfig.precision = myStatus->audioBitsPerSample; - myEngine->currConfig.frequency = myStatus->audioFrequency; + + + /* Audio parameters sanity checking and setup */ + myEngine->currConfig.precision = myStatus->audioBitsPerSample; + tmpFreq = myStatus->audioFrequency; + + if (myStatus->oversampleEnable) + tmpFreq = (tmpFreq * myStatus->oversampleFactor); + + myEngine->currConfig.frequency = tmpFreq; switch (myStatus->audioBitsPerSample) { case XS_RES_8BIT: @@ -283,6 +207,7 @@ break; case XS_RES_16BIT: + default: switch (myStatus->audioFormat) { case FMT_U16_LE: myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; @@ -293,7 +218,6 @@ break; case FMT_U16_NE: - myStatus->audioFormat = FMT_U16_NE; #ifdef WORDS_BIGENDIAN myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; #else @@ -322,7 +246,6 @@ break; } - /* Now set the emulator configuration */ if (myEngine->currEng->config(myEngine->currConfig) < 0) { @@ -330,12 +253,111 @@ return FALSE; } + /* Create the sidtune */ + myEngine->currTune = new SidTune(0); + if (!myEngine->currTune) + { + XSERR("Could not initialize SIDTune object.\n"); + return FALSE; + } + return TRUE; } -/* - * Delete tune +/* Close SIDPlay2 engine + */ +void xs_sidplay2_close(t_xs_status *myStatus) +{ + t_xs_sidplay2 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; + + /* Free internals */ + if (myEngine->currBuilder) + { + delete myEngine->currBuilder; + myEngine->currBuilder = NULL; + } + + if (myEngine->currEng) + { + delete myEngine->currEng; + myEngine->currEng = NULL; + } + + if (myEngine->currTune) + { + delete myEngine->currTune; + myEngine->currTune = NULL; + } + + xs_sidplay2_deletesid(myStatus); + + g_free(myEngine); + myStatus->sidEngine = NULL; +} + + +/* Initialize current song and sub-tune + */ +gboolean xs_sidplay2_initsong(t_xs_status *myStatus) +{ + t_xs_sidplay2 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; + if (!myEngine) return FALSE; + + if (!myEngine->currTune->selectSong(myStatus->currSong)) + { + XSERR("currTune->selectSong() failed\n"); + return FALSE; + } + + if (myEngine->currEng->load(myEngine->currTune) < 0) + { + XSERR("currEng->load() failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* Emulate and render audio data to given buffer + */ +guint xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize) +{ + t_xs_sidplay2 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; + if (!myEngine) return 0; + + return myEngine->currEng->play(audioBuffer, audioBufSize); +} + + +/* Load a given SID-tune file + */ +gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFilename) +{ + t_xs_sidplay2 *myEngine; + assert(myStatus); + + myEngine = (t_xs_sidplay2 *) myStatus->sidEngine; + + /* Try to get the tune */ + if (!pcFilename) return FALSE; + if (!myEngine->currTune->load(pcFilename)) return FALSE; + + return TRUE; +} + + +/* Delete INTERNAL information */ void xs_sidplay2_deletesid(t_xs_status *myStatus) { @@ -345,8 +367,7 @@ } -/* - * Return song information +/* Return song information */ #define TFUNCTION xs_sidplay2_getsidinfo #define TTUNEINFO SidTuneInfo