From f8a7f23a4b9a633fe455f5b4f21d600de78f44e2 Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Fri, 13 Apr 2018 10:25:26 -0500 Subject: [PATCH] Revert "Add threaded APU option." This reverts commit 045f68bb268a22d3225d269dd046dc9cd505e84c. --- apu/apu.cpp | 879 ++++++++++++++++-------------------- gtk/configure.ac | 17 - gtk/src/gtk_config.cpp | 6 - gtk/src/gtk_preferences.cpp | 5 +- gtk/src/snes9x.ui | 26 +- snes9x.cpp | 1 - snes9x.h | 1 - 7 files changed, 384 insertions(+), 551 deletions(-) diff --git a/apu/apu.cpp b/apu/apu.cpp index d5aabc89..144d6942 100644 --- a/apu/apu.cpp +++ b/apu/apu.cpp @@ -199,133 +199,60 @@ #include "snes/snes.hpp" -#define APU_DEFAULT_INPUT_RATE 31987 // 60hz -#define APU_MINIMUM_SAMPLE_COUNT 512 -#define APU_MINIMUM_SAMPLE_BLOCK 128 -#define APU_NUMERATOR_NTSC 15664 -#define APU_DENOMINATOR_NTSC 328125 -#define APU_NUMERATOR_PAL 34176 -#define APU_DENOMINATOR_PAL 709379 +#define APU_DEFAULT_INPUT_RATE 31987 // 60hz +#define APU_MINIMUM_SAMPLE_COUNT 512 +#define APU_MINIMUM_SAMPLE_BLOCK 128 +#define APU_NUMERATOR_NTSC 15664 +#define APU_DENOMINATOR_NTSC 328125 +#define APU_NUMERATOR_PAL 34176 +#define APU_DENOMINATOR_PAL 709379 namespace SNES { #include "bapu/dsp/blargg_endian.h" -CPU cpu; + + CPU cpu; } namespace spc { -static apu_callback sa_callback = NULL; -static void *extra_data = NULL; + static apu_callback sa_callback = NULL; + static void *extra_data = NULL; -static bool8 sound_in_sync = TRUE; -static bool8 sound_enabled = FALSE; + static bool8 sound_in_sync = TRUE; + static bool8 sound_enabled = FALSE; -static int buffer_size; -static int lag_master = 0; -static int lag = 0; + static int buffer_size; + static int lag_master = 0; + static int lag = 0; -static uint8 *landing_buffer = NULL; -static uint8 *shrink_buffer = NULL; + static uint8 *landing_buffer = NULL; + static uint8 *shrink_buffer = NULL; -static Resampler *resampler = NULL; + static Resampler *resampler = NULL; -static int32 reference_time; -static uint32 remainder; + static int32 reference_time; + static uint32 remainder; -static const int timing_hack_numerator = 256; -static int timing_hack_denominator = 256; -/* Set these to NTSC for now. Will change to PAL in S9xAPUTimingSetSpeedup - if necessary on game load. */ -static uint32 ratio_numerator = APU_NUMERATOR_NTSC; -static uint32 ratio_denominator = APU_DENOMINATOR_NTSC; + static const int timing_hack_numerator = 256; + static int timing_hack_denominator = 256; + /* Set these to NTSC for now. Will change to PAL in S9xAPUTimingSetSpeedup + if necessary on game load. */ + static uint32 ratio_numerator = APU_NUMERATOR_NTSC; + static uint32 ratio_denominator = APU_DENOMINATOR_NTSC; -static double dynamic_rate_multiplier = 1.0; -static bool8 using_threads = FALSE; + static double dynamic_rate_multiplier = 1.0; } namespace msu { -static int buffer_size; -static uint8 *landing_buffer = NULL; -static Resampler *resampler = NULL; -static int resample_buffer_size = -1; -static uint8 *resample_buffer = NULL; + static int buffer_size; + static uint8 *landing_buffer = NULL; + static Resampler *resampler = NULL; + static int resample_buffer_size = -1; + static uint8 *resample_buffer = NULL; } -#ifdef USE_THREADS -#include -static pthread_t worker_thread; - -static pthread_mutex_t thread_running_mutex; -static pthread_cond_t thread_running_cond; -static bool8 thread_running = FALSE; -static bool8 thread_exit = FALSE; - -static void *S9xAPUWorkerThread(void *arg) -{ - while (!thread_exit) - { - pthread_mutex_lock(&thread_running_mutex); - - while (!thread_running) - { - pthread_cond_wait(&thread_running_cond, &thread_running_mutex); - if (thread_exit) - break; - } - - pthread_mutex_unlock(&thread_running_mutex); - - S9xAPUExecute(); - SNES::dsp.synchronize(); - - pthread_mutex_lock(&thread_running_mutex); - thread_running = FALSE; - pthread_cond_broadcast(&thread_running_cond); - pthread_mutex_unlock(&thread_running_mutex); - } - - return NULL; -} - -static void S9xAPUThreadWait(void) -{ - pthread_mutex_lock(&thread_running_mutex); - while (thread_running) - { - pthread_cond_wait(&thread_running_cond, &thread_running_mutex); - } - pthread_mutex_unlock(&thread_running_mutex); -} - -static void S9xAPUThreadRun(void) -{ - pthread_mutex_lock(&thread_running_mutex); - thread_running++; - pthread_cond_broadcast(&thread_running_cond); - pthread_mutex_unlock(&thread_running_mutex); -} - -static void S9xAPUThreadInit(void) -{ - pthread_cond_init(&thread_running_cond, NULL); - pthread_mutex_init(&thread_running_mutex, NULL); - thread_running = TRUE; - pthread_create(&worker_thread, NULL, S9xAPUWorkerThread, NULL); -} - -static void S9xAPUThreadDeinit(void) -{ - S9xAPUThreadWait(); - thread_exit = TRUE; - S9xAPUThreadRun(); - pthread_join(worker_thread, NULL); - pthread_cond_destroy(&thread_running_cond); - pthread_mutex_destroy(&thread_running_mutex); -} -#endif - static void EightBitize (uint8 *, int); static void DeStereo (uint8 *, int); static void ReverseStereo (uint8 *, int); @@ -337,574 +264,522 @@ static inline int S9xAPUGetClockRemainder (int32); static void EightBitize (uint8 *buffer, int sample_count) { - uint8 *buf8 = (uint8 *) buffer; - int16 *buf16 = (int16 *) buffer; + uint8 *buf8 = (uint8 *) buffer; + int16 *buf16 = (int16 *) buffer; - for (int i = 0; i < sample_count; i++) - buf8[i] = (uint8) ((buf16[i] / 256) + 128); + for (int i = 0; i < sample_count; i++) + buf8[i] = (uint8) ((buf16[i] / 256) + 128); } static void DeStereo (uint8 *buffer, int sample_count) { - int16 *buf = (int16 *) buffer; - int32 s1, s2; + int16 *buf = (int16 *) buffer; + int32 s1, s2; - for (int i = 0; i < (sample_count >> 1); i++) - { - s1 = (int32) buf[2 * i]; - s2 = (int32) buf[2 * i + 1]; - buf[i] = (int16) ((s1 + s2) >> 1); - } + for (int i = 0; i < (sample_count >> 1); i++) + { + s1 = (int32) buf[2 * i]; + s2 = (int32) buf[2 * i + 1]; + buf[i] = (int16) ((s1 + s2) >> 1); + } } static void ReverseStereo (uint8 *src_buffer, int sample_count) { - int16 *buffer = (int16 *) src_buffer; + int16 *buffer = (int16 *) src_buffer; - for (int i = 0; i < sample_count; i += 2) - { - buffer[i + 1] ^= buffer[i]; - buffer[i] ^= buffer[i + 1]; - buffer[i + 1] ^= buffer[i]; - } + for (int i = 0; i < sample_count; i += 2) + { + buffer[i + 1] ^= buffer[i]; + buffer[i] ^= buffer[i + 1]; + buffer[i + 1] ^= buffer[i]; + } } bool8 S9xMixSamples (uint8 *buffer, int sample_count) { - static int shrink_buffer_size = -1; - uint8 *dest; + static int shrink_buffer_size = -1; + uint8 *dest; - if (!Settings.SixteenBitSound || !Settings.Stereo) - { - /* We still need both stereo samples for generating the mono sample */ - if (!Settings.Stereo) - sample_count <<= 1; + if (!Settings.SixteenBitSound || !Settings.Stereo) + { + /* We still need both stereo samples for generating the mono sample */ + if (!Settings.Stereo) + sample_count <<= 1; - /* We still have to generate 16-bit samples for bit-dropping, too */ - if (shrink_buffer_size < (sample_count << 1)) - { - delete[] spc::shrink_buffer; - spc::shrink_buffer = new uint8[sample_count << 1]; - shrink_buffer_size = sample_count << 1; - } + /* We still have to generate 16-bit samples for bit-dropping, too */ + if (shrink_buffer_size < (sample_count << 1)) + { + delete[] spc::shrink_buffer; + spc::shrink_buffer = new uint8[sample_count << 1]; + shrink_buffer_size = sample_count << 1; + } - dest = spc::shrink_buffer; - } - else - dest = buffer; + dest = spc::shrink_buffer; + } + else + dest = buffer; - if (Settings.MSU1 && msu::resample_buffer_size < (sample_count << 1)) - { - delete[] msu::resample_buffer; - msu::resample_buffer = new uint8[sample_count << 1]; - msu::resample_buffer_size = sample_count << 1; - } + if (Settings.MSU1 && msu::resample_buffer_size < (sample_count << 1)) + { + delete[] msu::resample_buffer; + msu::resample_buffer = new uint8[sample_count << 1]; + msu::resample_buffer_size = sample_count << 1; + } - if (Settings.Mute) - { - memset(dest, 0, sample_count << 1); - spc::resampler->clear(); + if (Settings.Mute) + { + memset(dest, 0, sample_count << 1); + spc::resampler->clear(); - if(Settings.MSU1) - msu::resampler->clear(); + if(Settings.MSU1) + msu::resampler->clear(); - return (FALSE); - } - else - { - if (spc::resampler->avail() >= (sample_count + spc::lag)) - { - spc::resampler->read((short *) dest, sample_count); - if (spc::lag == spc::lag_master) - spc::lag = 0; + return (FALSE); + } + else + { + if (spc::resampler->avail() >= (sample_count + spc::lag)) + { + spc::resampler->read((short *) dest, sample_count); + if (spc::lag == spc::lag_master) + spc::lag = 0; - if (Settings.MSU1) - { - if (msu::resampler->avail() >= sample_count) - { - msu::resampler->read((short *)msu::resample_buffer, sample_count); - for (int i = 0; i < sample_count; ++i) - *((int16*)(dest+(i * 2))) += *((int16*)(msu::resample_buffer +(i * 2))); - } - else // should never occur - assert(0); - } - } - else - { - memset(buffer, (Settings.SixteenBitSound ? 0 : 128), (sample_count << (Settings.SixteenBitSound ? 1 : 0)) >> (Settings.Stereo ? 0 : 1)); - if (spc::lag == 0) - spc::lag = spc::lag_master; + if (Settings.MSU1) + { + if (msu::resampler->avail() >= sample_count) + { + msu::resampler->read((short *)msu::resample_buffer, sample_count); + for (int i = 0; i < sample_count; ++i) + *((int16*)(dest+(i * 2))) += *((int16*)(msu::resample_buffer +(i * 2))); + } + else // should never occur + assert(0); + } + } + else + { + memset(buffer, (Settings.SixteenBitSound ? 0 : 128), (sample_count << (Settings.SixteenBitSound ? 1 : 0)) >> (Settings.Stereo ? 0 : 1)); + if (spc::lag == 0) + spc::lag = spc::lag_master; - return (FALSE); - } - } + return (FALSE); + } + } - if (Settings.ReverseStereo && Settings.Stereo) - ReverseStereo(dest, sample_count); + if (Settings.ReverseStereo && Settings.Stereo) + ReverseStereo(dest, sample_count); - if (!Settings.Stereo || !Settings.SixteenBitSound) - { - if (!Settings.Stereo) - { - DeStereo(dest, sample_count); - sample_count >>= 1; - } + if (!Settings.Stereo || !Settings.SixteenBitSound) + { + if (!Settings.Stereo) + { + DeStereo(dest, sample_count); + sample_count >>= 1; + } - if (!Settings.SixteenBitSound) - EightBitize(dest, sample_count); + if (!Settings.SixteenBitSound) + EightBitize(dest, sample_count); - memcpy(buffer, dest, (sample_count << (Settings.SixteenBitSound ? 1 : 0))); - } + memcpy(buffer, dest, (sample_count << (Settings.SixteenBitSound ? 1 : 0))); + } - return (TRUE); + return (TRUE); } int S9xGetSampleCount (void) { - return (spc::resampler->avail() >> (Settings.Stereo ? 0 : 1)); + return (spc::resampler->avail() >> (Settings.Stereo ? 0 : 1)); } /* TODO: Attach */ void S9xFinalizeSamples (void) { - bool drop_current_msu1_samples = true; + bool drop_current_msu1_samples = true; - if (!Settings.Mute) - { - drop_current_msu1_samples = false; + if (!Settings.Mute) + { + drop_current_msu1_samples = false; - if (!spc::resampler->push((short *)spc::landing_buffer, SNES::dsp.spc_dsp.sample_count())) - { - /* We weren't able to process the entire buffer. Potential overrun. */ - spc::sound_in_sync = FALSE; + if (!spc::resampler->push((short *)spc::landing_buffer, SNES::dsp.spc_dsp.sample_count())) + { + /* We weren't able to process the entire buffer. Potential overrun. */ + spc::sound_in_sync = FALSE; - if (Settings.SoundSync && !Settings.TurboMode) - return; + if (Settings.SoundSync && !Settings.TurboMode) + return; - // since we drop the current dsp samples we also want to drop generated msu1 samples - drop_current_msu1_samples = true; - } - } + // since we drop the current dsp samples we also want to drop generated msu1 samples + drop_current_msu1_samples = true; + } + } - // only generate msu1 if we really consumed the dsp samples (sample_count() resets at end of function), - // otherwise we will generate multiple times for the same samples - so this needs to be after all early - // function returns - if (Settings.MSU1) - { - // generate the same number of msu1 samples as dsp samples were generated - S9xMSU1SetOutput((int16 *)msu::landing_buffer, msu::buffer_size); - S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count()); - if (!drop_current_msu1_samples && !msu::resampler->push((short *)msu::landing_buffer, S9xMSU1Samples())) - { - // should not occur, msu buffer is larger and we drop msu samples if spc buffer overruns - assert(0); - } - } + // only generate msu1 if we really consumed the dsp samples (sample_count() resets at end of function), + // otherwise we will generate multiple times for the same samples - so this needs to be after all early + // function returns + if (Settings.MSU1) + { + // generate the same number of msu1 samples as dsp samples were generated + S9xMSU1SetOutput((int16 *)msu::landing_buffer, msu::buffer_size); + S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count()); + if (!drop_current_msu1_samples && !msu::resampler->push((short *)msu::landing_buffer, S9xMSU1Samples())) + { + // should not occur, msu buffer is larger and we drop msu samples if spc buffer overruns + assert(0); + } + } - if (!Settings.SoundSync || Settings.TurboMode || Settings.Mute) - spc::sound_in_sync = TRUE; - else - if (spc::resampler->space_empty() >= spc::resampler->space_filled()) - spc::sound_in_sync = TRUE; - else - spc::sound_in_sync = FALSE; + if (!Settings.SoundSync || Settings.TurboMode || Settings.Mute) + spc::sound_in_sync = TRUE; + else + if (spc::resampler->space_empty() >= spc::resampler->space_filled()) + spc::sound_in_sync = TRUE; + else + spc::sound_in_sync = FALSE; - SNES::dsp.spc_dsp.set_output((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size); + SNES::dsp.spc_dsp.set_output((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size); } void S9xLandSamples (void) { - if (spc::sa_callback != NULL) - spc::sa_callback(spc::extra_data); - else - S9xFinalizeSamples(); + if (spc::sa_callback != NULL) + spc::sa_callback(spc::extra_data); + else + S9xFinalizeSamples(); } void S9xClearSamples (void) { - spc::resampler->clear(); - if (Settings.MSU1) - msu::resampler->clear(); - spc::lag = spc::lag_master; + spc::resampler->clear(); + if (Settings.MSU1) + msu::resampler->clear(); + spc::lag = spc::lag_master; } bool8 S9xSyncSound (void) { - if (!Settings.SoundSync || spc::sound_in_sync) - return (TRUE); + if (!Settings.SoundSync || spc::sound_in_sync) + return (TRUE); - S9xLandSamples(); + S9xLandSamples(); - return (spc::sound_in_sync); + return (spc::sound_in_sync); } void S9xSetSamplesAvailableCallback (apu_callback callback, void *data) { - spc::sa_callback = callback; - spc::extra_data = data; + spc::sa_callback = callback; + spc::extra_data = data; } void S9xUpdateDynamicRate (int avail, int buffer_size) { - spc::dynamic_rate_multiplier = 1.0 + (Settings.DynamicRateLimit * (buffer_size - 2 * avail)) / - (double)(1000 * buffer_size); + spc::dynamic_rate_multiplier = 1.0 + (Settings.DynamicRateLimit * (buffer_size - 2 * avail)) / + (double)(1000 * buffer_size); - UpdatePlaybackRate(); + UpdatePlaybackRate(); } -static inline void UpdatePlaybackRate (void) +static void UpdatePlaybackRate (void) { - if (Settings.SoundInputRate == 0) - Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE; + if (Settings.SoundInputRate == 0) + Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE; - double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator); + double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator); - if (Settings.DynamicRateControl) - { - time_ratio *= spc::dynamic_rate_multiplier; - } + if (Settings.DynamicRateControl) + { + time_ratio *= spc::dynamic_rate_multiplier; + } - spc::resampler->time_ratio(time_ratio); + spc::resampler->time_ratio(time_ratio); - if (Settings.MSU1) - { - time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0); - msu::resampler->time_ratio(time_ratio); - } + if (Settings.MSU1) + { + time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0); + msu::resampler->time_ratio(time_ratio); + } } bool8 S9xInitSound (int buffer_ms, int lag_ms) { - // buffer_ms : buffer size given in millisecond - // lag_ms : allowable time-lag given in millisecond + // buffer_ms : buffer size given in millisecond + // lag_ms : allowable time-lag given in millisecond - int sample_count = buffer_ms * 32040 / 1000; - int lag_sample_count = lag_ms * 32040 / 1000; + int sample_count = buffer_ms * 32040 / 1000; + int lag_sample_count = lag_ms * 32040 / 1000; - spc::lag_master = lag_sample_count; - if (Settings.Stereo) - spc::lag_master <<= 1; - spc::lag = spc::lag_master; + spc::lag_master = lag_sample_count; + if (Settings.Stereo) + spc::lag_master <<= 1; + spc::lag = spc::lag_master; - if (sample_count < APU_MINIMUM_SAMPLE_COUNT) - sample_count = APU_MINIMUM_SAMPLE_COUNT; + if (sample_count < APU_MINIMUM_SAMPLE_COUNT) + sample_count = APU_MINIMUM_SAMPLE_COUNT; - spc::buffer_size = sample_count << 2; - msu::buffer_size = (int)((sample_count << 2) * 1.5); // Always 16-bit, Stereo; 1.5 to never overflow before dsp buffer + spc::buffer_size = sample_count << 2; + msu::buffer_size = (int)((sample_count << 2) * 1.5); // Always 16-bit, Stereo; 1.5 to never overflow before dsp buffer - printf("Sound buffer size: %d (%d samples)\n", spc::buffer_size, sample_count); + printf("Sound buffer size: %d (%d samples)\n", spc::buffer_size, sample_count); - if (spc::landing_buffer) - delete[] spc::landing_buffer; - spc::landing_buffer = new uint8[spc::buffer_size * 2]; - if (!spc::landing_buffer) - return (FALSE); - if (msu::landing_buffer) - delete[] msu::landing_buffer; - msu::landing_buffer = new uint8[msu::buffer_size * 2]; - if (!msu::landing_buffer) - return (FALSE); + if (spc::landing_buffer) + delete[] spc::landing_buffer; + spc::landing_buffer = new uint8[spc::buffer_size * 2]; + if (!spc::landing_buffer) + return (FALSE); + if (msu::landing_buffer) + delete[] msu::landing_buffer; + msu::landing_buffer = new uint8[msu::buffer_size * 2]; + if (!msu::landing_buffer) + return (FALSE); - /* The resampler and spc unit use samples (16-bit short) as - arguments. Use 2x in the resampler for buffer leveling with SoundSync */ - if (!spc::resampler) - { - spc::resampler = new HermiteResampler(spc::buffer_size >> (Settings.SoundSync ? 0 : 1)); - if (!spc::resampler) - { - delete[] spc::landing_buffer; - return (FALSE); - } - } - else - spc::resampler->resize(spc::buffer_size >> (Settings.SoundSync ? 0 : 1)); + /* The resampler and spc unit use samples (16-bit short) as + arguments. Use 2x in the resampler for buffer leveling with SoundSync */ + if (!spc::resampler) + { + spc::resampler = new HermiteResampler(spc::buffer_size >> (Settings.SoundSync ? 0 : 1)); + if (!spc::resampler) + { + delete[] spc::landing_buffer; + return (FALSE); + } + } + else + spc::resampler->resize(spc::buffer_size >> (Settings.SoundSync ? 0 : 1)); - if (!msu::resampler) - { - msu::resampler = new HermiteResampler(msu::buffer_size); - if (!msu::resampler) - { - delete[] msu::landing_buffer; - return (FALSE); - } - } - else - msu::resampler->resize(msu::buffer_size); + if (!msu::resampler) + { + msu::resampler = new HermiteResampler(msu::buffer_size); + if (!msu::resampler) + { + delete[] msu::landing_buffer; + return (FALSE); + } + } + else + msu::resampler->resize(msu::buffer_size); - SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size); + SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size); - UpdatePlaybackRate(); + UpdatePlaybackRate(); - spc::sound_enabled = S9xOpenSoundDevice(); + spc::sound_enabled = S9xOpenSoundDevice(); -#ifdef USE_THREADS - if (spc::using_threads) - { - S9xAPUThreadDeinit(); - } - - spc::using_threads = Settings.ThreadedAPU & spc::sound_enabled; - - if (spc::using_threads) - { - printf ("Using threaded APU.\n"); - S9xAPUThreadInit(); - } -#endif - - return (spc::sound_enabled); + return (spc::sound_enabled); } void S9xSetSoundControl (uint8 voice_switch) { - SNES::dsp.spc_dsp.set_stereo_switch (voice_switch << 8 | voice_switch); + SNES::dsp.spc_dsp.set_stereo_switch (voice_switch << 8 | voice_switch); } void S9xSetSoundMute (bool8 mute) { - Settings.Mute = mute; - if (!spc::sound_enabled) - Settings.Mute = TRUE; + Settings.Mute = mute; + if (!spc::sound_enabled) + Settings.Mute = TRUE; } void S9xDumpSPCSnapshot (void) { - SNES::dsp.spc_dsp.dump_spc_snapshot(); + SNES::dsp.spc_dsp.dump_spc_snapshot(); } static void SPCSnapshotCallback (void) { - S9xSPCDump(S9xGetFilenameInc((".spc"), SPC_DIR)); - printf("Dumped key-on triggered spc snapshot.\n"); + S9xSPCDump(S9xGetFilenameInc((".spc"), SPC_DIR)); + printf("Dumped key-on triggered spc snapshot.\n"); } bool8 S9xInitAPU (void) { - spc::landing_buffer = NULL; - spc::shrink_buffer = NULL; - spc::resampler = NULL; - msu::resampler = NULL; + spc::landing_buffer = NULL; + spc::shrink_buffer = NULL; + spc::resampler = NULL; + msu::resampler = NULL; - return (TRUE); + return (TRUE); } void S9xDeinitAPU (void) { - if (spc::using_threads) - { - S9xAPUThreadDeinit(); - } + if (spc::resampler) + { + delete spc::resampler; + spc::resampler = NULL; + } - if (spc::resampler) - { - delete spc::resampler; - spc::resampler = NULL; - } + if (spc::landing_buffer) + { + delete[] spc::landing_buffer; + spc::landing_buffer = NULL; + } - if (spc::landing_buffer) - { - delete[] spc::landing_buffer; - spc::landing_buffer = NULL; - } + if (spc::shrink_buffer) + { + delete[] spc::shrink_buffer; + spc::shrink_buffer = NULL; + } - if (spc::shrink_buffer) - { - delete[] spc::shrink_buffer; - spc::shrink_buffer = NULL; - } + if (msu::resampler) + { + delete msu::resampler; + msu::resampler = NULL; + } - if (msu::resampler) - { - delete msu::resampler; - msu::resampler = NULL; - } + if (msu::landing_buffer) + { + delete[] msu::landing_buffer; + msu::landing_buffer = NULL; + } - if (msu::landing_buffer) - { - delete[] msu::landing_buffer; - msu::landing_buffer = NULL; - } + if (msu::resample_buffer) + { + delete[] msu::resample_buffer; + msu::resample_buffer = NULL; + } - if (msu::resample_buffer) - { - delete[] msu::resample_buffer; - msu::resample_buffer = NULL; - } - - S9xMSU1DeInit(); + S9xMSU1DeInit(); } static inline int S9xAPUGetClock (int32 cpucycles) { - return (spc::ratio_numerator * (cpucycles - spc::reference_time) + spc::remainder) / - spc::ratio_denominator; + return (spc::ratio_numerator * (cpucycles - spc::reference_time) + spc::remainder) / + spc::ratio_denominator; } static inline int S9xAPUGetClockRemainder (int32 cpucycles) { - return (spc::ratio_numerator * (cpucycles - spc::reference_time) + spc::remainder) % - spc::ratio_denominator; -} - -static inline void S9xAPUUpdateClock (void) -{ - SNES::smp.clock -= S9xAPUGetClock (CPU.Cycles); - spc::remainder = S9xAPUGetClockRemainder(CPU.Cycles); - S9xAPUSetReferenceTime(CPU.Cycles); + return (spc::ratio_numerator * (cpucycles - spc::reference_time) + spc::remainder) % + spc::ratio_denominator; } uint8 S9xAPUReadPort (int port) { -#ifdef USE_THREADS - if (spc::using_threads) - { - S9xAPUThreadWait(); - } -#endif - S9xAPUUpdateClock(); - S9xAPUExecute (); - return ((uint8) SNES::smp.port_read (port & 3)); + S9xAPUExecute (); + return ((uint8) SNES::smp.port_read (port & 3)); } void S9xAPUWritePort (int port, uint8 byte) { -#ifdef USE_THREADS - if (spc::using_threads) - { - S9xAPUThreadWait(); - } -#endif - S9xAPUUpdateClock(); - S9xAPUExecute (); - SNES::cpu.port_write (port & 3, byte); + S9xAPUExecute (); + SNES::cpu.port_write (port & 3, byte); } void S9xAPUSetReferenceTime (int32 cpucycles) { - spc::reference_time = cpucycles; + spc::reference_time = cpucycles; } void S9xAPUExecute (void) { - SNES::smp.enter (); + SNES::smp.clock -= S9xAPUGetClock (CPU.Cycles); + SNES::smp.enter (); + + spc::remainder = S9xAPUGetClockRemainder(CPU.Cycles); + + S9xAPUSetReferenceTime(CPU.Cycles); } void S9xAPUEndScanline (void) { -#ifdef USE_THREADS - if (spc::using_threads) - { - S9xAPUThreadWait(); + S9xAPUExecute(); + SNES::dsp.synchronize(); - if (SNES::dsp.spc_dsp.sample_count() >= APU_MINIMUM_SAMPLE_BLOCK || !spc::sound_in_sync) - S9xLandSamples(); - - S9xAPUUpdateClock(); - S9xAPUThreadRun(); - - return; - } -#endif - - S9xAPUUpdateClock(); - S9xAPUExecute(); - SNES::dsp.synchronize(); - - if (SNES::dsp.spc_dsp.sample_count() >= APU_MINIMUM_SAMPLE_BLOCK || !spc::sound_in_sync) - S9xLandSamples(); + if (SNES::dsp.spc_dsp.sample_count() >= APU_MINIMUM_SAMPLE_BLOCK || !spc::sound_in_sync) + S9xLandSamples(); } void S9xAPUTimingSetSpeedup (int ticks) { - if (ticks != 0) - printf("APU speedup hack: %d\n", ticks); + if (ticks != 0) + printf("APU speedup hack: %d\n", ticks); - spc::timing_hack_denominator = 256 - ticks; + spc::timing_hack_denominator = 256 - ticks; - spc::ratio_numerator = Settings.PAL ? APU_NUMERATOR_PAL : APU_NUMERATOR_NTSC; - spc::ratio_denominator = Settings.PAL ? APU_DENOMINATOR_PAL : APU_DENOMINATOR_NTSC; - spc::ratio_denominator = spc::ratio_denominator * spc::timing_hack_denominator / spc::timing_hack_numerator; + spc::ratio_numerator = Settings.PAL ? APU_NUMERATOR_PAL : APU_NUMERATOR_NTSC; + spc::ratio_denominator = Settings.PAL ? APU_DENOMINATOR_PAL : APU_DENOMINATOR_NTSC; + spc::ratio_denominator = spc::ratio_denominator * spc::timing_hack_denominator / spc::timing_hack_numerator; - UpdatePlaybackRate(); + UpdatePlaybackRate(); } void S9xResetAPU (void) { - spc::reference_time = 0; - spc::remainder = 0; + spc::reference_time = 0; + spc::remainder = 0; - SNES::cpu.reset (); - SNES::cpu.frequency = Settings.PAL ? PAL_MASTER_CLOCK : NTSC_MASTER_CLOCK; - SNES::smp.power (); - SNES::dsp.power (); - SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); - SNES::dsp.spc_dsp.set_spc_snapshot_callback(SPCSnapshotCallback); + SNES::cpu.reset (); + SNES::cpu.frequency = Settings.PAL ? PAL_MASTER_CLOCK : NTSC_MASTER_CLOCK; + SNES::smp.power (); + SNES::dsp.power (); + SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); + SNES::dsp.spc_dsp.set_spc_snapshot_callback(SPCSnapshotCallback); - spc::resampler->clear(); + spc::resampler->clear(); - if (Settings.MSU1) - msu::resampler->clear(); + if (Settings.MSU1) + msu::resampler->clear(); } void S9xSoftResetAPU (void) { - spc::reference_time = 0; - spc::remainder = 0; - SNES::cpu.reset (); - SNES::smp.reset (); - SNES::dsp.reset (); - SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); + spc::reference_time = 0; + spc::remainder = 0; + SNES::cpu.reset (); + SNES::smp.reset (); + SNES::dsp.reset (); + SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); - spc::resampler->clear(); + spc::resampler->clear(); - if (Settings.MSU1) - msu::resampler->clear(); + if (Settings.MSU1) + msu::resampler->clear(); } void S9xAPUSaveState (uint8 *block) { - uint8 *ptr = block; + uint8 *ptr = block; - SNES::smp.save_state (&ptr); - SNES::dsp.save_state (&ptr); + SNES::smp.save_state (&ptr); + SNES::dsp.save_state (&ptr); - SNES::set_le32(ptr, spc::reference_time); - ptr += sizeof(int32); - SNES::set_le32(ptr, spc::remainder); - ptr += sizeof(int32); - SNES::set_le32(ptr, SNES::dsp.clock); - ptr += sizeof(int32); - memcpy (ptr, SNES::cpu.registers, 4); - ptr += sizeof(int32); + SNES::set_le32(ptr, spc::reference_time); + ptr += sizeof(int32); + SNES::set_le32(ptr, spc::remainder); + ptr += sizeof(int32); + SNES::set_le32(ptr, SNES::dsp.clock); + ptr += sizeof(int32); + memcpy (ptr, SNES::cpu.registers, 4); + ptr += sizeof(int32); - memset (ptr, 0, SPC_SAVE_STATE_BLOCK_SIZE-(ptr-block)); + memset (ptr, 0, SPC_SAVE_STATE_BLOCK_SIZE-(ptr-block)); } void S9xAPULoadState (uint8 *block) { - uint8 *ptr = block; + uint8 *ptr = block; - SNES::smp.load_state (&ptr); - SNES::dsp.load_state (&ptr); + SNES::smp.load_state (&ptr); + SNES::dsp.load_state (&ptr); - spc::reference_time = SNES::get_le32(ptr); - ptr += sizeof(int32); - spc::remainder = SNES::get_le32(ptr); - ptr += sizeof(int32); - SNES::dsp.clock = SNES::get_le32(ptr); - ptr += sizeof(int32); - memcpy (SNES::cpu.registers, ptr, 4); + spc::reference_time = SNES::get_le32(ptr); + ptr += sizeof(int32); + spc::remainder = SNES::get_le32(ptr); + ptr += sizeof(int32); + SNES::dsp.clock = SNES::get_le32(ptr); + ptr += sizeof(int32); + memcpy (SNES::cpu.registers, ptr, 4); } static void to_var_from_buf (uint8 **buf, void *var, size_t size) { - memcpy(var, *buf, size); - *buf += size; + memcpy(var, *buf, size); + *buf += size; } #undef IF_0_THEN_256 @@ -953,10 +828,10 @@ void S9xAPULoadBlarggState(uint8 *oldblock) uint8_t divider[3], counter[3]; for ( int i = 0; i < 3; i++ ) { - next_time[i] = copier.copy_int( 0, sizeof(uint16_t) ); - divider[i] = copier.copy_int( 0, sizeof(uint8_t) ); - counter[i] = copier.copy_int( 0, sizeof(uint8_t) ); - copier.extra(); + next_time[i] = copier.copy_int( 0, sizeof(uint16_t) ); + divider[i] = copier.copy_int( 0, sizeof(uint8_t) ); + counter[i] = copier.copy_int( 0, sizeof(uint8_t) ); + copier.extra(); } // construct timers out of available parts from blargg smp SNES::smp.timer0.enable = regs[1] >> 0 & 1; // regs[1] = CONTROL @@ -1014,28 +889,28 @@ void S9xAPULoadBlarggState(uint8 *oldblock) bool8 S9xSPCDump (const char *filename) { - FILE *fs; - uint8 buf[SPC_FILE_SIZE]; - size_t ignore; + FILE *fs; + uint8 buf[SPC_FILE_SIZE]; + size_t ignore; - fs = fopen(filename, "wb"); - if (!fs) - return (FALSE); + fs = fopen(filename, "wb"); + if (!fs) + return (FALSE); - S9xSetSoundMute(TRUE); + S9xSetSoundMute(TRUE); - SNES::smp.save_spc (buf); + SNES::smp.save_spc (buf); - ignore = fwrite (buf, SPC_FILE_SIZE, 1, fs); + ignore = fwrite (buf, SPC_FILE_SIZE, 1, fs); - if (ignore == 0) - { - fprintf (stderr, "Couldn't write file %s.\n", filename); - } + if (ignore == 0) + { + fprintf (stderr, "Couldn't write file %s.\n", filename); + } - fclose(fs); + fclose(fs); - S9xSetSoundMute(FALSE); + S9xSetSoundMute(FALSE); - return (TRUE); + return (TRUE); } diff --git a/gtk/configure.ac b/gtk/configure.ac index 4454fca8..4cd190bf 100644 --- a/gtk/configure.ac +++ b/gtk/configure.ac @@ -66,12 +66,6 @@ AC_ARG_WITH(xrandr, [], [with_xrandr=yes]) -AC_ARG_WITH(pthreads, - [AS_HELP_STRING([--with(out)-pthreads], - [Enable POSIX Threads (default: with)])], - [], - [with_pthreads=yes]) - AC_ARG_WITH(portaudio, [AS_HELP_STRING([--with(out)-portaudio], [Enable PortAudio sound driver support (default: with)])], @@ -274,17 +268,6 @@ if test yes = "$with_oss" ; then ]) fi -THREADS=0 -if test yes = "$with_pthreads" ; then - AC_CHECK_HEADER(pthread.h, [ - CFLAGS="$CFLAGS -DUSE_THREADS" - LIBS="$LIBS -lpthread" - THREADS=1 - ],[ - echo "Cannot find pthreads. Disabling threading." - ]) -fi - ALSA=0 ALSA_CFLAGS="" ALSA_LIBS="" diff --git a/gtk/src/gtk_config.cpp b/gtk/src/gtk_config.cpp index 1da0e386..54393e59 100644 --- a/gtk/src/gtk_config.cpp +++ b/gtk/src/gtk_config.cpp @@ -255,7 +255,6 @@ Snes9xConfig::load_defaults (void) Settings.SoundSync = 1; Settings.DynamicRateControl = 1; Settings.DynamicRateLimit = 5; - Settings.ThreadedAPU = FALSE; Settings.HDMATimingHack = 100; Settings.ApplyCheats = 1; @@ -407,7 +406,6 @@ Snes9xConfig::save_config_file (void) xml_out_int (xml, "sound_sync", Settings.SoundSync); xml_out_int (xml, "dynamic_rate_control", Settings.DynamicRateControl); xml_out_int (xml, "dynamic_rate_limit", Settings.DynamicRateLimit); - xml_out_int (xml, "threaded_apu", Settings.ThreadedAPU); /* Snes9X core-stored variables */ xml_out_int (xml, "transparency", Settings.Transparency); @@ -679,10 +677,6 @@ Snes9xConfig::set_option (const char *name, const char *value) Settings.DynamicRateLimit = atoi (value); Settings.DynamicRateLimit = CLAMP (Settings.DynamicRateLimit, 1, 1000); } - else if (!strcasecmp (name, "threaded_apu")) - { - Settings.ThreadedAPU = atoi (value); - } else if (!strcasecmp (name, "gaussian_interpolation")) { } diff --git a/gtk/src/gtk_preferences.cpp b/gtk/src/gtk_preferences.cpp index 130673e8..85794c85 100644 --- a/gtk/src/gtk_preferences.cpp +++ b/gtk/src/gtk_preferences.cpp @@ -678,7 +678,6 @@ Snes9xPreferences::move_settings_to_dialog (void) set_check ("sync_sound", Settings.SoundSync); set_check ("dynamic_rate_control", Settings.DynamicRateControl); set_spin ("dynamic_rate_limit", Settings.DynamicRateLimit / 1000.0); - set_check ("threaded_apu", Settings.ThreadedAPU); set_spin ("rewind_buffer_size", config->rewind_buffer_size); set_spin ("rewind_granularity", config->rewind_granularity); @@ -771,8 +770,7 @@ Snes9xPreferences::get_settings_from_dialog (void) (7 - (get_combo ("playback_combo")))) || (config->sound_input_rate != get_slider ("sound_input_rate")) || (Settings.SoundSync != get_check ("sync_sound")) || - (Settings.DynamicRateControl != get_check ("dynamic_rate_control")) || - (Settings.ThreadedAPU != get_check ("threaded_apu")) + (Settings.DynamicRateControl != get_check ("dynamic_rate_control")) ) { sound_needs_restart = 1; @@ -838,7 +836,6 @@ Snes9xPreferences::get_settings_from_dialog (void) config->mute_sound_turbo = get_check ("mute_sound_turbo_check"); Settings.DynamicRateControl = get_check ("dynamic_rate_control"); Settings.DynamicRateLimit = (uint32) (get_spin ("dynamic_rate_limit") * 1000); - Settings.ThreadedAPU = get_check ("threaded_apu"); store_ntsc_settings (); config->ntsc_scanline_intensity = get_combo ("ntsc_scanline_intensity"); diff --git a/gtk/src/snes9x.ui b/gtk/src/snes9x.ui index ab5f3322..a4c038bb 100644 --- a/gtk/src/snes9x.ui +++ b/gtk/src/snes9x.ui @@ -4016,21 +4016,7 @@ 1 - - - Threaded sound processors - True - True - False - Tries to run the S-SMP and S-DSP on a separate thread - True - - - False - False - 2 - - + Dynamic rate control @@ -4043,7 +4029,7 @@ False False - 3 + 2 @@ -4060,7 +4046,7 @@ False False - 4 + 3 @@ -4076,7 +4062,7 @@ False False - 5 + 4 @@ -4092,7 +4078,7 @@ False False - 6 + 5 @@ -4312,7 +4298,7 @@ False True - 7 + 6 diff --git a/snes9x.cpp b/snes9x.cpp index f3904797..7fab3827 100644 --- a/snes9x.cpp +++ b/snes9x.cpp @@ -424,7 +424,6 @@ void S9xLoadConfigFiles (char **argv, int argc) Settings.Mute = conf.GetBool("Sound::Mute", false); Settings.DynamicRateControl = conf.GetBool("Sound::DynamicRateControl", false); Settings.DynamicRateLimit = conf.GetInt ("Sound::DynamicRateLimit", 5); - Settings.ThreadedAPU = conf.GetBool("Sound::ThreadedAPU", false); // Display diff --git a/snes9x.h b/snes9x.h index d9884479..5f439768 100644 --- a/snes9x.h +++ b/snes9x.h @@ -409,7 +409,6 @@ struct SSettings bool8 Mute; bool8 DynamicRateControl; int32 DynamicRateLimit; /* Multiplied by 1000 */ - bool8 ThreadedAPU; bool8 SupportHiRes; bool8 Transparency;