android: expose sound latency setting. default to auto
Issue #182 remove video Clipping option remove audio LimitFPS option
This commit is contained in:
parent
bceed97817
commit
58c936fa6c
|
@ -40,7 +40,6 @@ Option<bool> AutoSavestate("Dreamcast.AutoSavestate");
|
||||||
|
|
||||||
// Sound
|
// Sound
|
||||||
|
|
||||||
Option<bool> LimitFPS("aica.LimitFPS", true);
|
|
||||||
Option<bool> DSPEnabled("aica.DSPEnabled", false);
|
Option<bool> DSPEnabled("aica.DSPEnabled", false);
|
||||||
Option<bool> DisableSound("aica.NoSound");
|
Option<bool> DisableSound("aica.NoSound");
|
||||||
#if HOST_CPU == CPU_ARM
|
#if HOST_CPU == CPU_ARM
|
||||||
|
@ -48,6 +47,13 @@ Option<int> AudioBufferSize("aica.BufferSize", 5644); // 128 ms
|
||||||
#else
|
#else
|
||||||
Option<int> AudioBufferSize("aica.BufferSize", 2822); // 64 ms
|
Option<int> AudioBufferSize("aica.BufferSize", 2822); // 64 ms
|
||||||
#endif
|
#endif
|
||||||
|
Option<bool> AutoLatency("aica.AutoLatency",
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
OptionString AudioBackend("backend", "auto", "audio");
|
OptionString AudioBackend("backend", "auto", "audio");
|
||||||
|
|
||||||
|
@ -61,7 +67,6 @@ Option<bool> RenderToTextureBuffer("rend.RenderToTextureBuffer");
|
||||||
Option<int> RenderToTextureUpscale("rend.RenderToTextureUpscale", 1);
|
Option<int> RenderToTextureUpscale("rend.RenderToTextureUpscale", 1);
|
||||||
Option<bool> TranslucentPolygonDepthMask("rend.TranslucentPolygonDepthMask");
|
Option<bool> TranslucentPolygonDepthMask("rend.TranslucentPolygonDepthMask");
|
||||||
Option<bool> ModifierVolumes("rend.ModifierVolumes", true);
|
Option<bool> ModifierVolumes("rend.ModifierVolumes", true);
|
||||||
Option<bool> Clipping("rend.Clipping", true);
|
|
||||||
Option<int> TextureUpscale("rend.TextureUpscale", 1);
|
Option<int> TextureUpscale("rend.TextureUpscale", 1);
|
||||||
Option<int> MaxFilteredTextureSize("rend.MaxFilteredTextureSize", 256);
|
Option<int> MaxFilteredTextureSize("rend.MaxFilteredTextureSize", 256);
|
||||||
Option<float> ExtraDepthScale("rend.ExtraDepthScale", 1.f);
|
Option<float> ExtraDepthScale("rend.ExtraDepthScale", 1.f);
|
||||||
|
|
|
@ -277,6 +277,12 @@ protected:
|
||||||
|
|
||||||
using OptionString = Option<std::string>;
|
using OptionString = Option<std::string>;
|
||||||
|
|
||||||
|
template<typename T, T value = T()>
|
||||||
|
class ConstOption {
|
||||||
|
public:
|
||||||
|
operator T() const { return value; }
|
||||||
|
};
|
||||||
|
|
||||||
// Dynarec
|
// Dynarec
|
||||||
|
|
||||||
extern Option<bool> DynarecEnabled;
|
extern Option<bool> DynarecEnabled;
|
||||||
|
@ -297,10 +303,11 @@ extern Option<bool> AutoSavestate;
|
||||||
|
|
||||||
// Sound
|
// Sound
|
||||||
|
|
||||||
extern Option<bool> LimitFPS;
|
constexpr ConstOption<bool, true> LimitFPS;
|
||||||
extern Option<bool> DSPEnabled;
|
extern Option<bool> DSPEnabled;
|
||||||
extern Option<bool> DisableSound;
|
extern Option<bool> DisableSound;
|
||||||
extern Option<int> AudioBufferSize; //In samples ,*4 for bytes (1024)
|
extern Option<int> AudioBufferSize; //In samples ,*4 for bytes
|
||||||
|
extern Option<bool> AutoLatency;
|
||||||
|
|
||||||
extern OptionString AudioBackend;
|
extern OptionString AudioBackend;
|
||||||
|
|
||||||
|
@ -352,7 +359,7 @@ extern Option<bool> RenderToTextureBuffer;
|
||||||
extern Option<int> RenderToTextureUpscale;
|
extern Option<int> RenderToTextureUpscale;
|
||||||
extern Option<bool> TranslucentPolygonDepthMask;
|
extern Option<bool> TranslucentPolygonDepthMask;
|
||||||
extern Option<bool> ModifierVolumes;
|
extern Option<bool> ModifierVolumes;
|
||||||
extern Option<bool> Clipping;
|
constexpr ConstOption<bool, true> Clipping;
|
||||||
extern Option<int> TextureUpscale;
|
extern Option<int> TextureUpscale;
|
||||||
extern Option<int> MaxFilteredTextureSize;
|
extern Option<int> MaxFilteredTextureSize;
|
||||||
extern Option<float> ExtraDepthScale;
|
extern Option<float> ExtraDepthScale;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 flyinghead
|
Copyright 2019 flyinghead
|
||||||
|
|
||||||
This file is part of reicast.
|
This file is part of Flycast.
|
||||||
|
|
||||||
reicast is free software: you can redistribute it and/or modify
|
Flycast is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
reicast is distributed in the hope that it will be useful,
|
Flycast is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -1007,7 +1007,7 @@ static void gui_display_settings()
|
||||||
ImGui::ListBoxFooter();
|
ImGui::ListBoxFooter();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ShowHelpMarker("The directory where reicast saves configuration files and VMUs. BIOS files should be in a subfolder named \"data\"");
|
ShowHelpMarker("The directory where Flycast saves configuration files and VMUs. BIOS files should be in a subfolder named \"data\"");
|
||||||
if (OptionCheckbox("Hide Legacy Naomi Roms", config::HideLegacyNaomiRoms,
|
if (OptionCheckbox("Hide Legacy Naomi Roms", config::HideLegacyNaomiRoms,
|
||||||
"Hide .bin, .dat and .lst files from the content browser"))
|
"Hide .bin, .dat and .lst files from the content browser"))
|
||||||
scanner.refresh();
|
scanner.refresh();
|
||||||
|
@ -1245,8 +1245,6 @@ static void gui_display_settings()
|
||||||
OptionRadioButton("Maximum", config::AutoSkipFrame, 2, "Skip a frame when the GPU is running slow");
|
OptionRadioButton("Maximum", config::AutoSkipFrame, 2, "Skip a frame when the GPU is running slow");
|
||||||
ImGui::Columns(1, nullptr, false);
|
ImGui::Columns(1, nullptr, false);
|
||||||
|
|
||||||
OptionCheckbox("Clipping", config::Clipping,
|
|
||||||
"Enable clipping. May produce graphical errors when disabled");
|
|
||||||
OptionCheckbox("Shadows", config::ModifierVolumes,
|
OptionCheckbox("Shadows", config::ModifierVolumes,
|
||||||
"Enable modifier volumes, usually used for shadows");
|
"Enable modifier volumes, usually used for shadows");
|
||||||
OptionCheckbox("Fog", config::Fog, "Enable fog effects");
|
OptionCheckbox("Fog", config::Fog, "Enable fog effects");
|
||||||
|
@ -1342,14 +1340,19 @@ static void gui_display_settings()
|
||||||
OptionCheckbox("Disable Sound", config::DisableSound, "Disable the emulator sound output");
|
OptionCheckbox("Disable Sound", config::DisableSound, "Disable the emulator sound output");
|
||||||
OptionCheckbox("Enable DSP", config::DSPEnabled,
|
OptionCheckbox("Enable DSP", config::DSPEnabled,
|
||||||
"Enable the Dreamcast Digital Sound Processor. Only recommended on fast platforms");
|
"Enable the Dreamcast Digital Sound Processor. Only recommended on fast platforms");
|
||||||
OptionCheckbox("Limit Emulator Speed", config::LimitFPS,
|
#if !defined(_WIN32)
|
||||||
"Whether to limit the emulator speed using the audio output. Recommended");
|
#ifdef __ANDROID__
|
||||||
#if !defined(__ANDROID__) && !defined(_WIN32)
|
OptionCheckbox("Automatic Latency", config::AutoLatency,
|
||||||
int latency = (int)roundf(config::AudioBufferSize * 1000.f / 44100.f);
|
"Automatically set audio latency. Recommended");
|
||||||
ImGui::SliderInt("Latency", &latency, 12, 512, "%d ms");
|
#endif
|
||||||
config::AudioBufferSize = (int)roundf(latency * 44100.f / 1000.f);
|
if (!config::AutoLatency)
|
||||||
ImGui::SameLine();
|
{
|
||||||
ShowHelpMarker("Sets the maximum audio latency. Not supported by all audio drivers.");
|
int latency = (int)roundf(config::AudioBufferSize * 1000.f / 44100.f);
|
||||||
|
ImGui::SliderInt("Latency", &latency, 12, 512, "%d ms");
|
||||||
|
config::AudioBufferSize = (int)roundf(latency * 44100.f / 1000.f);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ShowHelpMarker("Sets the maximum audio latency. Not supported by all audio drivers.");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
audiobackend_t* backend = nullptr;
|
audiobackend_t* backend = nullptr;
|
||||||
|
@ -1711,7 +1714,7 @@ static void gui_display_content()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string gamePath(game.path);
|
std::string gamePath(game.path);
|
||||||
scanner.get_mutex().unlock();
|
scanner.get_mutex().unlock();
|
||||||
gui_state = GuiState::Closed;
|
gui_state = GuiState::Closed;
|
||||||
gui_start_game(gamePath);
|
gui_start_game(gamePath);
|
||||||
|
|
|
@ -24,12 +24,12 @@ public final class AudioBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by native code
|
// Called by native code
|
||||||
private void init()
|
private void init(int bufferSize)
|
||||||
{
|
{
|
||||||
int bufferSize = 2048;
|
if (bufferSize == 0)
|
||||||
int min = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
bufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
||||||
if (bufferSize < min)
|
else
|
||||||
bufferSize = min;
|
bufferSize *= 4;
|
||||||
|
|
||||||
audioTrack = new AudioTrack(
|
audioTrack = new AudioTrack(
|
||||||
AudioManager.STREAM_MUSIC,
|
AudioManager.STREAM_MUSIC,
|
||||||
|
@ -48,7 +48,7 @@ public final class AudioBackend {
|
||||||
size = bufferSize / 4;
|
size = bufferSize / 4;
|
||||||
writePosition = 0;
|
writePosition = 0;
|
||||||
|
|
||||||
Log.i("audcfg", "Audio streaming: buffer size " + size + " samples / " + size / 44100.0 + " ms");
|
Log.i("audcfg", "Audio streaming: buffer size " + size + " samples / " + size * 1000.0 / 44100.0 + " ms");
|
||||||
audioTrack.play();
|
audioTrack.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,14 +469,14 @@ JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_guiIsContentBrows
|
||||||
static u32 androidaudio_push(const void* frame, u32 amt, bool wait)
|
static u32 androidaudio_push(const void* frame, u32 amt, bool wait)
|
||||||
{
|
{
|
||||||
verify(amt==SAMPLE_COUNT);
|
verify(amt==SAMPLE_COUNT);
|
||||||
//yeah, do some audio piping magic here !
|
|
||||||
jvm_attacher.getEnv()->SetShortArrayRegion(jsamples, 0, amt * 2, (jshort *)frame);
|
jvm_attacher.getEnv()->SetShortArrayRegion(jsamples, 0, amt * 2, (jshort *)frame);
|
||||||
return jvm_attacher.getEnv()->CallIntMethod(g_audioBackend, writeBufferMid, jsamples, wait);
|
return jvm_attacher.getEnv()->CallIntMethod(g_audioBackend, writeBufferMid, jsamples, wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void androidaudio_init()
|
static void androidaudio_init()
|
||||||
{
|
{
|
||||||
jvm_attacher.getEnv()->CallVoidMethod(g_audioBackend, audioInitMid);
|
jint bufferSize = config::AutoLatency ? 0 : config::AudioBufferSize;
|
||||||
|
jvm_attacher.getEnv()->CallVoidMethod(g_audioBackend, audioInitMid, bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void androidaudio_term()
|
static void androidaudio_term()
|
||||||
|
@ -539,7 +539,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_AudioBackend_setInstance(JN
|
||||||
else {
|
else {
|
||||||
g_audioBackend = env->NewGlobalRef(instance);
|
g_audioBackend = env->NewGlobalRef(instance);
|
||||||
writeBufferMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "writeBuffer", "([SZ)I");
|
writeBufferMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "writeBuffer", "([SZ)I");
|
||||||
audioInitMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "init", "()V");
|
audioInitMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "init", "(I)V");
|
||||||
audioTermMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "term", "()V");
|
audioTermMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "term", "()V");
|
||||||
if (jsamples == NULL) {
|
if (jsamples == NULL) {
|
||||||
jsamples = env->NewShortArray(SAMPLE_COUNT * 2);
|
jsamples = env->NewShortArray(SAMPLE_COUNT * 2);
|
||||||
|
|
Loading…
Reference in New Issue