Skip to content

Commit

Permalink
FEAT(client, ui): Allow for max bitrate in client
Browse files Browse the repository at this point in the history
Via mumble-voip#4700, the server binaries were adapted to allow for an Opus bitrate
of up to 510000 bits per second. The client on the other hand was left
at a max of 192 kb/s.

While this should be more than sufficient for most users, we now adapt
the limit on the client side to (in theory) be able to encode packages
with that 510 kb/s bitrate limit. Outside of very specialized
applications, this should be avoided though.

In order to keep the UI manageable, the respective slider now uses a
logarithmic scale. This also has the benefit that optically, the default
value of 40 kb/s looks pretty good compared to the max. possible value
and therefore novice users hopefully keep that value at its default.

Fixes mumble-voip#5989
  • Loading branch information
Krzmbrzl committed Dec 26, 2022
1 parent 4f3c289 commit cd5fa38
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 75 deletions.
35 changes: 28 additions & 7 deletions src/mumble/AudioConfigDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@

#include <QSignalBlocker>

#include <cmath>

const QString AudioOutputDialog::name = QLatin1String("AudioOutputWidget");
const QString AudioInputDialog::name = QLatin1String("AudioInputWidget");

constexpr int bitrateToLog(int bitrate) {
return std::log10(static_cast< float >(bitrate)) * 100;
}

constexpr int logToBitrate(int log) {
return std::pow(10, static_cast< float >(log) / 100);
}


static ConfigWidget *AudioInputDialogNew(Settings &st) {
return new AudioInputDialog(st);
Expand Down Expand Up @@ -146,7 +156,7 @@ void AudioInputDialog::load(const Settings &r) {
loadCheckBox(qcbPushWindow, r.bShowPTTButtonWindow);
loadCheckBox(qcbPushClick, r.bTxAudioCue);
loadCheckBox(qcbMuteCue, r.bTxMuteCue);
loadSlider(qsQuality, r.iQuality);
loadSlider(qsQuality, bitrateToLog(r.iQuality));
loadCheckBox(qcbAllowLowDelay, r.bAllowLowDelay);
if (r.iSpeexNoiseCancelStrength != 0) {
loadSlider(qsSpeexNoiseSupStrength, -r.iSpeexNoiseCancelStrength);
Expand Down Expand Up @@ -236,7 +246,7 @@ void AudioInputDialog::verifyMicrophonePermission() {
}

void AudioInputDialog::save() const {
s.iQuality = qsQuality->value();
s.iQuality = qsbQuality->value() * 1000;
s.bAllowLowDelay = qcbAllowLowDelay->isChecked();
s.iSpeexNoiseCancelStrength = (qsSpeexNoiseSupStrength->value() == 14) ? 0 : -qsSpeexNoiseSupStrength->value();

Expand Down Expand Up @@ -312,8 +322,21 @@ void AudioInputDialog::on_qsTransmitHold_valueChanged(int v) {
qlTransmitHold->setText(tr("%1 s").arg(val, 0, 'f', 2));
}

void AudioInputDialog::on_qsQuality_valueChanged(int v) {
qlQuality->setText(tr("%1 kb/s").arg(static_cast< float >(v) / 1000.0f, 0, 'f', 1));
void AudioInputDialog::on_qsQuality_valueChanged(int logValue) {
QSignalBlocker blocker(qsbQuality);

// Note: qsQuality is in b/s whereas qsbQuality is in kb/s
qsbQuality->setValue(static_cast< float >(logToBitrate(logValue)) / 1000);

updateBitrate();
}

void AudioInputDialog::on_qsbQuality_valueChanged(double bitrate) {
QSignalBlocker blocker(qsQuality);

// Note: qsQuality is in b/s whereas qsbQuality is in kb/s
qsQuality->setValue(bitrateToLog(bitrate * 1000));

updateBitrate();
}

Expand All @@ -338,7 +361,7 @@ void AudioInputDialog::on_qsAmp_valueChanged(int v) {
void AudioInputDialog::updateBitrate() {
if (!qsQuality || !qsFrames || !qlBitrate)
return;
int q = qsQuality->value();
int q = qsbQuality->value() * 1000;
int p = qsFrames->value();

int audiorate, overhead, posrate;
Expand Down Expand Up @@ -379,8 +402,6 @@ void AudioInputDialog::updateBitrate() {
.arg(posrate / 1000.0, 0, 'f', 1);

qlBitrate->setText(v);

qsQuality->setMinimum(8000);
}

void AudioInputDialog::on_qcbPushClick_clicked(bool b) {
Expand Down
1 change: 1 addition & 0 deletions src/mumble/AudioConfigDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public slots:
void on_qsTransmitHold_valueChanged(int v);
void on_qsFrames_valueChanged(int v);
void on_qsQuality_valueChanged(int v);
void on_qsbQuality_valueChanged(double v);
void on_qsAmp_valueChanged(int v);
void on_qsDoublePush_valueChanged(int v);
void on_qsPTTHold_valueChanged(int v);
Expand Down
139 changes: 71 additions & 68 deletions src/mumble/AudioInput.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>588</width>
<height>953</height>
<width>592</width>
<height>961</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -447,44 +447,33 @@
<property name="title">
<string>Compression</string>
</property>
<layout class="QGridLayout">
<item row="1" column="0">
<widget class="QLabel" name="qliFrames">
<property name="text">
<string>Audio per packet</string>
</property>
<property name="buddy">
<cstring>qsFrames</cstring>
<layout class="QGridLayout" rowstretch="0,0,0,0" columnstretch="0,0,0,0">
<item row="3" column="0" colspan="4">
<widget class="QLabel" name="qlBitrate">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="qsFrames">
<property name="toolTip">
<string>How many audio frames to send per packet</string>
<string>Maximum bandwidth used for sending audio</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;This selects how many audio frames should be put in one packet.&lt;/b&gt;&lt;br /&gt;Increasing this will increase the latency of your voice, but will also reduce bandwidth requirements.</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4</number>
<string>&lt;b&gt;This shows peak outgoing bandwidth used.&lt;/b&gt;&lt;br /&gt;This shows the peak amount of bandwidth sent out from your machine. Audio bitrate is the maximum bitrate (as we use VBR) for the audio data alone. Position is the bitrate used for positional information. Overhead is our framing and the IP packet headers (IP and UDP is 75% of this overhead).</string>
</property>
<property name="pageStep">
<number>2</number>
<property name="text">
<string/>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="qlQuality">
<item row="1" column="3">
<widget class="QLabel" name="qlFrames">
<property name="minimumSize">
<size>
<width>30</width>
<width>40</width>
<height>0</height>
</size>
</property>
Expand All @@ -493,16 +482,16 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="qlFrames">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="qcbAllowLowDelay">
<property name="toolTip">
<string>Enable Opus' low-delay mode when the quality is set to &lt;b&gt;64 kb/s&lt;/b&gt; or higher. </string>
</property>
<property name="whatsThis">
<string>If checked, Mumble will enable Opus' low-delay mode when the quality is set to &lt;b&gt;64 kbit/s&lt;/b&gt; or higher. Low-delay mode decreases latency by &lt;b&gt;~15 milliseconds&lt;/b&gt; in the round trip. This mode may require an higher bitrate to preserve the same quality, in comparison with the music and VOIP modes.</string>
</property>
<property name="text">
<string/>
<string>Allow low delay mode</string>
</property>
</widget>
</item>
Expand All @@ -515,66 +504,80 @@
<string>&lt;b&gt;This sets the quality of compression.&lt;/b&gt;&lt;br /&gt;This determines how much bandwidth Mumble is allowed to use for outgoing audio.</string>
</property>
<property name="minimum">
<number>8000</number>
<number>390</number>
</property>
<property name="maximum">
<number>192000</number>
<number>571</number>
</property>
<property name="singleStep">
<number>1000</number>
<number>1</number>
</property>
<property name="pageStep">
<number>5000</number>
<number>20</number>
</property>
<property name="value">
<number>32000</number>
<number>390</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="qlBitrate">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="toolTip">
<string>Maximum bandwidth used for sending audio</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;This shows peak outgoing bandwidth used.&lt;/b&gt;&lt;br /&gt;This shows the peak amount of bandwidth sent out from your machine. Audio bitrate is the maximum bitrate (as we use VBR) for the audio data alone. Position is the bitrate used for positional information. Overhead is our framing and the IP packet headers (IP and UDP is 75% of this overhead).</string>
</property>
<item row="0" column="0">
<widget class="QLabel" name="qliQuality">
<property name="text">
<string/>
<string>&amp;Quality</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<property name="buddy">
<cstring>qsQuality</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="qliQuality">
<item row="1" column="0">
<widget class="QLabel" name="qliFrames">
<property name="text">
<string>&amp;Quality</string>
<string>Audio per packet</string>
</property>
<property name="buddy">
<cstring>qsQuality</cstring>
<cstring>qsFrames</cstring>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="qcbAllowLowDelay">
<item row="1" column="1">
<widget class="QSlider" name="qsFrames">
<property name="toolTip">
<string>Enable Opus' low-delay mode when the quality is set to &lt;b&gt;64 kb/s&lt;/b&gt; or higher. </string>
<string>How many audio frames to send per packet</string>
</property>
<property name="whatsThis">
<string>If checked, Mumble will enable Opus' low-delay mode when the quality is set to &lt;b&gt;64 kbit/s&lt;/b&gt; or higher. Low-delay mode decreases latency by &lt;b&gt;~15 milliseconds&lt;/b&gt; in the round trip. This mode may require an higher bitrate to preserve the same quality, in comparison with the music and VOIP modes.</string>
<string>&lt;b&gt;This selects how many audio frames should be put in one packet.&lt;/b&gt;&lt;br /&gt;Increasing this will increase the latency of your voice, but will also reduce bandwidth requirements.</string>
</property>
<property name="text">
<string>Allow low delay mode</string>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4</number>
</property>
<property name="pageStep">
<number>2</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QDoubleSpinBox" name="qsbQuality">
<property name="suffix">
<string> kb/s</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>8.000000000000000</double>
</property>
<property name="maximum">
<double>510.000000000000000</double>
</property>
</widget>
</item>
Expand Down

0 comments on commit cd5fa38

Please sign in to comment.