From fb190340a368ba1d7de09733b088bc2d77232b13 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sat, 18 Apr 2020 20:12:29 +0200 Subject: [PATCH] Add the smoother demo client --- tests/CMakeLists.txt | 5 ++ tests/DemoSmooth.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++ tests/DemoSmooth.ui | 40 +++++++++++ 3 files changed, 200 insertions(+) create mode 100644 tests/DemoSmooth.cpp create mode 100644 tests/DemoSmooth.ui diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d3f32fe4..67a0947e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -54,6 +54,11 @@ if(JACK_FOUND AND TARGET Qt5::Widgets) target_link_libraries(sfizz_demo_filters PRIVATE sfizz::sfizz Qt5::Widgets ${JACK_LIBRARIES}) set_target_properties(sfizz_demo_filters PROPERTIES AUTOUIC ON) + add_executable(sfizz_demo_smooth DemoSmooth.cpp) + target_include_directories(sfizz_demo_smooth PRIVATE ${JACK_INCLUDE_DIRS}) + target_link_libraries(sfizz_demo_smooth PRIVATE sfizz::sfizz Qt5::Widgets ${JACK_LIBRARIES}) + set_target_properties(sfizz_demo_smooth PROPERTIES AUTOUIC ON) + add_executable(sfizz_demo_stereo DemoStereo.cpp) target_include_directories(sfizz_demo_stereo PRIVATE ${JACK_INCLUDE_DIRS}) target_link_libraries(sfizz_demo_stereo PRIVATE sfizz::sfizz Qt5::Widgets ${JACK_LIBRARIES}) diff --git a/tests/DemoSmooth.cpp b/tests/DemoSmooth.cpp new file mode 100644 index 00000000..e9b7d68c --- /dev/null +++ b/tests/DemoSmooth.cpp @@ -0,0 +1,155 @@ +// 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/Smoothers.h" +#include "sfizz/MathHelpers.h" +#include "ui_DemoSmooth.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/// +struct jack_delete { + void operator()(jack_client_t* x) const noexcept { jack_client_close(x); } +}; + +typedef std::unique_ptr 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 valueChangedSmooth(int value); + +private: + QMainWindow* fWindow = nullptr; + Ui::DemoSmoothWindow fUi; + + static constexpr int smoothMin = 0; + static constexpr int smoothMax = 100; + + int fSmooth = 0; + + sfz::Smoother fFilter; + + jack_client_u fClient; + jack_port_t* fPorts[2] = {}; +}; + +DemoApp::DemoApp(int& argc, char** argv) + : QApplication(argc, argv) +{ + setApplicationName(tr("Sfizz Smooth")); +} + +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.setSmoothing(fSmooth, sampleRate); + + fPorts[0] = jack_port_register(client, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + fPorts[1] = jack_port_register(client, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + + if (!(fPorts[0] && fPorts[1])) { + 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()); + + fUi.dialSmooth->setRange(smoothMin, smoothMax); + fUi.spinSmooth->setRange(smoothMin, smoothMax); + + fUi.dialSmooth->setValue(fSmooth); + fUi.spinSmooth->setValue(fSmooth); + + connect( + fUi.dialSmooth, &QDial::valueChanged, + this, [this](int value) { valueChangedSmooth(value); }); + connect( + fUi.spinSmooth, QOverload::of(&QSpinBox::valueChanged), + this, [this](int value) { valueChangedSmooth(value); }); + + window->adjustSize(); + window->setFixedSize(window->size()); + + window->show(); +} + +int DemoApp::processAudio(jack_nframes_t nframes, void* cbdata) +{ + DemoApp* self = reinterpret_cast(cbdata); + + const float* in = reinterpret_cast(jack_port_get_buffer(self->fPorts[0], nframes)); + float* out = reinterpret_cast(jack_port_get_buffer(self->fPorts[1], nframes)); + + self->fFilter.process(absl::MakeSpan(in, nframes), absl::MakeSpan(out, nframes)); + return 0; +} + +void DemoApp::valueChangedSmooth(int value) +{ + fUi.dialSmooth->blockSignals(true); + fUi.dialSmooth->setValue(value); + fUi.dialSmooth->blockSignals(false); + + fUi.spinSmooth->blockSignals(true); + fUi.spinSmooth->setValue(value); + fUi.spinSmooth->blockSignals(false); + + fSmooth = value; + + double sampleRate = jack_get_sample_rate(fClient.get()); + fFilter.setSmoothing(fSmooth, sampleRate); +} + +int main(int argc, char* argv[]) +{ + DemoApp app(argc, argv); + + if (!app.initSound()) + return 1; + + app.initWindow(); + + return app.exec(); +} diff --git a/tests/DemoSmooth.ui b/tests/DemoSmooth.ui new file mode 100644 index 00000000..4cb2db02 --- /dev/null +++ b/tests/DemoSmooth.ui @@ -0,0 +1,40 @@ + + + DemoSmoothWindow + + + + 0 + 0 + 118 + 169 + + + + + + + + Qt::AlignCenter + + + + + + + + + + Smooth + + + Qt::AlignCenter + + + + + + + + +