Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/core/StarAudio.cpp20
-rw-r--r--source/core/StarAudio.hpp9
-rw-r--r--source/frontend/StarMainMixer.cpp1
-rw-r--r--source/frontend/StarVoice.cpp17
-rw-r--r--source/frontend/StarVoice.hpp6
5 files changed, 45 insertions, 8 deletions
diff --git a/source/core/StarAudio.cpp b/source/core/StarAudio.cpp
index 4f07d05..2dfdaee 100644
--- a/source/core/StarAudio.cpp
+++ b/source/core/StarAudio.cpp
@@ -13,6 +13,26 @@
namespace Star {
+float const DefaultPerceptualRangeDb = 40.f;
+float const DefaultPerceptualBoostRangeDb = 6.f;
+// https://github.com/discord/perceptual
+float perceptualToAmplitude(float perceptual, float normalizedMax, float range, float boostRange) {
+ if (perceptual == 0.f) return 0.f;
+ float dB = perceptual > normalizedMax
+ ? ((perceptual - normalizedMax) / normalizedMax) * boostRange
+ : (perceptual / normalizedMax) * range - range;
+ return normalizedMax * pow(10.f, dB / 20.f);
+}
+
+float amplitudeToPerceptual(float amp, float normalizedMax, float range, float boostRange) {
+ if (amp == 0.f) return 0.f;
+ float const dB = 20.f * log10(amp / normalizedMax);
+ float perceptual = dB > 0.f
+ ? dB / boostRange + 1
+ : (range + dB) / range;
+ return normalizedMax * perceptual;
+}
+
namespace {
struct WaveData {
ByteArrayPtr byteArray;
diff --git a/source/core/StarAudio.hpp b/source/core/StarAudio.hpp
index cf8f91f..571aaf3 100644
--- a/source/core/StarAudio.hpp
+++ b/source/core/StarAudio.hpp
@@ -4,6 +4,15 @@
namespace Star {
+extern float const DefaultPerceptualRangeDb;
+extern float const DefaultPerceptualBoostRangeDb;
+
+float perceptualToAmplitude(float perceptual, float normalizedMax = 1.f,
+ float range = DefaultPerceptualRangeDb, float boostRange = DefaultPerceptualBoostRangeDb);
+
+float amplitudeToPerceptual(float amp, float normalizedMax = 1.f,
+ float range = DefaultPerceptualRangeDb, float boostRange = DefaultPerceptualBoostRangeDb);
+
STAR_CLASS(CompressedAudioImpl);
STAR_CLASS(UncompressedAudioImpl);
STAR_CLASS(Audio);
diff --git a/source/frontend/StarMainMixer.cpp b/source/frontend/StarMainMixer.cpp
index fe676d5..df80018 100644
--- a/source/frontend/StarMainMixer.cpp
+++ b/source/frontend/StarMainMixer.cpp
@@ -37,6 +37,7 @@ void MainMixer::update(float dt, bool muteSfx, bool muteMusic) {
}
} else if (!m_mutedGroups.contains(group)) {
float volumeSetting = Root::singleton().configuration()->get(settingName).toFloat() / 100.0f;
+ volumeSetting = perceptualToAmplitude(volumeSetting);
if (!m_groupVolumes.contains(group) || volumeSetting != m_groupVolumes[group]) {
m_mixer->setGroupVolume(group, volumeSetting);
m_groupVolumes[group] = volumeSetting;
diff --git a/source/frontend/StarVoice.cpp b/source/frontend/StarVoice.cpp
index b2c4695..0d56089 100644
--- a/source/frontend/StarVoice.cpp
+++ b/source/frontend/StarVoice.cpp
@@ -6,6 +6,7 @@
#include "StarRoot.hpp"
#include "StarLogging.hpp"
#include "StarInterpolation.hpp"
+#include "StarAudio.hpp"
#include "opus/opus.h"
#include "SDL2/SDL.h"
@@ -196,9 +197,11 @@ void Voice::loadJson(Json const& config, bool skipSave) {
&& change(m_deviceName, config.optString("deviceName"), changed))
resetDevice();
- m_threshold = config.getFloat("threshold", m_threshold);
- m_inputVolume = config.getFloat("inputVolume", m_inputVolume);
- m_outputVolume = config.getFloat("outputVolume", m_outputVolume);
+ m_threshold = config.getFloat("threshold", m_threshold);
+ m_inputAmplitude = perceptualToAmplitude(
+ m_inputVolume = config.getFloat("inputVolume", m_inputVolume));
+ m_outputAmplitude = perceptualToAmplitude(
+ m_outputVolume = config.getFloat("outputVolume", m_outputVolume));
if (change(m_loopback, config.getBool("loopback", m_loopback), changed))
m_clientSpeaker->playing = false;
@@ -321,7 +324,7 @@ void Voice::readAudioData(uint8_t* stream, int len) {
}
}
- m_clientSpeaker->decibelLevel = getAudioLoudness((int16_t*)stream, sampleCount, m_inputVolume);
+ m_clientSpeaker->decibelLevel = getAudioLoudness((int16_t*)stream, sampleCount, m_inputAmplitude);
if (!m_loopback) {
if (active && !m_clientSpeaker->playing)
@@ -411,7 +414,7 @@ void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) {
if (mix) {
finalBuffer.resize(sharedBuffer.size(), 0);
- float vol = m_outputVolume;
+ float vol = m_outputAmplitude;
for (size_t i = 0; i != sharedBuffer.size(); ++i)
finalBuffer[i] = (int16_t)clamp<int>(sharedBuffer[i] * vol, INT16_MIN, INT16_MAX);
@@ -678,9 +681,9 @@ void Voice::thread() {
}
m_capturedChunksFrames -= VOICE_FRAME_SIZE;
- if (m_inputVolume != 1.0f) {
+ if (m_inputAmplitude != 1.0f) {
for (size_t i = 0; i != samples.size(); ++i)
- samples[i] *= m_inputVolume;
+ samples[i] *= m_inputAmplitude;
}
if (int encodedSize = opus_encode(m_encoder.get(), samples.data(), VOICE_FRAME_SIZE, (unsigned char*)encoded.ptr(), encoded.size())) {
diff --git a/source/frontend/StarVoice.hpp b/source/frontend/StarVoice.hpp
index fa149b6..8059dd4 100644
--- a/source/frontend/StarVoice.hpp
+++ b/source/frontend/StarVoice.hpp
@@ -173,9 +173,13 @@ private:
OpusEncoderPtr m_encoder;
-
+
float m_outputVolume = 1.0f;
float m_inputVolume = 1.0f;
+
+ float m_outputAmplitude = 1.0f;
+ float m_inputAmplitude = 1.0f;
+
float m_threshold = -50.0f;
int64_t m_lastSentTime = 0;