parent
4a0a1a32a4
commit
5d96ee5492
|
@ -574,6 +574,7 @@ endif(HAVE_GLOBALSHORTCUTS)
|
||||||
optional_source(HAVE_ALSA
|
optional_source(HAVE_ALSA
|
||||||
SOURCES
|
SOURCES
|
||||||
engine/alsadevicefinder.cpp
|
engine/alsadevicefinder.cpp
|
||||||
|
engine/alsapcmdevicefinder.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# DBUS
|
# DBUS
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Strawberry is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QString>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include <core/logging.h>
|
||||||
|
|
||||||
|
#include "devicefinder.h"
|
||||||
|
#include "alsapcmdevicefinder.h"
|
||||||
|
|
||||||
|
AlsaPCMDeviceFinder::AlsaPCMDeviceFinder()
|
||||||
|
: DeviceFinder("alsa", {"alsa","alsasink"}) {}
|
||||||
|
|
||||||
|
QList<DeviceFinder::Device> AlsaPCMDeviceFinder::ListDevices() {
|
||||||
|
|
||||||
|
QList<Device> ret;
|
||||||
|
|
||||||
|
void **hints = nullptr;
|
||||||
|
if (snd_device_name_hint(-1, "pcm", &hints) < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (void **n = hints ; *n ; ++n) {
|
||||||
|
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||||
|
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||||
|
char *desc = snd_device_name_get_hint(*n, "DESC");
|
||||||
|
if (io && name && desc && strcmp(io, "Output") == 0) {
|
||||||
|
|
||||||
|
char *desc_last = desc;
|
||||||
|
QString description;
|
||||||
|
for (char *desc_i = desc ; desc_i && *desc_i != '\0' ; ++desc_i) {
|
||||||
|
if (*desc_i == '\n') {
|
||||||
|
*desc_i = '\0';
|
||||||
|
if (!description.isEmpty()) description.append(' ');
|
||||||
|
description.append(desc_last);
|
||||||
|
desc_last = desc_i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc_last) {
|
||||||
|
if (!description.isEmpty()) description.append(' ');
|
||||||
|
description.append(desc_last);
|
||||||
|
}
|
||||||
|
|
||||||
|
Device device;
|
||||||
|
device.value = name;
|
||||||
|
device.description = description;
|
||||||
|
device.iconname = GuessIconName(device.description);
|
||||||
|
ret << device;
|
||||||
|
}
|
||||||
|
if (io) free(io);
|
||||||
|
if (name) free(name);
|
||||||
|
if (desc) free(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_device_name_free_hint(hints);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Strawberry is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ALSAPCMDEVICEFINDER_H
|
||||||
|
#define ALSAPCMDEVICEFINDER_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#include "devicefinder.h"
|
||||||
|
|
||||||
|
class AlsaPCMDeviceFinder : public DeviceFinder {
|
||||||
|
public:
|
||||||
|
explicit AlsaPCMDeviceFinder();
|
||||||
|
|
||||||
|
bool Initialize() override { return true; }
|
||||||
|
QList<Device> ListDevices() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ALSAPCMDEVICEFINDER_H
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
# include "alsadevicefinder.h"
|
# include "alsadevicefinder.h"
|
||||||
|
# include "alsapcmdevicefinder.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBPULSE
|
#ifdef HAVE_LIBPULSE
|
||||||
|
@ -57,6 +58,7 @@ void DeviceFinders::Init() {
|
||||||
|
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
device_finders.append(new AlsaDeviceFinder);
|
device_finders.append(new AlsaDeviceFinder);
|
||||||
|
device_finders.append(new AlsaPCMDeviceFinder);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBPULSE
|
#ifdef HAVE_LIBPULSE
|
||||||
device_finders.append(new PulseDeviceFinder);
|
device_finders.append(new PulseDeviceFinder);
|
||||||
|
|
|
@ -60,6 +60,8 @@ Engine::Base::Base()
|
||||||
fadeout_duration_(2),
|
fadeout_duration_(2),
|
||||||
fadeout_duration_nanosec_(2 * kNsecPerSec),
|
fadeout_duration_nanosec_(2 * kNsecPerSec),
|
||||||
proxy_authentication_(false),
|
proxy_authentication_(false),
|
||||||
|
channels_enabled_(false),
|
||||||
|
channels_(0),
|
||||||
about_to_end_emitted_(false) {}
|
about_to_end_emitted_(false) {}
|
||||||
|
|
||||||
Engine::Base::~Base() {}
|
Engine::Base::~Base() {}
|
||||||
|
@ -110,6 +112,9 @@ void Engine::Base::ReloadSettings() {
|
||||||
|
|
||||||
volume_control_ = s.value("volume_control", true).toBool();
|
volume_control_ = s.value("volume_control", true).toBool();
|
||||||
|
|
||||||
|
channels_enabled_ = s.value("channels_enabled", false).toBool();
|
||||||
|
channels_ = s.value("channels", 0).toInt();
|
||||||
|
|
||||||
buffer_duration_nanosec_ = s.value("bufferduration", BackendSettingsPage::kDefaultBufferDuration).toLongLong() * kNsecPerMsec;
|
buffer_duration_nanosec_ = s.value("bufferduration", BackendSettingsPage::kDefaultBufferDuration).toLongLong() * kNsecPerMsec;
|
||||||
buffer_low_watermark_ = s.value("bufferlowwatermark", BackendSettingsPage::kDefaultBufferLowWatermark).toDouble();
|
buffer_low_watermark_ = s.value("bufferlowwatermark", BackendSettingsPage::kDefaultBufferLowWatermark).toDouble();
|
||||||
buffer_high_watermark_ = s.value("bufferhighwatermark", BackendSettingsPage::kDefaultBufferHighWatermark).toDouble();
|
buffer_high_watermark_ = s.value("bufferhighwatermark", BackendSettingsPage::kDefaultBufferHighWatermark).toDouble();
|
||||||
|
@ -156,6 +161,7 @@ void Engine::Base::ReloadSettings() {
|
||||||
proxy_user_.clear();
|
proxy_user_.clear();
|
||||||
proxy_pass_.clear();
|
proxy_pass_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,10 @@ class Base : public QObject {
|
||||||
QString proxy_user_;
|
QString proxy_user_;
|
||||||
QString proxy_pass_;
|
QString proxy_pass_;
|
||||||
|
|
||||||
|
// Channels
|
||||||
|
bool channels_enabled_;
|
||||||
|
int channels_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool about_to_end_emitted_;
|
bool about_to_end_emitted_;
|
||||||
Q_DISABLE_COPY(Base)
|
Q_DISABLE_COPY(Base)
|
||||||
|
|
|
@ -817,6 +817,7 @@ std::shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline() {
|
||||||
ret->set_buffer_low_watermark(buffer_low_watermark_);
|
ret->set_buffer_low_watermark(buffer_low_watermark_);
|
||||||
ret->set_buffer_high_watermark(buffer_high_watermark_);
|
ret->set_buffer_high_watermark(buffer_high_watermark_);
|
||||||
ret->set_proxy_settings(proxy_address_, proxy_authentication_, proxy_user_, proxy_pass_);
|
ret->set_proxy_settings(proxy_address_, proxy_authentication_, proxy_user_, proxy_pass_);
|
||||||
|
ret->set_channels(channels_enabled_, channels_);
|
||||||
|
|
||||||
ret->AddBufferConsumer(this);
|
ret->AddBufferConsumer(this);
|
||||||
for (GstBufferConsumer *consumer : buffer_consumers_) {
|
for (GstBufferConsumer *consumer : buffer_consumers_) {
|
||||||
|
|
|
@ -86,6 +86,8 @@ GstEnginePipeline::GstEnginePipeline(GstEngine *engine)
|
||||||
buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark),
|
buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark),
|
||||||
buffering_(false),
|
buffering_(false),
|
||||||
proxy_authentication_(false),
|
proxy_authentication_(false),
|
||||||
|
channels_enabled_(false),
|
||||||
|
channels_(0),
|
||||||
segment_start_(0),
|
segment_start_(0),
|
||||||
segment_start_received_(false),
|
segment_start_received_(false),
|
||||||
end_offset_nanosec_(-1),
|
end_offset_nanosec_(-1),
|
||||||
|
@ -206,6 +208,11 @@ void GstEnginePipeline::set_proxy_settings(const QString &address, const bool au
|
||||||
proxy_pass_ = pass;
|
proxy_pass_ = pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GstEnginePipeline::set_channels(const bool enabled, const int channels) {
|
||||||
|
channels_enabled_ = enabled;
|
||||||
|
channels_ = channels;
|
||||||
|
}
|
||||||
|
|
||||||
bool GstEnginePipeline::InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec) {
|
bool GstEnginePipeline::InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec) {
|
||||||
|
|
||||||
stream_url_ = stream_url;
|
stream_url_ = stream_url;
|
||||||
|
@ -440,6 +447,10 @@ bool GstEnginePipeline::InitAudioBin() {
|
||||||
gst_element_link(next, audioconverter);
|
gst_element_link(next, audioconverter);
|
||||||
|
|
||||||
GstCaps *caps = gst_caps_new_empty_simple("audio/x-raw");
|
GstCaps *caps = gst_caps_new_empty_simple("audio/x-raw");
|
||||||
|
if (channels_enabled_ && channels_ > 0) {
|
||||||
|
qLog(Debug) << "Setting channels to" << channels_;
|
||||||
|
gst_caps_set_simple(caps, "channels", G_TYPE_INT, channels_, nullptr);
|
||||||
|
}
|
||||||
gst_element_link_filtered(audioconverter, audiosink, caps);
|
gst_element_link_filtered(audioconverter, audiosink, caps);
|
||||||
gst_caps_unref(caps);
|
gst_caps_unref(caps);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ class GstEnginePipeline : public QObject {
|
||||||
void set_buffer_low_watermark(const double value);
|
void set_buffer_low_watermark(const double value);
|
||||||
void set_buffer_high_watermark(const double value);
|
void set_buffer_high_watermark(const double value);
|
||||||
void set_proxy_settings(const QString &address, const bool authentication, const QString &user, const QString &pass);
|
void set_proxy_settings(const QString &address, const bool authentication, const QString &user, const QString &pass);
|
||||||
|
void set_channels(const bool enabled, const int channels);
|
||||||
|
|
||||||
// Creates the pipeline, returns false on error
|
// Creates the pipeline, returns false on error
|
||||||
bool InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec);
|
bool InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec);
|
||||||
|
@ -221,6 +222,10 @@ class GstEnginePipeline : public QObject {
|
||||||
QString proxy_user_;
|
QString proxy_user_;
|
||||||
QString proxy_pass_;
|
QString proxy_pass_;
|
||||||
|
|
||||||
|
// Channels
|
||||||
|
bool channels_enabled_;
|
||||||
|
int channels_;
|
||||||
|
|
||||||
// These get called when there is a new audio buffer available
|
// These get called when there is a new audio buffer available
|
||||||
QList<GstBufferConsumer*> buffer_consumers_;
|
QList<GstBufferConsumer*> buffer_consumers_;
|
||||||
QMutex buffer_consumers_mutex_;
|
QMutex buffer_consumers_mutex_;
|
||||||
|
|
|
@ -58,11 +58,17 @@
|
||||||
#include "ui_backendsettingspage.h"
|
#include "ui_backendsettingspage.h"
|
||||||
|
|
||||||
const char *BackendSettingsPage::kSettingsGroup = "Backend";
|
const char *BackendSettingsPage::kSettingsGroup = "Backend";
|
||||||
|
const char *BackendSettingsPage::kOutputAutomaticallySelect = "Automatically select";
|
||||||
|
const char *BackendSettingsPage::kOutputCustom = "Custom";
|
||||||
const qint64 BackendSettingsPage::kDefaultBufferDuration = 4000;
|
const qint64 BackendSettingsPage::kDefaultBufferDuration = 4000;
|
||||||
const double BackendSettingsPage::kDefaultBufferLowWatermark = 0.33;
|
const double BackendSettingsPage::kDefaultBufferLowWatermark = 0.33;
|
||||||
const double BackendSettingsPage::kDefaultBufferHighWatermark = 0.99;
|
const double BackendSettingsPage::kDefaultBufferHighWatermark = 0.99;
|
||||||
|
|
||||||
BackendSettingsPage::BackendSettingsPage(SettingsDialog *dialog) : SettingsPage(dialog), ui_(new Ui_BackendSettingsPage) {
|
BackendSettingsPage::BackendSettingsPage(SettingsDialog *dialog) :
|
||||||
|
SettingsPage(dialog),
|
||||||
|
ui_(new Ui_BackendSettingsPage),
|
||||||
|
configloaded_(false),
|
||||||
|
engineloaded_(false) {
|
||||||
|
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
setWindowIcon(IconLoader::Load("soundcard"));
|
setWindowIcon(IconLoader::Load("soundcard"));
|
||||||
|
@ -75,6 +81,24 @@ BackendSettingsPage::BackendSettingsPage(SettingsDialog *dialog) : SettingsPage(
|
||||||
ui_->label_replaygainfallbackgain->setMinimumWidth(QFontMetrics(ui_->label_replaygainfallbackgain->font()).width("-WW.W dB"));
|
ui_->label_replaygainfallbackgain->setMinimumWidth(QFontMetrics(ui_->label_replaygainfallbackgain->font()).width("-WW.W dB"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QObject::connect(ui_->combobox_engine, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BackendSettingsPage::EngineChanged);
|
||||||
|
QObject::connect(ui_->combobox_output, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BackendSettingsPage::OutputChanged);
|
||||||
|
QObject::connect(ui_->combobox_device, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BackendSettingsPage::DeviceSelectionChanged);
|
||||||
|
QObject::connect(ui_->lineedit_device, &QLineEdit::textChanged, this, &BackendSettingsPage::DeviceStringChanged);
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
QObject::connect(ui_->radiobutton_alsa_hw, &QRadioButton::clicked, this, &BackendSettingsPage::radiobutton_alsa_hw_clicked);
|
||||||
|
QObject::connect(ui_->radiobutton_alsa_plughw, &QRadioButton::clicked, this, &BackendSettingsPage::radiobutton_alsa_plughw_clicked);
|
||||||
|
QObject::connect(ui_->radiobutton_alsa_pcm, &QRadioButton::clicked, this, &BackendSettingsPage::radiobutton_alsa_pcm_clicked);
|
||||||
|
#endif
|
||||||
|
QObject::connect(ui_->stickyslider_replaygainpreamp, &StickySlider::valueChanged, this, &BackendSettingsPage::RgPreampChanged);
|
||||||
|
QObject::connect(ui_->stickyslider_replaygainfallbackgain, &StickySlider::valueChanged, this, &BackendSettingsPage::RgFallbackGainChanged);
|
||||||
|
QObject::connect(ui_->checkbox_fadeout_stop, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
||||||
|
QObject::connect(ui_->checkbox_fadeout_cross, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
||||||
|
QObject::connect(ui_->checkbox_fadeout_auto, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
||||||
|
QObject::connect(ui_->checkbox_volume_control, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
||||||
|
QObject::connect(ui_->checkbox_channels, &QCheckBox::toggled, ui_->widget_channels, &QSpinBox::setEnabled);
|
||||||
|
QObject::connect(ui_->button_buffer_defaults, &QPushButton::clicked, this, &BackendSettingsPage::BufferDefaults);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendSettingsPage::~BackendSettingsPage() {
|
BackendSettingsPage::~BackendSettingsPage() {
|
||||||
|
@ -111,8 +135,11 @@ void BackendSettingsPage::Load() {
|
||||||
|
|
||||||
ui_->checkbox_volume_control->setChecked(s.value("volume_control", true).toBool());
|
ui_->checkbox_volume_control->setChecked(s.value("volume_control", true).toBool());
|
||||||
|
|
||||||
ui_->spinbox_bufferduration->setValue(s.value("bufferduration", kDefaultBufferDuration).toInt());
|
ui_->checkbox_channels->setChecked(s.value("channels_enabled", false).toBool());
|
||||||
|
ui_->spinbox_channels->setValue(s.value("channels", 2).toInt());
|
||||||
|
ui_->widget_channels->setEnabled(ui_->checkbox_channels->isChecked());
|
||||||
|
|
||||||
|
ui_->spinbox_bufferduration->setValue(s.value("bufferduration", kDefaultBufferDuration).toInt());
|
||||||
ui_->spinbox_low_watermark->setValue(s.value("bufferlowwatermark", kDefaultBufferLowWatermark).toDouble());
|
ui_->spinbox_low_watermark->setValue(s.value("bufferlowwatermark", kDefaultBufferLowWatermark).toDouble());
|
||||||
ui_->spinbox_high_watermark->setValue(s.value("bufferhighwatermark", kDefaultBufferHighWatermark).toDouble());
|
ui_->spinbox_high_watermark->setValue(s.value("bufferhighwatermark", kDefaultBufferHighWatermark).toDouble());
|
||||||
|
|
||||||
|
@ -122,7 +149,7 @@ void BackendSettingsPage::Load() {
|
||||||
ui_->checkbox_replaygaincompression->setChecked(s.value("rgcompression", true).toBool());
|
ui_->checkbox_replaygaincompression->setChecked(s.value("rgcompression", true).toBool());
|
||||||
ui_->stickyslider_replaygainfallbackgain->setValue(static_cast<int>(s.value("rgfallbackgain", 0.0).toDouble() * 10 + 600));
|
ui_->stickyslider_replaygainfallbackgain->setValue(static_cast<int>(s.value("rgfallbackgain", 0.0).toDouble() * 10 + 600));
|
||||||
|
|
||||||
#if defined(HAVE_ALSA)
|
#ifdef HAVE_ALSA
|
||||||
bool fade_default = false;
|
bool fade_default = false;
|
||||||
#else
|
#else
|
||||||
bool fade_default = true;
|
bool fade_default = true;
|
||||||
|
@ -136,7 +163,7 @@ void BackendSettingsPage::Load() {
|
||||||
ui_->spinbox_fadeduration->setValue(s.value("FadeoutDuration", 2000).toInt());
|
ui_->spinbox_fadeduration->setValue(s.value("FadeoutDuration", 2000).toInt());
|
||||||
ui_->spinbox_fadeduration_pauseresume->setValue(s.value("FadeoutPauseDuration", 250).toInt());
|
ui_->spinbox_fadeduration_pauseresume->setValue(s.value("FadeoutPauseDuration", 250).toInt());
|
||||||
|
|
||||||
#if defined(HAVE_ALSA)
|
#ifdef HAVE_ALSA
|
||||||
ui_->lineedit_device->show();
|
ui_->lineedit_device->show();
|
||||||
ui_->widget_alsa_plugin->show();
|
ui_->widget_alsa_plugin->show();
|
||||||
int alsaplug_int = alsa_plugin(s.value("alsaplugin", 0).toInt());
|
int alsaplug_int = alsa_plugin(s.value("alsaplugin", 0).toInt());
|
||||||
|
@ -149,6 +176,9 @@ void BackendSettingsPage::Load() {
|
||||||
case alsa_plugin::alsa_plughw:
|
case alsa_plugin::alsa_plughw:
|
||||||
ui_->radiobutton_alsa_plughw->setChecked(true);
|
ui_->radiobutton_alsa_plughw->setChecked(true);
|
||||||
break;
|
break;
|
||||||
|
case alsa_plugin::alsa_pcm:
|
||||||
|
ui_->radiobutton_alsa_pcm->setChecked(true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -168,22 +198,6 @@ void BackendSettingsPage::Load() {
|
||||||
|
|
||||||
configloaded_ = true;
|
configloaded_ = true;
|
||||||
|
|
||||||
QObject::connect(ui_->combobox_engine, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BackendSettingsPage::EngineChanged);
|
|
||||||
QObject::connect(ui_->combobox_output, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BackendSettingsPage::OutputChanged);
|
|
||||||
QObject::connect(ui_->combobox_device, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BackendSettingsPage::DeviceSelectionChanged);
|
|
||||||
QObject::connect(ui_->lineedit_device, &QLineEdit::textChanged, this, &BackendSettingsPage::DeviceStringChanged);
|
|
||||||
#if defined(HAVE_ALSA)
|
|
||||||
QObject::connect(ui_->radiobutton_alsa_hw, &QRadioButton::clicked, this, &BackendSettingsPage::radiobutton_alsa_hw_clicked);
|
|
||||||
QObject::connect(ui_->radiobutton_alsa_plughw, &QRadioButton::clicked, this, &BackendSettingsPage::radiobutton_alsa_plughw_clicked);
|
|
||||||
#endif
|
|
||||||
QObject::connect(ui_->stickyslider_replaygainpreamp, &StickySlider::valueChanged, this, &BackendSettingsPage::RgPreampChanged);
|
|
||||||
QObject::connect(ui_->stickyslider_replaygainfallbackgain, &StickySlider::valueChanged, this, &BackendSettingsPage::RgFallbackGainChanged);
|
|
||||||
QObject::connect(ui_->checkbox_fadeout_stop, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
|
||||||
QObject::connect(ui_->checkbox_fadeout_cross, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
|
||||||
QObject::connect(ui_->checkbox_fadeout_auto, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
|
||||||
QObject::connect(ui_->checkbox_volume_control, &QCheckBox::toggled, this, &BackendSettingsPage::FadingOptionsChanged);
|
|
||||||
QObject::connect(ui_->button_buffer_defaults, &QPushButton::clicked, this, &BackendSettingsPage::BufferDefaults);
|
|
||||||
|
|
||||||
FadingOptionsChanged();
|
FadingOptionsChanged();
|
||||||
RgPreampChanged(ui_->stickyslider_replaygainpreamp->value());
|
RgPreampChanged(ui_->stickyslider_replaygainpreamp->value());
|
||||||
RgFallbackGainChanged(ui_->stickyslider_replaygainfallbackgain->value());
|
RgFallbackGainChanged(ui_->stickyslider_replaygainfallbackgain->value());
|
||||||
|
@ -202,7 +216,7 @@ void BackendSettingsPage::Load() {
|
||||||
}
|
}
|
||||||
QVariant device_value;
|
QVariant device_value;
|
||||||
if (ui_->combobox_device->currentText().isEmpty()) device_value = QVariant();
|
if (ui_->combobox_device->currentText().isEmpty()) device_value = QVariant();
|
||||||
else if (ui_->combobox_device->currentText() == "Custom") device_value = ui_->lineedit_device->text();
|
else if (ui_->combobox_device->currentText() == kOutputCustom) device_value = ui_->lineedit_device->text();
|
||||||
else device_value = ui_->combobox_device->itemData(ui_->combobox_device->currentIndex()).value<QVariant>();
|
else device_value = ui_->combobox_device->itemData(ui_->combobox_device->currentIndex()).value<QVariant>();
|
||||||
|
|
||||||
if (enginetype_current_ != enginetype || output_name != output_current_ || device_value != device_current_) {
|
if (enginetype_current_ != enginetype || output_name != output_current_ || device_value != device_current_) {
|
||||||
|
@ -318,7 +332,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (engine()->type() != Engine::GStreamer)
|
if (engine()->type() != Engine::GStreamer)
|
||||||
#endif
|
#endif
|
||||||
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Automatically select", QVariant());
|
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), kOutputAutomaticallySelect, QVariant());
|
||||||
|
|
||||||
for (DeviceFinder *f : dialog()->app()->device_finders()->ListFinders()) {
|
for (DeviceFinder *f : dialog()->app()->device_finders()->ListFinders()) {
|
||||||
if (!f->outputs().contains(output)) continue;
|
if (!f->outputs().contains(output)) continue;
|
||||||
|
@ -330,7 +344,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev
|
||||||
}
|
}
|
||||||
|
|
||||||
if (engine()->CustomDeviceSupport(output)) {
|
if (engine()->CustomDeviceSupport(output)) {
|
||||||
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Custom", QVariant());
|
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), kOutputCustom, QVariant());
|
||||||
ui_->lineedit_device->setEnabled(true);
|
ui_->lineedit_device->setEnabled(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -339,28 +353,36 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev
|
||||||
|
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
if (engine()->ALSADeviceSupport(output)) {
|
if (engine()->ALSADeviceSupport(output)) {
|
||||||
|
ui_->widget_alsa_plugin->setEnabled(true);
|
||||||
ui_->radiobutton_alsa_hw->setEnabled(true);
|
ui_->radiobutton_alsa_hw->setEnabled(true);
|
||||||
ui_->radiobutton_alsa_plughw->setEnabled(true);
|
ui_->radiobutton_alsa_plughw->setEnabled(true);
|
||||||
if (device.toString().contains(QRegularExpression("^plughw:.*"))) {
|
ui_->radiobutton_alsa_pcm->setEnabled(true);
|
||||||
ui_->radiobutton_alsa_hw->setChecked(false);
|
if (device.toString().contains(QRegularExpression("^hw:.*"))) {
|
||||||
|
ui_->radiobutton_alsa_hw->setChecked(true);
|
||||||
|
SwitchALSADevices(alsa_plugin::alsa_hw);
|
||||||
|
}
|
||||||
|
else if (device.toString().contains(QRegularExpression("^plughw:.*"))) {
|
||||||
ui_->radiobutton_alsa_plughw->setChecked(true);
|
ui_->radiobutton_alsa_plughw->setChecked(true);
|
||||||
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
||||||
}
|
}
|
||||||
|
else if (device.toString().contains(QRegularExpression("^.*:CARD=.*DEV=.*"))) {
|
||||||
|
ui_->radiobutton_alsa_pcm->setChecked(true);
|
||||||
|
SwitchALSADevices(alsa_plugin::alsa_pcm);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ui_->radiobutton_alsa_plughw->setChecked(false);
|
|
||||||
ui_->radiobutton_alsa_hw->setChecked(true);
|
ui_->radiobutton_alsa_hw->setChecked(true);
|
||||||
SwitchALSADevices(alsa_plugin::alsa_hw);
|
SwitchALSADevices(alsa_plugin::alsa_hw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui_->radiobutton_alsa_hw->setEnabled(false);
|
ui_->widget_alsa_plugin->setDisabled(true);
|
||||||
ui_->radiobutton_alsa_hw->setChecked(false);
|
ui_->radiobutton_alsa_hw->setChecked(false);
|
||||||
ui_->radiobutton_alsa_plughw->setEnabled(false);
|
|
||||||
ui_->radiobutton_alsa_plughw->setChecked(false);
|
ui_->radiobutton_alsa_plughw->setChecked(false);
|
||||||
|
ui_->radiobutton_alsa_pcm->setChecked(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool found(false);
|
bool found = false;
|
||||||
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
QVariant d = ui_->combobox_device->itemData(i).value<QVariant>();
|
QVariant d = ui_->combobox_device->itemData(i).value<QVariant>();
|
||||||
if (df_device.value.isValid() && df_device.value == d) {
|
if (df_device.value.isValid() && df_device.value == d) {
|
||||||
|
@ -381,8 +403,8 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev
|
||||||
ui_->lineedit_device->setText(device.toString());
|
ui_->lineedit_device->setText(device.toString());
|
||||||
if (!found) {
|
if (!found) {
|
||||||
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
if (ui_->combobox_device->itemText(i) == "Custom") {
|
if (ui_->combobox_device->itemText(i) == kOutputCustom) {
|
||||||
if (ui_->combobox_device->currentText() != "Custom") ui_->combobox_device->setCurrentIndex(i);
|
if (ui_->combobox_device->currentText() != kOutputCustom) ui_->combobox_device->setCurrentIndex(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,7 +433,7 @@ void BackendSettingsPage::Save() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui_->combobox_device->currentText().isEmpty()) device_value = QVariant();
|
if (ui_->combobox_device->currentText().isEmpty()) device_value = QVariant();
|
||||||
else if (ui_->combobox_device->currentText() == "Custom") device_value = ui_->lineedit_device->text();
|
else if (ui_->combobox_device->currentText() == kOutputCustom) device_value = ui_->lineedit_device->text();
|
||||||
else device_value = ui_->combobox_device->itemData(ui_->combobox_device->currentIndex()).value<QVariant>();
|
else device_value = ui_->combobox_device->itemData(ui_->combobox_device->currentIndex()).value<QVariant>();
|
||||||
|
|
||||||
QSettings s;
|
QSettings s;
|
||||||
|
@ -442,20 +464,26 @@ void BackendSettingsPage::Save() {
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
if (ui_->radiobutton_alsa_hw->isChecked()) s.setValue("alsaplugin", static_cast<int>(alsa_plugin::alsa_hw));
|
if (ui_->radiobutton_alsa_hw->isChecked()) s.setValue("alsaplugin", static_cast<int>(alsa_plugin::alsa_hw));
|
||||||
else if (ui_->radiobutton_alsa_plughw->isChecked()) s.setValue("alsaplugin", static_cast<int>(alsa_plugin::alsa_plughw));
|
else if (ui_->radiobutton_alsa_plughw->isChecked()) s.setValue("alsaplugin", static_cast<int>(alsa_plugin::alsa_plughw));
|
||||||
|
else if (ui_->radiobutton_alsa_pcm->isChecked()) s.setValue("alsaplugin", static_cast<int>(alsa_plugin::alsa_pcm));
|
||||||
else s.remove("alsaplugin");
|
else s.remove("alsaplugin");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s.setValue("volume_control", ui_->checkbox_volume_control->isChecked());
|
s.setValue("volume_control", ui_->checkbox_volume_control->isChecked());
|
||||||
|
|
||||||
|
s.setValue("channels_enabled", ui_->checkbox_channels->isChecked());
|
||||||
|
s.setValue("channels", ui_->spinbox_channels->value());
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackendSettingsPage::Cancel() {
|
void BackendSettingsPage::Cancel() {
|
||||||
|
|
||||||
if (engine() && engine()->type() != enginetype_current_) { // Reset engine back to the original because user cancelled.
|
if (engine() && engine()->type() != enginetype_current_) { // Reset engine back to the original because user cancelled.
|
||||||
dialog()->app()->player()->CreateEngine(enginetype_current_);
|
dialog()->app()->player()->CreateEngine(enginetype_current_);
|
||||||
dialog()->app()->player()->Init();
|
dialog()->app()->player()->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackendSettingsPage::EngineChanged(const int index) {
|
void BackendSettingsPage::EngineChanged(const int index) {
|
||||||
|
@ -496,7 +524,7 @@ void BackendSettingsPage::DeviceSelectionChanged(int index) {
|
||||||
|
|
||||||
if (engine()->CustomDeviceSupport(output.name)) {
|
if (engine()->CustomDeviceSupport(output.name)) {
|
||||||
ui_->lineedit_device->setEnabled(true);
|
ui_->lineedit_device->setEnabled(true);
|
||||||
if (ui_->combobox_device->currentText() != "Custom") {
|
if (ui_->combobox_device->currentText() != kOutputCustom) {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (device.metaType().id() == QMetaType::QString)
|
if (device.metaType().id() == QMetaType::QString)
|
||||||
#else
|
#else
|
||||||
|
@ -520,7 +548,7 @@ void BackendSettingsPage::DeviceStringChanged() {
|
||||||
if (!configloaded_ || !EngineInitialized()) return;
|
if (!configloaded_ || !EngineInitialized()) return;
|
||||||
|
|
||||||
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
||||||
bool found(false);
|
bool found = false;
|
||||||
|
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
if (engine()->ALSADeviceSupport(output.name)) {
|
if (engine()->ALSADeviceSupport(output.name)) {
|
||||||
|
@ -532,6 +560,10 @@ void BackendSettingsPage::DeviceStringChanged() {
|
||||||
ui_->radiobutton_alsa_plughw->setChecked(true);
|
ui_->radiobutton_alsa_plughw->setChecked(true);
|
||||||
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
||||||
}
|
}
|
||||||
|
else if (ui_->lineedit_device->text().contains(QRegularExpression("^.*:CARD=.*DEV=.*")) && !ui_->radiobutton_alsa_pcm->isChecked()) {
|
||||||
|
ui_->radiobutton_alsa_pcm->setChecked(true);
|
||||||
|
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -542,9 +574,10 @@ void BackendSettingsPage::DeviceStringChanged() {
|
||||||
#else
|
#else
|
||||||
if (device.type() != QVariant::String) continue;
|
if (device.type() != QVariant::String) continue;
|
||||||
#endif
|
#endif
|
||||||
if (device.toString().isEmpty()) continue;
|
QString device_str = device.toString();
|
||||||
if (ui_->combobox_device->itemText(i) == "Custom") continue;
|
if (device_str.isEmpty()) continue;
|
||||||
if (device.toString() == ui_->lineedit_device->text()) {
|
if (ui_->combobox_device->itemText(i) == kOutputCustom) continue;
|
||||||
|
if (device_str == ui_->lineedit_device->text()) {
|
||||||
if (ui_->combobox_device->currentIndex() != i) ui_->combobox_device->setCurrentIndex(i);
|
if (ui_->combobox_device->currentIndex() != i) ui_->combobox_device->setCurrentIndex(i);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
@ -552,15 +585,15 @@ void BackendSettingsPage::DeviceStringChanged() {
|
||||||
|
|
||||||
if (engine()->CustomDeviceSupport(output.name)) {
|
if (engine()->CustomDeviceSupport(output.name)) {
|
||||||
ui_->lineedit_device->setEnabled(true);
|
ui_->lineedit_device->setEnabled(true);
|
||||||
if ((!found) && (ui_->combobox_device->currentText() != "Custom")) {
|
if ((!found) && (ui_->combobox_device->currentText() != kOutputCustom)) {
|
||||||
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
if (ui_->combobox_device->itemText(i) == "Custom") {
|
if (ui_->combobox_device->itemText(i) == kOutputCustom) {
|
||||||
ui_->combobox_device->setCurrentIndex(i);
|
ui_->combobox_device->setCurrentIndex(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ui_->combobox_device->currentText() == "Custom") {
|
if (ui_->combobox_device->currentText() == kOutputCustom) {
|
||||||
if ((ui_->lineedit_device->text().isEmpty()) && (ui_->combobox_device->count() > 0) && (ui_->combobox_device->currentIndex() != 0)) ui_->combobox_device->setCurrentIndex(0);
|
if ((ui_->lineedit_device->text().isEmpty()) && (ui_->combobox_device->count() > 0) && (ui_->combobox_device->currentIndex() != 0)) ui_->combobox_device->setCurrentIndex(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -596,12 +629,14 @@ void BackendSettingsPage::SwitchALSADevices(const alsa_plugin alsaplugin) {
|
||||||
// All ALSA devices are listed twice, one for "hw" and one for "plughw"
|
// All ALSA devices are listed twice, one for "hw" and one for "plughw"
|
||||||
// Only show one of them by making the other ones invisible based on the alsa plugin radiobuttons
|
// Only show one of them by making the other ones invisible based on the alsa plugin radiobuttons
|
||||||
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
QListView *view = qobject_cast<QListView *>(ui_->combobox_device->view());
|
QListView *view = qobject_cast<QListView*>(ui_->combobox_device->view());
|
||||||
if (!view) continue;
|
if (!view) continue;
|
||||||
if (alsaplugin == alsa_plugin::alsa_hw && ui_->combobox_device->itemData(i).toString().contains(QRegularExpression("^plughw:.*"))) {
|
if ((ui_->combobox_device->itemData(i).toString().contains(QRegularExpression("^hw:.*")) && alsaplugin != alsa_plugin::alsa_hw)
|
||||||
view->setRowHidden(i, true);
|
||
|
||||||
}
|
(ui_->combobox_device->itemData(i).toString().contains(QRegularExpression("^plughw:.*")) && alsaplugin != alsa_plugin::alsa_plughw)
|
||||||
else if (alsaplugin == alsa_plugin::alsa_plughw && ui_->combobox_device->itemData(i).toString().contains(QRegularExpression("^hw:.*"))) {
|
||
|
||||||
|
(ui_->combobox_device->itemData(i).toString().contains(QRegularExpression("^.*:CARD=.*DEV=.*")) && alsaplugin != alsa_plugin::alsa_pcm)
|
||||||
|
) {
|
||||||
view->setRowHidden(i, true);
|
view->setRowHidden(i, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -614,7 +649,7 @@ void BackendSettingsPage::SwitchALSADevices(const alsa_plugin alsaplugin) {
|
||||||
|
|
||||||
void BackendSettingsPage::radiobutton_alsa_hw_clicked(const bool checked) {
|
void BackendSettingsPage::radiobutton_alsa_hw_clicked(const bool checked) {
|
||||||
|
|
||||||
Q_UNUSED(checked);
|
if (!checked) return;
|
||||||
|
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
|
|
||||||
|
@ -623,33 +658,27 @@ void BackendSettingsPage::radiobutton_alsa_hw_clicked(const bool checked) {
|
||||||
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
||||||
if (!engine()->ALSADeviceSupport(output.name)) return;
|
if (!engine()->ALSADeviceSupport(output.name)) return;
|
||||||
|
|
||||||
if (ui_->lineedit_device->text().contains(QRegularExpression("^plughw:.*"))) {
|
SwitchALSADevices(alsa_plugin::alsa_hw);
|
||||||
SwitchALSADevices(alsa_plugin::alsa_hw);
|
|
||||||
QString device_new = ui_->lineedit_device->text().replace(QRegularExpression("^plughw:"), "hw:");
|
QString device_new = ui_->lineedit_device->text();
|
||||||
bool found(false);
|
|
||||||
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
if (device_new.contains(QRegularExpression("^plughw:.*"))) {
|
||||||
QVariant device = ui_->combobox_device->itemData(i).value<QVariant>();
|
device_new = device_new.replace(QRegularExpression("^plughw:"), "hw:");
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
if (device.metaType().id() != QMetaType::QString) continue;
|
|
||||||
#else
|
|
||||||
if (device.type() != QVariant::String) continue;
|
|
||||||
#endif
|
|
||||||
if (device.toString().isEmpty()) continue;
|
|
||||||
if (device.toString() == device_new) {
|
|
||||||
if (ui_->combobox_device->currentIndex() != i) ui_->combobox_device->setCurrentIndex(i);
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) ui_->lineedit_device->setText(device_new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!device_new.contains(QRegularExpression("^hw:.*"))) {
|
||||||
|
device_new.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectDevice(device_new);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackendSettingsPage::radiobutton_alsa_plughw_clicked(const bool checked) {
|
void BackendSettingsPage::radiobutton_alsa_plughw_clicked(const bool checked) {
|
||||||
|
|
||||||
Q_UNUSED(checked);
|
if (!checked) return;
|
||||||
|
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
|
|
||||||
|
@ -658,28 +687,88 @@ void BackendSettingsPage::radiobutton_alsa_plughw_clicked(const bool checked) {
|
||||||
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
||||||
if (!engine()->ALSADeviceSupport(output.name)) return;
|
if (!engine()->ALSADeviceSupport(output.name)) return;
|
||||||
|
|
||||||
if (ui_->lineedit_device->text().contains(QRegularExpression("^hw:.*"))) {
|
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
||||||
SwitchALSADevices(alsa_plugin::alsa_plughw);
|
|
||||||
QString device_new = ui_->lineedit_device->text().replace(QRegularExpression("^hw:"), "plughw:");
|
QString device_new = ui_->lineedit_device->text();
|
||||||
bool found(false);
|
|
||||||
|
if (device_new.contains(QRegularExpression("^hw:.*"))) {
|
||||||
|
device_new = device_new.replace(QRegularExpression("^hw:"), "plughw:");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_new.contains(QRegularExpression("^plughw:.*"))) {
|
||||||
|
device_new.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectDevice(device_new);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackendSettingsPage::radiobutton_alsa_pcm_clicked(const bool checked) {
|
||||||
|
|
||||||
|
if (!checked) return;
|
||||||
|
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
|
||||||
|
if (!configloaded_ || !EngineInitialized()) return;
|
||||||
|
|
||||||
|
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
||||||
|
if (!engine()->ALSADeviceSupport(output.name)) return;
|
||||||
|
|
||||||
|
SwitchALSADevices(alsa_plugin::alsa_pcm);
|
||||||
|
|
||||||
|
QString device_new = ui_->lineedit_device->text();
|
||||||
|
|
||||||
|
if (!device_new.contains(QRegularExpression("^.*:CARD=.*DEV=.*"))) {
|
||||||
|
device_new.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectDevice(device_new);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackendSettingsPage::SelectDevice(const QString &device_new) {
|
||||||
|
|
||||||
|
if (device_new.isEmpty()) {
|
||||||
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
|
if (ui_->combobox_device->itemText(i) == kOutputAutomaticallySelect && ui_->combobox_device->currentIndex() != i) {
|
||||||
|
ui_->combobox_device->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
|
QListView *view = qobject_cast<QListView*>(ui_->combobox_device->view());
|
||||||
|
if (view && view->isRowHidden(i)) continue;
|
||||||
QVariant device = ui_->combobox_device->itemData(i).value<QVariant>();
|
QVariant device = ui_->combobox_device->itemData(i).value<QVariant>();
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (device.metaType().id() != QMetaType::QString) continue;
|
if (device.metaType().id() != QMetaType::QString) continue;
|
||||||
#else
|
#else
|
||||||
if (device.type() != QVariant::String) continue;
|
if (device.type() != QVariant::String) continue;
|
||||||
#endif
|
#endif
|
||||||
if (device.toString().isEmpty()) continue;
|
QString device_str = device.toString();
|
||||||
if (device.toString() == device_new) {
|
if (device_str.isEmpty()) continue;
|
||||||
|
if (device_str == device_new) {
|
||||||
if (ui_->combobox_device->currentIndex() != i) ui_->combobox_device->setCurrentIndex(i);
|
if (ui_->combobox_device->currentIndex() != i) ui_->combobox_device->setCurrentIndex(i);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) ui_->lineedit_device->setText(device_new);
|
if (!found) {
|
||||||
|
ui_->lineedit_device->setText(device_new);
|
||||||
|
for (int i = 0; i < ui_->combobox_device->count(); ++i) {
|
||||||
|
if (ui_->combobox_device->itemText(i) == kOutputCustom && ui_->combobox_device->currentIndex() != i) {
|
||||||
|
ui_->combobox_device->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackendSettingsPage::FadingOptionsChanged() {
|
void BackendSettingsPage::FadingOptionsChanged() {
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
void RgFallbackGainChanged(const int value);
|
void RgFallbackGainChanged(const int value);
|
||||||
void radiobutton_alsa_hw_clicked(const bool checked);
|
void radiobutton_alsa_hw_clicked(const bool checked);
|
||||||
void radiobutton_alsa_plughw_clicked(const bool checked);
|
void radiobutton_alsa_plughw_clicked(const bool checked);
|
||||||
|
void radiobutton_alsa_pcm_clicked(const bool checked);
|
||||||
void FadingOptionsChanged();
|
void FadingOptionsChanged();
|
||||||
void BufferDefaults();
|
void BufferDefaults();
|
||||||
|
|
||||||
|
@ -71,12 +72,11 @@ public:
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
enum alsa_plugin {
|
enum alsa_plugin {
|
||||||
alsa_hw = 1,
|
alsa_hw = 1,
|
||||||
alsa_plughw = 2
|
alsa_plughw = 2,
|
||||||
|
alsa_pcm = 3
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ui_BackendSettingsPage *ui_;
|
|
||||||
|
|
||||||
bool EngineInitialized();
|
bool EngineInitialized();
|
||||||
|
|
||||||
void Load_Engine(Engine::EngineType enginetype);
|
void Load_Engine(Engine::EngineType enginetype);
|
||||||
|
@ -85,7 +85,13 @@ public:
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
void SwitchALSADevices(const alsa_plugin alsaplugin);
|
void SwitchALSADevices(const alsa_plugin alsaplugin);
|
||||||
#endif
|
#endif
|
||||||
|
void SelectDevice(const QString &device_new);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char *kOutputAutomaticallySelect;
|
||||||
|
static const char *kOutputCustom;
|
||||||
|
|
||||||
|
Ui_BackendSettingsPage *ui_;
|
||||||
bool configloaded_;
|
bool configloaded_;
|
||||||
bool engineloaded_;
|
bool engineloaded_;
|
||||||
ErrorDialog errordialog_;
|
ErrorDialog errordialog_;
|
||||||
|
|
|
@ -21,125 +21,23 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="layout_audio_output">
|
<layout class="QVBoxLayout" name="layout_audio_output">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="layout_engine">
|
<layout class="QGridLayout" name="layout_engine_output_device">
|
||||||
<property name="spacing">
|
<item row="4" column="0">
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_engine">
|
|
||||||
<property name="text">
|
|
||||||
<string>Engine</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="combobox_engine">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>400</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="spacer_engine">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="layout_output">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_output">
|
|
||||||
<property name="text">
|
|
||||||
<string>Output</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="combobox_output">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>400</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="spacer_output">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="layout_device">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_device">
|
<widget class="QLabel" name="label_device">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Device</string>
|
<string>Device</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="5" column="1">
|
||||||
<widget class="QComboBox" name="combobox_device">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>240</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="LineEdit" name="lineedit_device" native="true">
|
<widget class="LineEdit" name="lineedit_device" native="true">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>90</width>
|
<width>0</width>
|
||||||
<height>30</height>
|
<height>20</height>
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>160</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="hint" stdset="0">
|
<property name="hint" stdset="0">
|
||||||
|
@ -147,23 +45,48 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="3" column="1">
|
||||||
<spacer name="spacer_device">
|
<widget class="QComboBox" name="combobox_output">
|
||||||
<property name="orientation">
|
<property name="enabled">
|
||||||
<enum>Qt::Horizontal</enum>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
</widget>
|
||||||
<size>
|
</item>
|
||||||
<width>0</width>
|
<item row="3" column="0">
|
||||||
<height>0</height>
|
<widget class="QLabel" name="label_output">
|
||||||
</size>
|
<property name="text">
|
||||||
|
<string>Output</string>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QComboBox" name="combobox_device">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="combobox_engine">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_engine">
|
||||||
|
<property name="text">
|
||||||
|
<string>Engine</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_alsa_plugin" native="true">
|
<widget class="QWidget" name="widget_alsa_plugin" native="true">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<layout class="QHBoxLayout" name="layout_alsa_plugin">
|
<layout class="QHBoxLayout" name="layout_alsa_plugin">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
@ -180,7 +103,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_alsaplugin">
|
<widget class="QLabel" name="label_alsaplugin">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>ALSA plugin</string>
|
<string>ALSA plugin:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -204,6 +127,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radiobutton_alsa_pcm">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>pcm</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="spacer_alsaplugin">
|
<spacer name="spacer_alsaplugin">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -227,6 +160,82 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_channels_enabled" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkbox_channels">
|
||||||
|
<property name="text">
|
||||||
|
<string>Upmix / downmix to</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_channels" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinbox_channels">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_channels">
|
||||||
|
<property name="text">
|
||||||
|
<string>channels</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="spacer_channels">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -689,7 +698,10 @@
|
||||||
<tabstop>combobox_device</tabstop>
|
<tabstop>combobox_device</tabstop>
|
||||||
<tabstop>radiobutton_alsa_hw</tabstop>
|
<tabstop>radiobutton_alsa_hw</tabstop>
|
||||||
<tabstop>radiobutton_alsa_plughw</tabstop>
|
<tabstop>radiobutton_alsa_plughw</tabstop>
|
||||||
|
<tabstop>radiobutton_alsa_pcm</tabstop>
|
||||||
<tabstop>checkbox_volume_control</tabstop>
|
<tabstop>checkbox_volume_control</tabstop>
|
||||||
|
<tabstop>checkbox_channels</tabstop>
|
||||||
|
<tabstop>spinbox_channels</tabstop>
|
||||||
<tabstop>spinbox_bufferduration</tabstop>
|
<tabstop>spinbox_bufferduration</tabstop>
|
||||||
<tabstop>spinbox_low_watermark</tabstop>
|
<tabstop>spinbox_low_watermark</tabstop>
|
||||||
<tabstop>spinbox_high_watermark</tabstop>
|
<tabstop>spinbox_high_watermark</tabstop>
|
||||||
|
@ -716,12 +728,12 @@
|
||||||
<slot>setEnabled(bool)</slot>
|
<slot>setEnabled(bool)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>89</x>
|
<x>110</x>
|
||||||
<y>259</y>
|
<y>465</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>143</x>
|
<x>164</x>
|
||||||
<y>285</y>
|
<y>573</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
|
Loading…
Reference in New Issue