mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-09 12:31:40 +12:00
Add volume slider & mute audio settings
This commit is contained in:
parent
b251f84ab1
commit
3b6190b69a
7 changed files with 70 additions and 12 deletions
|
@ -99,6 +99,11 @@ void EmulatorConfig::load() {
|
|||
|
||||
audioEnabled = toml::find_or<toml::boolean>(audio, "EnableAudio", false);
|
||||
aacEnabled = toml::find_or<toml::boolean>(audio, "EnableAACAudio", true);
|
||||
|
||||
audioDeviceConfig.muteAudio = toml::find_or<toml::boolean>(audio, "MuteAudio", false);
|
||||
// Our volume ranges from 0.0 (muted) to 2.0 (boosted, using a logarithmic scale). 1.0 is the "default" volume, ie we don't adjust the PCM
|
||||
// samples at all.
|
||||
audioDeviceConfig.volumeRaw = float(std::clamp(toml::find_or<toml::floating>(audio, "AudioVolume", 1.0), 0.0, 2.0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,6 +175,8 @@ void EmulatorConfig::save() {
|
|||
data["Audio"]["DSPEmulation"] = std::string(Audio::DSPCore::typeToString(dspType));
|
||||
data["Audio"]["EnableAudio"] = audioEnabled;
|
||||
data["Audio"]["EnableAACAudio"] = aacEnabled;
|
||||
data["Audio"]["MuteAudio"] = audioDeviceConfig.muteAudio;
|
||||
data["Audio"]["AudioVolume"] = double(audioDeviceConfig.volumeRaw);
|
||||
|
||||
data["Battery"]["ChargerPlugged"] = chargerPlugged;
|
||||
data["Battery"]["BatteryPercentage"] = batteryPercentage;
|
||||
|
|
|
@ -103,10 +103,8 @@ void AAC::Decoder::decode(AAC::Message& response, const AAC::Message& request, A
|
|||
}
|
||||
} else {
|
||||
// If audio is not enabled, push 0s
|
||||
for (int sample = 0; sample < info->frameSize; sample++) {
|
||||
for (int stream = 0; stream < channels; stream++) {
|
||||
audioStreams[stream].push_back(0);
|
||||
}
|
||||
for (int stream = 0; stream < channels; stream++) {
|
||||
audioStreams[stream].resize(audioStreams[stream].size() + info->frameSize, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -715,10 +715,7 @@ namespace Audio {
|
|||
response.command = request.command;
|
||||
response.mode = request.mode;
|
||||
|
||||
// We allow disabling AAC audio. Mostly useful for debugging & figuring out if an audio track is AAC or not.
|
||||
if (settings.aacEnabled) {
|
||||
aacDecoder->decode(response, request, [this](u32 paddr) { return getPointerPhys<u8>(paddr); });
|
||||
}
|
||||
aacDecoder->decode(response, request, [this](u32 paddr) { return getPointerPhys<u8>(paddr); }, settings.aacEnabled);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#include "audio/miniaudio_device.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
MiniAudioDevice::MiniAudioDevice() : initialized(false), running(false), samples(nullptr) {}
|
||||
MiniAudioDevice::MiniAudioDevice(AudioDeviceConfig& audioSettings)
|
||||
: initialized(false), running(false), samples(nullptr), audioSettings(audioSettings) {}
|
||||
|
||||
void MiniAudioDevice::init(Samples& samples, bool safe) {
|
||||
this->samples = &samples;
|
||||
|
@ -106,6 +110,40 @@ void MiniAudioDevice::init(Samples& samples, bool safe) {
|
|||
std::memcpy(&self->lastStereoSample[0], &output[(samplesWritten - 1) * 2], sizeof(lastStereoSample));
|
||||
}
|
||||
|
||||
// Adjust the volume of our samples based on the emulator's volume slider
|
||||
float audioVolume = self->audioSettings.getVolume();
|
||||
// If volume is 1.0 we don't need to do anything
|
||||
if (audioVolume != 1.0f) {
|
||||
s16* sample = output;
|
||||
|
||||
// If our volume is > 1.0 then we boost samples using a logarithmic scale,
|
||||
// In this case we also have to clamp samples to make sure they don't wrap around
|
||||
if (audioVolume > 1.0f) {
|
||||
audioVolume = 0.6 + 20 * std::log10(audioVolume);
|
||||
|
||||
constexpr s32 min = s32(std::numeric_limits<s16>::min());
|
||||
constexpr s32 max = s32(std::numeric_limits<s16>::max());
|
||||
|
||||
for (usize i = 0; i < samplesWritten; i += 2) {
|
||||
s16 l = s16(std::clamp<s32>(s32(float(sample[0]) * audioVolume), min, max));
|
||||
s16 r = s16(std::clamp<s32>(s32(float(sample[1]) * audioVolume), min, max));
|
||||
|
||||
*sample++ = l;
|
||||
*sample++ = r;
|
||||
}
|
||||
} else {
|
||||
// If our volume is in [0.0, 1.0) then just multiply by the volume. No need to clamp, since there is no danger of our samples wrapping
|
||||
// around due to overflow
|
||||
for (usize i = 0; i < samplesWritten; i += 2) {
|
||||
s16 l = s16(float(sample[0]) * audioVolume);
|
||||
s16 r = s16(float(sample[1]) * audioVolume);
|
||||
|
||||
*sample++ = l;
|
||||
*sample++ = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If underruning, copy the last output sample
|
||||
{
|
||||
s16* pointer = &output[samplesWritten * 2];
|
||||
|
|
|
@ -20,7 +20,7 @@ __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1;
|
|||
|
||||
Emulator::Emulator()
|
||||
: config(getConfigPath()), kernel(cpu, memory, gpu, config), cpu(memory, kernel, *this), gpu(memory, config), memory(cpu.getTicksRef(), config),
|
||||
cheats(memory, kernel.getServiceManager().getHID()), lua(*this), running(false)
|
||||
cheats(memory, kernel.getServiceManager().getHID()), audioDevice(config.audioDeviceConfig), lua(*this), running(false)
|
||||
#ifdef PANDA3DS_ENABLE_HTTP_SERVER
|
||||
,
|
||||
httpServer(this)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue