Commit f586f249 authored by Alf Gaida's avatar Alf Gaida

Adding upstream version 0.1.0.

parents
ABOUT-NLS
ChangeLog
*~
config.guess
config.rpath
config.sub
intltool-extract.in
intltool-merge.in
intltool-update.in
aclocal.m4
*.cache
compile
config.h
config.h.in
config.log
config.status
configure
depcomp
README
README.html
install-sh
missing
*.o
stamp*
Makefile
Makefile.in
.deps
*.tar.gz
*.swp
This is the Qt port of pavucontrol <https://freedesktop.org/software/pulseaudio/pavucontrol/>.
The original authors of the gtk+ version of pavucontrol are:
* Copyright 2006-2009 Lennart Poettering
* Copyright 2009-2011 Colin Guthrie <mzcnihpbageby (at) 0pointer (dot) de>
The Qt port pavucontrol-qt is derived from the gtk+ version.
It's done by LXQt developers:
* Copyright 2016 Hong Jen-Yee (PCMan) <pcman.tw@gmail.com>
This diff is collapsed.
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(pavucontrol-qt)
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
include(GNUInstallDirs)
find_package(Qt5Widgets REQUIRED QUIET)
find_package(Qt5LinguistTools REQUIRED QUIET)
find_package(lxqt REQUIRED QUIET)
find_package(XdgUserDirs REQUIRED QUIET)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
include(LXQtTranslate)
find_package(PkgConfig REQUIRED QUIET)
pkg_check_modules(
PULSE REQUIRED
libpulse>=5.0
libpulse-mainloop-glib>=0.9.16
)
pkg_check_modules(
GLIB REQUIRED
glib-2.0
)
add_subdirectory(src)
This diff is collapsed.
# pavucontrol-qt
## Overview
pavucontrol-qt is the Qt port of volume control [pavucontrol](https://freedesktop.org/software/pulseaudio/pavucontrol/) of sound server [PulseAudio](https://www.freedesktop.org/wiki/Software/PulseAudio/).
As such it can be used to adjust all controls provided by PulseAudio as well as some additional settings.
The software belongs to the LXQt project but its usage isn't limited to this desktop environment.
## Installation
### Compiling source code
Runtime dependencies are qtbase and PulseAudio client library libpulse.
Additional build dependencies are CMake, xdg-user-dirs and [liblxqt](https://github.com/lxde/liblxqt) as well as optionally Git to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxde/lxqt-l10n) so the corresponding dependencies are needed, too. Please refer to this repository's `README.md` for further information.
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX` has to be set to `/usr` on most operating systems.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
### Binary packages
This project was launched in August 2016 and binary packages are rare so far. On Arch Linux an [AUR](https://aur.archlinux.org/) package [pavucontrol-qt-git](https://aur.archlinux.org/packages/pavucontrol-qt-git/) can be used to build current checkouts of branch `master`.
## Usage
In LXQt sessions the binary is placed in sub-menu "Sound & Video" of the panel's main menu.
The usage itself should be self-explanatory.
pavucontrol
pavucontrol.desktop
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
include_directories(
${PULSE_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
)
set(pavucontrol-qt_HDRS
pavucontrol.h
mainwindow.h
cardwidget.h
channel.h
devicewidget.h
minimalstreamwidget.h
rolewidget.h
sinkinputwidget.h
sinkwidget.h
sourceoutputwidget.h
sourcewidget.h
streamwidget.h
)
set(pavucontrol-qt_SRCS
pavucontrol.cc
mainwindow.cc
cardwidget.cc
channel.cc
devicewidget.cc
minimalstreamwidget.cc
rolewidget.cc
sinkinputwidget.cc
sinkwidget.cc
sourceoutputwidget.cc
sourcewidget.cc
streamwidget.cc
)
set(pavucontrol-qt_UI
cardwidget.ui
devicewidget.ui
mainwindow.ui
streamwidget.ui
)
# Translations
lxqt_translate_ts(pavucontrol-qt_QM_FILES
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${pavucontrol-qt_HDRS}
${pavucontrol-qt_SRCS}
${pavucontrol-qt_UI}
INSTALL_DIR
"${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/translations"
PULL_TRANSLATIONS
${PULL_TRANSLATIONS}
CLEAN_TRANSLATIONS
${CLEAN_TRANSLATIONS}
TRANSLATIONS_REPO
${TRANSLATIONS_REPO}
TRANSLATIONS_REFSPEC
${TRANSLATIONS_REFSPEC}
)
lxqt_translate_desktop(DESKTOP_FILES
SOURCES
pavucontrol-qt.desktop.in
)
add_executable(pavucontrol-qt
${pavucontrol-qt_SRCS}
${pavucontrol-qt_QM_FILES}
${pavucontrol-qt_QM_LOADER}
${DESKTOP_FILES}
)
set_property(
TARGET pavucontrol-qt APPEND
PROPERTY COMPILE_DEFINITIONS
PAVUCONTROL_QT_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}"
)
target_link_libraries(pavucontrol-qt
Qt5::Widgets
Qt5::DBus
${PULSE_LIBRARIES}
${GLIB_LIBRARIES}
)
install(TARGETS
pavucontrol-qt
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
COMPONENT Runtime
)
install(FILES
${DESKTOP_FILES}
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
COMPONENT Runtime
)
# This file is part of pavucontrol.
#
# Copyright 2006-2008 Lennart Poettering
#
# pavucontrol 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 2 of the License, or
# (at your option) any later version.
#
# pavucontrol 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 pavucontrol. If not, see <http://www.gnu.org/licenses/>.
desktopdir = $(datadir)/applications
gladedir = $(pkgdatadir)
localedir = $(datadir)/locale
bin_PROGRAMS=pavucontrol
glade_DATA=pavucontrol.glade
desktop_in_files=pavucontrol.desktop.in
desktop_DATA=$(desktop_in_files:.desktop.in=.desktop)
pavucontrol_SOURCES= \
minimalstreamwidget.h minimalstreamwidget.cc \
channelwidget.h channelwidget.cc \
streamwidget.h streamwidget.cc \
devicewidget.h devicewidget.cc \
cardwidget.h cardwidget.cc \
sinkwidget.h sinkwidget.cc \
sourcewidget.h sourcewidget.cc \
sinkinputwidget.h sinkinputwidget.cc \
sourceoutputwidget.h sourceoutputwidget.cc \
rolewidget.h rolewidget.cc \
mainwindow.h mainwindow.cc \
pavucontrol.h pavucontrol.cc \
i18n.h
pavucontrol_LDADD=$(AM_LDADD) $(GUILIBS_LIBS) $(PULSE_LIBS)
pavucontrol_CXXFLAGS=$(AM_CXXFLAGS) $(GUILIBS_CFLAGS) $(PULSE_CFLAGS) -DLOCALEDIR=\"$(localedir)\"
pavucontrol_CXXFLAGS+=-DGLADE_FILE=\"$(gladedir)/pavucontrol.glade\"
#pavucontrol_CXXFLAGS+=-DGLADE_FILE=\"pavucontrol.glade\"
EXTRA_DIST = $(glade_DATA) $(desktop_in_files)
CLEANFILES = $(desktop_DATA)
@INTLTOOL_DESKTOP_RULE@
/***
This file is part of pavucontrol.
Copyright 2006-2008 Lennart Poettering
Copyright 2009 Colin Guthrie
pavucontrol 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 2 of the License, or
(at your option) any later version.
pavucontrol 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 pavucontrol. If not, see <http://www.gnu.org/licenses/>.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "cardwidget.h"
/*** CardWidget ***/
CardWidget::CardWidget(QWidget* parent) :
QWidget(parent) {
setupUi(this);
connect(profileList, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CardWidget::onProfileChange);
}
void CardWidget::prepareMenu() {
int idx = 0;
int active_idx = -1;
profileList->clear();
/* Fill the ComboBox */
for (uint32_t i = 0; i < profiles.size(); ++i) {
const auto& profile = profiles[i];
QByteArray name = profile.first;
QString desc = QString::fromUtf8(profile.second);
profileList->addItem(desc, name);
if (profile.first == activeProfile)
active_idx = idx;
idx++;
}
if (active_idx >= 0)
profileList->setCurrentIndex(active_idx);
}
void CardWidget::onProfileChange(int active) {
if (updating)
return;
if (active != -1) {
QString desc = profileList->itemText(active);
QByteArray name = profileList->itemData(active).toByteArray();
pa_operation* o;
if (!(o = pa_context_set_card_profile_by_index(get_context(), index, name.constData(), NULL, NULL))) {
show_error(tr("pa_context_set_card_profile_by_index() failed").toUtf8().constData());
return;
}
pa_operation_unref(o);
}
}
/***
This file is part of pavucontrol.
Copyright 2006-2008 Lennart Poettering
Copyright 2009 Colin Guthrie
pavucontrol 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 2 of the License, or
(at your option) any later version.
pavucontrol 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 pavucontrol. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef cardwidget_h
#define cardwidget_h
#include "pavucontrol.h"
#include "ui_cardwidget.h"
#include <QWidget>
class PortInfo {
public:
QByteArray name;
QByteArray description;
uint32_t priority;
int available;
int direction;
int64_t latency_offset;
std::vector<QByteArray> profiles;
};
class CardWidget : public QWidget, public Ui::CardWidget {
Q_OBJECT
public:
CardWidget(QWidget *parent = nullptr);
QByteArray name;
uint32_t index;
bool updating;
std::vector< std::pair<QByteArray,QByteArray> > profiles;
std::map<QByteArray, PortInfo> ports;
QByteArray activeProfile;
bool hasSinks;
bool hasSources;
void prepareMenu();
protected:
virtual void onProfileChange(int active);
};
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CardWidget</class>
<widget class="QWidget" name="CardWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>79</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
<item>
<widget class="QLabel" name="iconImage">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Card Name</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Profile:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="profileList"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
/***
This file is part of pavucontrol.
Copyright 2006-2008 Lennart Poettering
Copyright 2009 Colin Guthrie
pavucontrol 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 2 of the License, or
(at your option) any later version.
pavucontrol 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 pavucontrol. If not, see <http://www.gnu.org/licenses/>.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <QGridLayout>
#include <QLabel>
#include <QSlider>
#include "channel.h"
#include "minimalstreamwidget.h"
/*** ChannelWidget ***/
Channel::Channel(QGridLayout* parent) :
QObject(parent),
can_decibel(false),
volumeScaleEnabled(true),
last(false)
{
channelLabel = new QLabel(nullptr);
volumeScale = new QSlider(Qt::Horizontal, nullptr);
volumeLabel = new QLabel(nullptr);
const int row = parent->rowCount();
parent->addWidget(channelLabel, row, 0);
parent->addWidget(volumeScale, row, 1);
parent->addWidget(volumeLabel, row, 2);
volumeScale->setMinimum(PA_VOLUME_MUTED);
volumeScale->setMaximum(PA_VOLUME_UI_MAX);
volumeScale->setValue(PA_VOLUME_NORM);
volumeScale->setSingleStep(qRound((double)PA_VOLUME_NORM)/100.0);
volumeScale->setPageStep(qRound((double)PA_VOLUME_NORM)/20.0);
setBaseVolume(PA_VOLUME_NORM);
connect(volumeScale, &QSlider::valueChanged, this, &Channel::onVolumeScaleValueChanged);
}
void Channel::setVolume(pa_volume_t volume) {
double v;
char txt[64];
v = ((gdouble) volume * 100) / PA_VOLUME_NORM;
if (can_decibel) {
double dB = pa_sw_volume_to_dB(volume);
if (dB > PA_DECIBEL_MININFTY)
snprintf(txt, sizeof(txt), "<small>%0.0f%% (%0.2fdB)</small>", v, dB);
else
snprintf(txt, sizeof(txt), "<small>%0.0f%% (-&#8734;dB)</small>", v);
}
else
snprintf(txt, sizeof(txt), "%0.0f%%", v);
volumeLabel->setText(QString::fromUtf8(txt));
volumeScaleEnabled = false;
volumeScale->setValue(volume > PA_VOLUME_UI_MAX ? PA_VOLUME_UI_MAX : volume);
volumeScaleEnabled = true;
}
void Channel::setVisible(bool visible)
{
channelLabel->setVisible(visible);
volumeScale->setVisible(visible);
volumeLabel->setVisible(visible);
}
void Channel::setEnabled(bool enabled)
{
channelLabel->setEnabled(enabled);
volumeScale->setEnabled(enabled);
volumeLabel->setEnabled(enabled);
}
void Channel::onVolumeScaleValueChanged(int value) {
if (!volumeScaleEnabled)
return;
if (minimalStreamWidget->updating)
return;
pa_volume_t volume = (pa_volume_t) volumeScale->value();
minimalStreamWidget->updateChannelVolume(channel, volume);
}
/*
void Channel::set_sensitive(bool enabled) {
setEnabled(enabled);
channelLabel->setEnabled(enabled);
volumeLabel->setEnabled(enabled);
volumeScale->setEnabled(enabled);
}
*/
void Channel::setBaseVolume(pa_volume_t v) {
#if 0 // FIXME: Qt does not support this functionality
gtk_scale_clear_marks(GTK_SCALE(volumeScale->gobj()));
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), (double)PA_VOLUME_MUTED, (GtkPositionType) GTK_POS_BOTTOM,
last ? (can_decibel ? tr("<small>Silence</small>").toUtf8().constData() : tr("<small>Min</small>").toUtf8().constData()) : NULL);
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), (double)PA_VOLUME_NORM, (GtkPositionType) GTK_POS_BOTTOM,
last ? tr("<small>100% (0dB)</small>").toUtf8().constData() : NULL);
if (v > PA_VOLUME_MUTED && v < PA_VOLUME_NORM) {
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), (double)v, (GtkPositionType) GTK_POS_BOTTOM,
last ? tr("<small><i>Base</i></small>").toUtf8().constData() : NULL);
}
#endif
}
/***
This file is part of pavucontrol.
Copyright 2006-2008 Lennart Poettering
Copyright 2009 Colin Guthrie
pavucontrol 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 2 of the License, or
(at your option) any later version.
pavucontrol 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 pavucontrol. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef channel_h
#define channel_h
#include <QObject>
#include "pavucontrol.h"
class QGridLayout;
class QLabel;
class QSlider;
class MinimalStreamWidget;
class Channel : public QObject {
Q_OBJECT
public:
Channel(QGridLayout* parent=nullptr);
void setVolume(pa_volume_t volume);
void setVisible(bool visible);
void setEnabled(bool enabled);
int channel;
MinimalStreamWidget *minimalStreamWidget;
protected Q_SLOTS:
void onVolumeScaleValueChanged(int value);
public:
bool can_decibel;
bool volumeScaleEnabled;
bool last;
QLabel *channelLabel;
QSlider *volumeScale;
QLabel *volumeLabel;
//virtual void set_sensitive(bool enabled);
virtual void setBaseVolume(pa_volume_t);
};
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChannelWidget</class>
<widget class="QWidget" name="ChannelWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>34</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="channelLabel">
<property name="text">
<string>&lt;b&gt;left-front&lt;/b&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="volumeScale">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="volumeLabel">
<property name="text">
<string>&lt;small&gt;50%&lt;/small&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
/***
This file is part of pavucontrol.
Copyright 2006-2008 Lennart Poettering
Copyright 2009 Colin Guthrie
pavucontrol 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 2 of the License, or
(at your option) any later version.
pavucontrol 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 pavucontrol. If not, see <http://www.gnu.org/licenses/>.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pulse/ext-device-manager.h>
#include "mainwindow.h"
#include "devicewidget.h"
#include "channel.h"
#include <sstream>
#include <QLabel>
/*** DeviceWidget ***/
DeviceWidget::DeviceWidget(MainWindow* parent, QByteArray deviceType) :
MinimalStreamWidget(parent),
offsetButtonEnabled(false),
mpMainWindow(parent),
mDeviceType(deviceType) {
setupUi(this);
advancedWidget->hide();
initPeakProgressBar(channelsGrid);
timeout.setSingleShot(true);
timeout.setInterval(100);
connect(&timeout, &QTimer::timeout, this, &DeviceWidget::timeoutEvent);
// FIXME: this->signal_button_press_event().connect(sigc::mem_fun(*this, &DeviceWidget::onContextTriggerEvent));
connect(muteToggleButton, &QToolButton::toggled, this, &DeviceWidget::onMuteToggleButton);
connect(lockToggleButton, &QToolButton::toggled, this, &DeviceWidget::onLockToggleButton);
connect(defaultToggleButton, &QToolButton::toggled, this, &DeviceWidget::onDefaultToggleButton);
#if 0
rename.set_label(tr("Rename Device...").toUtf8().constData());
rename.signal_activate().connect(sigc::mem_fun(*this, &DeviceWidget::renamePopup));
contextMenu.append(rename);
contextMenu.show_all();
#endif