From fdd94352495ef30fea5f67c3025ea46c838be2fd Mon Sep 17 00:00:00 2001 From: newsie-oss <58197643+newsie-oss@users.noreply.github.com> Date: Sat, 21 Dec 2019 12:18:02 -0500 Subject: [PATCH] Libretro: Sample rate option + static linking (#734) * [libretro] use audio batch * [libretro] variable sound rate * [libretro] mingw static libs * [libretro] mingw xp support --- Libretro/LibretroSoundManager.h | 8 ++++---- Libretro/Makefile | 2 +- Libretro/libretro.cpp | 30 +++++++++++++++++++++++++++--- Utilities/stb_vorbis.cpp | 2 +- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Libretro/LibretroSoundManager.h b/Libretro/LibretroSoundManager.h index 469a8e64..a545830d 100644 --- a/Libretro/LibretroSoundManager.h +++ b/Libretro/LibretroSoundManager.h @@ -7,7 +7,7 @@ class LibretroSoundManager : public IAudioDevice { private: - retro_audio_sample_t _sendAudioSample = nullptr; + retro_audio_sample_batch_t _sendAudioSample = nullptr; bool _skipMode = false; shared_ptr _console; @@ -27,13 +27,13 @@ public: virtual void PlayBuffer(int16_t *soundBuffer, uint32_t sampleCount, uint32_t sampleRate, bool isStereo) override { if(!_skipMode && _sendAudioSample) { - for(uint32_t i = 0; i < sampleCount; i++) { - _sendAudioSample(soundBuffer[i*2], soundBuffer[i*2+1]); + for(uint32_t total = 0; total < sampleCount; ) { + total += _sendAudioSample(soundBuffer + total*2, sampleCount - total); } } } - void SetSendAudioSample(retro_audio_sample_t sendAudioSample) + void SetSendAudioSample(retro_audio_sample_batch_t sendAudioSample) { _sendAudioSample = sendAudioSample; } diff --git a/Libretro/Makefile b/Libretro/Makefile index c1f44890..3cc61784 100644 --- a/Libretro/Makefile +++ b/Libretro/Makefile @@ -253,7 +253,7 @@ else CC ?= gcc CXX ?= g++ TARGET := $(TARGET_NAME)_libretro.dll - SHARED := -shared -s -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined + SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined endif LDFLAGS += $(LIBM) diff --git a/Libretro/libretro.cpp b/Libretro/libretro.cpp index 22fb0dac..0c9f0444 100644 --- a/Libretro/libretro.cpp +++ b/Libretro/libretro.cpp @@ -47,6 +47,7 @@ static int32_t _saveStateSize = -1; static struct retro_memory_descriptor _descriptors[3]; static struct retro_memory_map _memoryMap; static bool _shiftButtonsClockwise = false; +static int32_t _audioSampleRate = 44100; //Include game database as a byte array (representing the MesenDB.txt file) #include "MesenDB.inc" @@ -78,6 +79,7 @@ static constexpr const char* MesenReduceDmcPopping = "mesen_reduce_dmc_popping"; static constexpr const char* MesenSwapDutyCycle = "mesen_swap_duty_cycle"; static constexpr const char* MesenDisableNoiseModeFlag = "mesen_disable_noise_mode_flag"; static constexpr const char* MesenShiftButtonsClockwise = "mesen_shift_buttons_clockwise"; +static constexpr const char* MesenAudioSampleRate = "mesen_audio_sample_rate"; uint32_t defaultPalette[0x40] { 0xFF666666, 0xFF002A88, 0xFF1412A7, 0xFF3B00A4, 0xFF5C007E, 0xFF6E0040, 0xFF6C0600, 0xFF561D00, 0xFF333500, 0xFF0B4800, 0xFF005200, 0xFF004F08, 0xFF00404D, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFADADAD, 0xFF155FD9, 0xFF4240FF, 0xFF7527FE, 0xFFA01ACC, 0xFFB71E7B, 0xFFB53120, 0xFF994E00, 0xFF6B6D00, 0xFF388700, 0xFF0C9300, 0xFF008F32, 0xFF007C8D, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFF64B0FF, 0xFF9290FF, 0xFFC676FF, 0xFFF36AFF, 0xFFFE6ECC, 0xFFFE8170, 0xFFEA9E22, 0xFFBCBE00, 0xFF88D800, 0xFF5CE430, 0xFF45E082, 0xFF48CDDE, 0xFF4F4F4F, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFFC0DFFF, 0xFFD3D2FF, 0xFFE8C8FF, 0xFFFBC2FF, 0xFFFEC4EA, 0xFFFECCC5, 0xFFF7D8A5, 0xFFE4E594, 0xFFCFEF96, 0xFFBDF4AB, 0xFFB3F3CC, 0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000 }; uint32_t unsaturatedPalette[0x40] { 0xFF6B6B6B, 0xFF001E87, 0xFF1F0B96, 0xFF3B0C87, 0xFF590D61, 0xFF5E0528, 0xFF551100, 0xFF461B00, 0xFF303200, 0xFF0A4800, 0xFF004E00, 0xFF004619, 0xFF003A58, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFB2B2B2, 0xFF1A53D1, 0xFF4835EE, 0xFF7123EC, 0xFF9A1EB7, 0xFFA51E62, 0xFFA52D19, 0xFF874B00, 0xFF676900, 0xFF298400, 0xFF038B00, 0xFF008240, 0xFF007891, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFF63ADFD, 0xFF908AFE, 0xFFB977FC, 0xFFE771FE, 0xFFF76FC9, 0xFFF5836A, 0xFFDD9C29, 0xFFBDB807, 0xFF84D107, 0xFF5BDC3B, 0xFF48D77D, 0xFF48CCCE, 0xFF555555, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFC4E3FE, 0xFFD7D5FE, 0xFFE6CDFE, 0xFFF9CAFE, 0xFFFEC9F0, 0xFFFED1C7, 0xFFF7DCAC, 0xFFE8E89C, 0xFFD1F29D, 0xFFBFF4B1, 0xFFB7F5CD, 0xFFB7F0EE, 0xFFBEBEBE, 0xFF000000, 0xFF000000 }; @@ -126,7 +128,7 @@ extern "C" { _console->GetSettings()->SetFlags(EmulationFlags::FdsAutoLoadDisk); _console->GetSettings()->SetFlags(EmulationFlags::AutoConfigureInput); - _console->GetSettings()->SetSampleRate(96000); + _console->GetSettings()->SetSampleRate(_audioSampleRate); _console->GetSettings()->SetAutoSaveOptions(0, false); _console->GetSettings()->SetRewindBufferSize(0); } @@ -169,6 +171,7 @@ extern "C" { { MesenRamState, "Default power-on state for RAM; All 0s (Default)|All 1s|Random Values" }, { MesenFdsAutoSelectDisk, "FDS: Automatically insert disks; disabled|enabled" }, { MesenFdsFastForwardLoad, "FDS: Fast forward while loading; disabled|enabled" }, + { MesenAudioSampleRate, "Sound Output Sample Rate; 11025|22050|44100|48000|96000|192000|384000" }, { NULL, NULL }, }; @@ -243,11 +246,11 @@ extern "C" { RETRO_API void retro_set_audio_sample(retro_audio_sample_t sendAudioSample) { - _soundManager->SetSendAudioSample(sendAudioSample); } RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t audioSampleBatch) { + _soundManager->SetSendAudioSample(audioSampleBatch); } RETRO_API void retro_set_input_poll(retro_input_poll_t pollInput) @@ -530,6 +533,23 @@ extern "C" { } } + if(readVariable(MesenAudioSampleRate, var)) { + int old_value = _audioSampleRate; + + _audioSampleRate = atoi(var.value); + + if(old_value != _audioSampleRate) { + _console->GetSettings()->SetSampleRate(_audioSampleRate); + + // switch when core actively running + if(_saveStateSize != -1) { + struct retro_system_av_info system_av_info; + retro_get_system_av_info(&system_av_info); + retroEnv(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &system_av_info); + } + } + } + auto getKeyCode = [=](int port, int retroKey) { return (port << 8) | (retroKey + 1); }; @@ -683,7 +703,11 @@ extern "C" { { std::stringstream ss; ss.write((char*)data, size); - return _console->GetSaveStateManager()->LoadState(ss, false); + + bool result = _console->GetSaveStateManager()->LoadState(ss, false); + if(result) + _console->GetSettings()->SetSampleRate(_audioSampleRate); + return result; } RETRO_API void retro_cheat_reset() diff --git a/Utilities/stb_vorbis.cpp b/Utilities/stb_vorbis.cpp index 40643261..655a737a 100644 --- a/Utilities/stb_vorbis.cpp +++ b/Utilities/stb_vorbis.cpp @@ -4621,7 +4621,7 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { FILE *f; -#if _WIN32 || _WIN64 +#if defined(_MSC_VER) || defined(__MINGW64__) fopen_s(&f, filename, "rb"); #else f = fopen(filename, "rb");