Skip to content

Commit

Permalink
FIX(server): Cap receiver ranges at a vol. diff of 5dB
Browse files Browse the repository at this point in the history
The factor difference cap works for larger volume adjustments, but for
low volumes, the difference can easily exceed 5dB (from -24dB and lower,
a difference of 0.05 in the factor is a difference of more than 5dB).
  • Loading branch information
Krzmbrzl committed Nov 29, 2023
1 parent 432f62a commit ea3e7cd
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 9 deletions.
21 changes: 19 additions & 2 deletions src/murmur/AudioReceiverBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ class AudioReceiverBuffer {
std::vector< AudioReceiver > &getReceivers(bool receivePositionalData);


/**
* If two receivers differ in their volume adjustment factors by this much or more, they will never end up in the
* same receiver range
*/
constexpr static const float maxFactorDiff = 0.05f;
/**
* If two receivers differ in their volume adjustment decibels by this much or more, they will never end up in the
* same receiver range
*/
constexpr static const int maxDecibelDiff = 5;

template< typename Iterator > static ReceiverRange< Iterator > getReceiverRange(Iterator begin, Iterator end) {
ZoneScoped;

Expand All @@ -82,8 +93,14 @@ class AudioReceiverBuffer {
return lhs.getContext() == rhs.getContext()
&& Mumble::Protocol::protocolVersionsAreCompatible(lhs.getReceiver().m_version,
rhs.getReceiver().m_version)
// Allow a little variance between volume adjustments
&& std::abs(lhs.getVolumeAdjustment().factor - rhs.getVolumeAdjustment().factor) < 0.05f;
// The factor difference caps audible differences for high volume adjustments (where 1dB is already a
// big difference). Thus, this is a cap on the absolute loudness difference.
&& std::abs(lhs.getVolumeAdjustment().factor - rhs.getVolumeAdjustment().factor) < maxFactorDiff
// The dB difference caps audible difference for low volume adjustments. E.g. a factor difference of
// 0.05 for an adjustment of -24dB is a difference of more than 5dB and therefore audible. Thus, this
// is a cap on the relative loudness difference.
&& std::abs(lhs.getVolumeAdjustment().dbAdjustment - rhs.getVolumeAdjustment().dbAdjustment)
< maxDecibelDiff;
});

return range;
Expand Down
49 changes: 42 additions & 7 deletions src/tests/TestAudioReceiverBuffer/TestAudioReceiverBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ Version::full_t vOld2 = Version::fromComponents(1, 3, 1);
Version::full_t vOld3 = Version::fromComponents(1, 4, 0);
Version::full_t vNew = Mumble::Protocol::PROTOBUF_INTRODUCTION_VERSION;

std::array< ServerUser, 5 > users = { ServerUser(0, vOld1), ServerUser(1, vOld2), ServerUser(2, vOld3),
ServerUser(3, vNew), ServerUser(4, vNew) };
std::array< ServerUser, 6 > users = { ServerUser(0, vOld1), ServerUser(1, vOld2), ServerUser(2, vOld3),
ServerUser(3, vNew), ServerUser(4, vNew), ServerUser(5, vNew) };

ServerUser deafUser(5, vOld1, true);
ServerUser selfDeafUser(6, vNew, false, true);
ServerUser contextUser1(7, vNew, false, false, "context1");
ServerUser contextUser2(8, vNew, false, false, "context2");
ServerUser contextUser3(9, vNew, false, false, "context1");
ServerUser deafUser(6, vOld1, true);
ServerUser selfDeafUser(7, vNew, false, true);
ServerUser contextUser1(8, vNew, false, false, "context1");
ServerUser contextUser2(9, vNew, false, false, "context2");
ServerUser contextUser3(10, vNew, false, false, "context1");


struct Range {
Expand Down Expand Up @@ -203,6 +203,41 @@ private slots:
QCOMPARE(volumeReceiver->getVolumeAdjustment().factor, 1.4f);
}

void test_getReceiverRange() {
AudioReceiverBuffer buffer;

ServerUser &sender = contextUser2;

buffer.addReceiver(sender, users[0], Mumble::Protocol::AudioContext::NORMAL, false,
VolumeAdjustment::fromFactor(1.22));
buffer.addReceiver(sender, users[1], Mumble::Protocol::AudioContext::NORMAL, false,
VolumeAdjustment::fromFactor(1.22 + 0.6 * AudioReceiverBuffer::maxFactorDiff));
buffer.addReceiver(sender, users[2], Mumble::Protocol::AudioContext::NORMAL, false,
VolumeAdjustment::fromFactor(1.22 + 1.1 * AudioReceiverBuffer::maxFactorDiff));
buffer.addReceiver(sender, users[3], Mumble::Protocol::AudioContext::NORMAL, false,
VolumeAdjustment::fromDBAdjustment(-60));
buffer.addReceiver(sender, users[4], Mumble::Protocol::AudioContext::NORMAL, false,
VolumeAdjustment::fromDBAdjustment(-60 + AudioReceiverBuffer::maxDecibelDiff - 1));
buffer.addReceiver(sender, users[5], Mumble::Protocol::AudioContext::NORMAL, false,
VolumeAdjustment::fromDBAdjustment(-60 + AudioReceiverBuffer::maxDecibelDiff));

buffer.preprocessBuffer();

std::vector< AudioReceiver > receivers = buffer.getReceivers(false);
auto receiverRange = AudioReceiverBuffer::getReceiverRange(receivers.begin(), receivers.end());

std::array< int, 4 > expectedGroupSizes = { 2, 1, 2, 1 };

for (std::size_t i = 0; i < expectedGroupSizes.size(); ++i) {
QVERIFY(receiverRange.begin != receiverRange.end);
QCOMPARE(std::distance(receiverRange.begin, receiverRange.end), expectedGroupSizes.at(i));
receiverRange = AudioReceiverBuffer::getReceiverRange(receiverRange.end, receivers.end());
}

QVERIFY(receiverRange.begin == receiverRange.end);
}


void test_encoding() {
AudioReceiverBuffer buffer;

Expand Down

0 comments on commit ea3e7cd

Please sign in to comment.