Add a filter demo program
This commit is contained in:
parent
d12b3f490d
commit
39e150f3d0
3 changed files with 577 additions and 0 deletions
|
|
@ -31,4 +31,17 @@ target_link_libraries(sfizz_tests PRIVATE sfizz::sfizz)
|
|||
sfizz_enable_lto_if_needed(sfizz_tests)
|
||||
# target_link_libraries(sfizz_tests PRIVATE absl::strings absl::str_format absl::flat_hash_map cnpy absl::span absl::algorithm)
|
||||
|
||||
find_package(PkgConfig)
|
||||
if(PKGCONFIG_FOUND)
|
||||
pkg_check_modules(JACK "jack")
|
||||
endif()
|
||||
find_package(Qt5 COMPONENTS Widgets)
|
||||
|
||||
if(JACK_FOUND AND TARGET Qt5::Widgets)
|
||||
add_executable(sfizz_demo_filters DemoFilters.cpp)
|
||||
target_include_directories(sfizz_demo_filters PRIVATE ${JACK_INCLUDE_DIRS})
|
||||
target_link_libraries(sfizz_demo_filters PRIVATE sfizz::sfizz Qt5::Widgets ${JACK_LIBRARIES})
|
||||
set_target_properties(sfizz_demo_filters PROPERTIES AUTOUIC ON)
|
||||
endif()
|
||||
|
||||
file(COPY "." DESTINATION ${CMAKE_BINARY_DIR}/tests)
|
||||
|
|
|
|||
325
tests/DemoFilters.cpp
Normal file
325
tests/DemoFilters.cpp
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#include "sfizz/SfzFilter.h"
|
||||
#include "ui_DemoFilters.h"
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QButtonGroup>
|
||||
#include <QDebug>
|
||||
#include <jack/jack.h>
|
||||
#include <memory>
|
||||
|
||||
///
|
||||
struct jack_delete {
|
||||
void operator()(jack_client_t *x) const noexcept { jack_client_close(x); }
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<jack_client_t, jack_delete> jack_client_u;
|
||||
|
||||
///
|
||||
class DemoApp : public QApplication {
|
||||
public:
|
||||
DemoApp(int &argc, char **argv);
|
||||
bool initSound();
|
||||
void initWindow();
|
||||
|
||||
private:
|
||||
static int processAudio(jack_nframes_t nframes, void *cbdata);
|
||||
|
||||
private:
|
||||
void valueChangedType(int value);
|
||||
void valueChangedCutoff(int value);
|
||||
void valueChangedResonance(int value);
|
||||
void valueChangedPkShGain(int value);
|
||||
void valueChangedBandwidth(int value);
|
||||
void valueChangedFilterMode(int value);
|
||||
|
||||
private:
|
||||
QMainWindow *fWindow = nullptr;
|
||||
Ui::DemoFiltersWindow fUi;
|
||||
|
||||
static constexpr int cutoffMin = 10.0;
|
||||
static constexpr int cutoffMax = 20000.0;
|
||||
|
||||
static constexpr int resoMin = 0.0;
|
||||
static constexpr int resoMax = 40.0;
|
||||
|
||||
static constexpr int pkshMin = -40.0;
|
||||
static constexpr int pkshMax = 40.0;
|
||||
|
||||
static constexpr int bwMin = 1.0;
|
||||
static constexpr int bwMax = 10.0;
|
||||
|
||||
int fType = sfz::kFilterNone;
|
||||
int fCutoff = 500.0;
|
||||
int fReso = 0.0;
|
||||
int fPksh = 20.0;
|
||||
int fBw = 1.0;
|
||||
|
||||
sfz::Filter fFilter;
|
||||
sfz::FilterEq fFilterEq;
|
||||
|
||||
enum FilterMode {
|
||||
kFilterModeMulti,
|
||||
kFilterModeEq,
|
||||
};
|
||||
FilterMode fFilterMode = kFilterModeMulti;
|
||||
|
||||
jack_client_u fClient;
|
||||
jack_port_t *fPorts[4] = {};
|
||||
};
|
||||
|
||||
DemoApp::DemoApp(int &argc, char **argv)
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
setApplicationName(tr("Sfizz Filters"));
|
||||
}
|
||||
|
||||
bool DemoApp::initSound()
|
||||
{
|
||||
jack_client_t *client = jack_client_open(
|
||||
applicationName().toUtf8().data(), JackNoStartServer, nullptr);
|
||||
if (!client) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("Cannot open JACK audio."));
|
||||
return false;
|
||||
}
|
||||
|
||||
fClient.reset(client);
|
||||
|
||||
double sampleRate = jack_get_sample_rate(client);
|
||||
|
||||
fFilter.init(sampleRate);
|
||||
fFilter.setChannels(2);
|
||||
|
||||
fFilterEq.init(sampleRate);
|
||||
fFilterEq.setChannels(2);
|
||||
|
||||
fPorts[0] = jack_port_register(client, "in_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
|
||||
fPorts[1] = jack_port_register(client, "in_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
|
||||
fPorts[2] = jack_port_register(client, "out_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
|
||||
fPorts[3] = jack_port_register(client, "out_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
|
||||
|
||||
if (!(fPorts[0] && fPorts[1] && fPorts[2] && fPorts[3])) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("Cannot register JACK ports."));
|
||||
return false;
|
||||
}
|
||||
|
||||
jack_set_process_callback(client, &processAudio, this);
|
||||
|
||||
if (jack_activate(client) != 0) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("Cannot activate JACK client."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DemoApp::initWindow()
|
||||
{
|
||||
QMainWindow *window = new QMainWindow;
|
||||
fWindow = window;
|
||||
fUi.setupUi(window);
|
||||
window->setWindowTitle(applicationDisplayName());
|
||||
|
||||
QComboBox *cbTypes = fUi.comboBox;
|
||||
cbTypes->addItem("None", static_cast<int>(sfz::kFilterNone));
|
||||
cbTypes->addItem("Apf1p", static_cast<int>(sfz::kFilterApf1p));
|
||||
cbTypes->addItem("Bpf1p", static_cast<int>(sfz::kFilterBpf1p));
|
||||
cbTypes->addItem("Bpf2p", static_cast<int>(sfz::kFilterBpf2p));
|
||||
cbTypes->addItem("Bpf4p", static_cast<int>(sfz::kFilterBpf4p));
|
||||
cbTypes->addItem("Bpf6p", static_cast<int>(sfz::kFilterBpf6p));
|
||||
cbTypes->addItem("Brf1p", static_cast<int>(sfz::kFilterBrf1p));
|
||||
cbTypes->addItem("Brf2p", static_cast<int>(sfz::kFilterBrf2p));
|
||||
cbTypes->addItem("Hpf1p", static_cast<int>(sfz::kFilterHpf1p));
|
||||
cbTypes->addItem("Hpf2p", static_cast<int>(sfz::kFilterHpf2p));
|
||||
cbTypes->addItem("Hpf4p", static_cast<int>(sfz::kFilterHpf4p));
|
||||
cbTypes->addItem("Hpf6p", static_cast<int>(sfz::kFilterHpf6p));
|
||||
cbTypes->addItem("Lpf1p", static_cast<int>(sfz::kFilterLpf1p));
|
||||
cbTypes->addItem("Lpf2p", static_cast<int>(sfz::kFilterLpf2p));
|
||||
cbTypes->addItem("Lpf4p", static_cast<int>(sfz::kFilterLpf4p));
|
||||
cbTypes->addItem("Lpf6p", static_cast<int>(sfz::kFilterLpf6p));
|
||||
cbTypes->addItem("Pink", static_cast<int>(sfz::kFilterPink));
|
||||
cbTypes->addItem("Lpf2pSv", static_cast<int>(sfz::kFilterLpf2pSv));
|
||||
cbTypes->addItem("Hpf2pSv", static_cast<int>(sfz::kFilterHpf2pSv));
|
||||
cbTypes->addItem("Bpf2pSv", static_cast<int>(sfz::kFilterBpf2pSv));
|
||||
cbTypes->addItem("Brf2pSv", static_cast<int>(sfz::kFilterBrf2pSv));
|
||||
cbTypes->addItem("Lsh", static_cast<int>(sfz::kFilterLsh));
|
||||
cbTypes->addItem("Hsh", static_cast<int>(sfz::kFilterHsh));
|
||||
cbTypes->addItem("Peq", static_cast<int>(sfz::kFilterPeq));
|
||||
|
||||
cbTypes->setCurrentIndex(cbTypes->findData(fType));
|
||||
fUi.lcdType->display(fType);
|
||||
|
||||
connect(
|
||||
cbTypes, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, [this, cbTypes](int index) { valueChangedType(cbTypes->itemData(index).toInt()); });
|
||||
|
||||
fUi.dialCutoff->setRange(cutoffMin, cutoffMax);
|
||||
fUi.dialResonance->setRange(resoMin, resoMax);
|
||||
fUi.dialPkShGain->setRange(pkshMin, pkshMax);
|
||||
fUi.dialBandwidth->setRange(bwMin, bwMax);
|
||||
fUi.spinCutoff->setRange(cutoffMin, cutoffMax);
|
||||
fUi.spinResonance->setRange(resoMin, resoMax);
|
||||
fUi.spinPkShGain->setRange(pkshMin, pkshMax);
|
||||
fUi.spinBandwidth->setRange(bwMin, bwMax);
|
||||
|
||||
fUi.dialCutoff->setValue(fCutoff);
|
||||
fUi.dialResonance->setValue(fReso);
|
||||
fUi.dialPkShGain->setValue(fPksh);
|
||||
fUi.dialBandwidth->setValue(fBw);
|
||||
fUi.spinCutoff->setValue(fCutoff);
|
||||
fUi.spinResonance->setValue(fReso);
|
||||
fUi.spinPkShGain->setValue(fPksh);
|
||||
fUi.spinBandwidth->setValue(fBw);
|
||||
|
||||
connect(
|
||||
fUi.dialCutoff, &QDial::valueChanged,
|
||||
this, [this](int value) { valueChangedCutoff(value); });
|
||||
connect(
|
||||
fUi.spinCutoff, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, [this](int value) { valueChangedCutoff(value); });
|
||||
connect(
|
||||
fUi.dialResonance, &QDial::valueChanged,
|
||||
this, [this](int value) { valueChangedResonance(value); });
|
||||
connect(
|
||||
fUi.spinResonance, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, [this](int value) { valueChangedResonance(value); });
|
||||
connect(
|
||||
fUi.dialPkShGain, &QDial::valueChanged,
|
||||
this, [this](int value) { valueChangedPkShGain(value); });
|
||||
connect(
|
||||
fUi.spinPkShGain, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, [this](int value) { valueChangedPkShGain(value); });
|
||||
connect(
|
||||
fUi.dialBandwidth, &QDial::valueChanged,
|
||||
this, [this](int value) { valueChangedBandwidth(value); });
|
||||
connect(
|
||||
fUi.spinBandwidth, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, [this](int value) { valueChangedBandwidth(value); });
|
||||
|
||||
QButtonGroup *grpMode = new QButtonGroup(this);
|
||||
grpMode->addButton(fUi.btnMultiMode, kFilterModeMulti);
|
||||
grpMode->addButton(fUi.btnEqMode, kFilterModeEq);
|
||||
fUi.btnMultiMode->setChecked(true);
|
||||
grpMode->setExclusive(true);
|
||||
|
||||
connect(
|
||||
grpMode, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this,
|
||||
[this](int id, bool toggled) {
|
||||
if (toggled)
|
||||
valueChangedFilterMode(id);
|
||||
});
|
||||
|
||||
window->adjustSize();
|
||||
window->setFixedSize(window->size());
|
||||
|
||||
window->show();
|
||||
}
|
||||
|
||||
int DemoApp::processAudio(jack_nframes_t nframes, void *cbdata)
|
||||
{
|
||||
DemoApp *self = reinterpret_cast<DemoApp *>(cbdata);
|
||||
|
||||
const float *ins[2];
|
||||
float *outs[2];
|
||||
|
||||
ins[0] = reinterpret_cast<float *>(jack_port_get_buffer(self->fPorts[0], nframes));
|
||||
ins[1] = reinterpret_cast<float *>(jack_port_get_buffer(self->fPorts[1], nframes));
|
||||
outs[0] = reinterpret_cast<float *>(jack_port_get_buffer(self->fPorts[2], nframes));
|
||||
outs[1] = reinterpret_cast<float *>(jack_port_get_buffer(self->fPorts[3], nframes));
|
||||
|
||||
switch (self->fFilterMode) {
|
||||
default:
|
||||
case kFilterModeMulti:
|
||||
self->fFilter.setType(static_cast<sfz::FilterType>(self->fType));
|
||||
self->fFilter.process(ins, outs, self->fCutoff, self->fReso, self->fPksh, nframes);
|
||||
break;
|
||||
case kFilterModeEq:
|
||||
self->fFilterEq.process(ins, outs, self->fCutoff, self->fBw, self->fPksh, nframes);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DemoApp::valueChangedType(int value)
|
||||
{
|
||||
fType = value;
|
||||
fUi.lcdType->display(value);
|
||||
}
|
||||
|
||||
void DemoApp::valueChangedCutoff(int value)
|
||||
{
|
||||
fUi.dialCutoff->blockSignals(true);
|
||||
fUi.dialCutoff->setValue(value);
|
||||
fUi.dialCutoff->blockSignals(false);
|
||||
|
||||
fUi.spinCutoff->blockSignals(true);
|
||||
fUi.spinCutoff->setValue(value);
|
||||
fUi.spinCutoff->blockSignals(false);
|
||||
|
||||
fCutoff = value;
|
||||
}
|
||||
|
||||
void DemoApp::valueChangedResonance(int value)
|
||||
{
|
||||
fUi.dialResonance->blockSignals(true);
|
||||
fUi.dialResonance->setValue(value);
|
||||
fUi.dialResonance->blockSignals(false);
|
||||
|
||||
fUi.spinResonance->blockSignals(true);
|
||||
fUi.spinResonance->setValue(value);
|
||||
fUi.spinResonance->blockSignals(false);
|
||||
|
||||
fReso = value;
|
||||
}
|
||||
|
||||
void DemoApp::valueChangedPkShGain(int value)
|
||||
{
|
||||
fUi.dialPkShGain->blockSignals(true);
|
||||
fUi.dialPkShGain->setValue(value);
|
||||
fUi.dialPkShGain->blockSignals(false);
|
||||
|
||||
fUi.spinPkShGain->blockSignals(true);
|
||||
fUi.spinPkShGain->setValue(value);
|
||||
fUi.spinPkShGain->blockSignals(false);
|
||||
|
||||
fPksh = value;
|
||||
}
|
||||
|
||||
void DemoApp::valueChangedBandwidth(int value)
|
||||
{
|
||||
fUi.dialBandwidth->blockSignals(true);
|
||||
fUi.dialBandwidth->setValue(value);
|
||||
fUi.dialBandwidth->blockSignals(false);
|
||||
|
||||
fUi.spinBandwidth->blockSignals(true);
|
||||
fUi.spinBandwidth->setValue(value);
|
||||
fUi.spinBandwidth->blockSignals(false);
|
||||
|
||||
fBw = value;
|
||||
}
|
||||
|
||||
void DemoApp::valueChangedFilterMode(int value)
|
||||
{
|
||||
fUi.stackedWidget->setCurrentIndex(value);
|
||||
|
||||
fFilterMode = static_cast<FilterMode>(value);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
DemoApp app(argc, argv);
|
||||
|
||||
if (!app.initSound())
|
||||
return 1;
|
||||
|
||||
app.initWindow();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
239
tests/DemoFilters.ui
Normal file
239
tests/DemoFilters.ui
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DemoFiltersWindow</class>
|
||||
<widget class="QMainWindow" name="DemoFiltersWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>415</width>
|
||||
<height>216</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QDial" name="dialCutoff"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDial" name="dialPkShGain"/>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="3">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="widget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<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 row="0" column="0">
|
||||
<widget class="QDial" name="dialResonance"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLCDNumber" name="lcdType">
|
||||
<property name="digitCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QSpinBox" name="spinResonance">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Resonance</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget">
|
||||
<layout class="QGridLayout" name="gridLayout_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 row="0" column="0">
|
||||
<widget class="QDial" name="dialBandwidth"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Bandwidth</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QSpinBox" name="spinBandwidth">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> oct</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="3">
|
||||
<widget class="QWidget" name="widget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QSpinBox" name="spinCutoff">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinPkShGain">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Cutoff</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Peak/shelf gain</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="btnMultiMode">
|
||||
<property name="text">
|
||||
<string>Multi-mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="btnEqMode">
|
||||
<property name="text">
|
||||
<string>Equalizer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Loading…
Add table
Reference in a new issue