From 4e93f51b7515f1f73810917250f95c93c85427cb Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 31 May 2024 23:39:09 +0200 Subject: [PATCH 01/31] Adjust rendering of BarModelEditor (#7299) Adjust the rendering of BarModelEditor to make it respect logarithmic and linear models. The code now uses `inverseScaledValue` instead of `value` just like the `Knob` class does when calculating the angle. --- src/gui/widgets/BarModelEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/BarModelEditor.cpp b/src/gui/widgets/BarModelEditor.cpp index 4b02c9634..ae224530d 100644 --- a/src/gui/widgets/BarModelEditor.cpp +++ b/src/gui/widgets/BarModelEditor.cpp @@ -86,7 +86,7 @@ void BarModelEditor::paintEvent(QPaintEvent *event) // Paint the bar // Compute the percentage as: // min + x * (max - min) = v <=> x = (v - min) / (max - min) - auto const percentage = range == 0 ? 1. : (mod->value() - minValue) / range; + auto const percentage = range == 0 ? 1. : (model()->inverseScaledValue(model()->value()) - minValue) / range; int const margin = 3; QMargins const margins(margin, margin, margin, margin); From 042f8ac32539fec6eb90bbaacfac0db2be896e4e Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 1 Jun 2024 12:09:47 +0200 Subject: [PATCH 02/31] Add peak indicators (#7295) Add peak indicators to the mixer strips. They show the maximum peak value that was observed and can be reset by clicking on them. ## Implementation details The implementation works via a signal/slot mechanism. The `Fader` class has a new signal `peakChanged` which reports peak values as amplifications. A new class `PeakIndicator` is added which has a slot `updatePeak` which is connected to the new signal in `Fader`. The `PeakIndicator` inherits from `QLabel` and mainly deals with updating the label text from the current peak value. Add a `PeakIndicator` instance to `MixerChannelView`. Add a `reset` method to `MixerChannelView` so that the mixer channel can be reset on the loading of new projects, etc. The current implementation resets the peak indicator back to -inf dbFS. The `reset` method is called in `MixerView::clear`. Remove the clamping in `Fader::setPeak` so that all peaks are reported. Emit the new signal if the peak changes. --- data/themes/classic/style.css | 5 ++ data/themes/default/style.css | 5 ++ include/Fader.h | 3 ++ include/MixerChannelView.h | 5 ++ include/PeakIndicator.h | 60 ++++++++++++++++++++++ src/gui/CMakeLists.txt | 1 + src/gui/MixerChannelView.cpp | 10 ++++ src/gui/MixerView.cpp | 2 + src/gui/widgets/Fader.cpp | 4 +- src/gui/widgets/PeakIndicator.cpp | 84 +++++++++++++++++++++++++++++++ 10 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 include/PeakIndicator.h create mode 100644 src/gui/widgets/PeakIndicator.cpp diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 5489a7d21..95737ed3a 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -661,6 +661,11 @@ lmms--gui--MixerChannelView QGraphicsView { border-style: none; } +lmms--gui--PeakIndicator { + background-color: #111811; + font-size: 7pt; +} + /* persistent peak markers for fx peak meters */ lmms--gui--Fader { qproperty-peakOk: rgb( 74, 253, 133); diff --git a/data/themes/default/style.css b/data/themes/default/style.css index a4f94de09..ef98c0609 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -710,6 +710,11 @@ lmms--gui--MixerChannelView QGraphicsView { border-style: none; } +lmms--gui--PeakIndicator { + background-color: #111811; + font-size: 7pt; +} + /* persistent peak markers for fx peak meters */ lmms--gui--Fader { qproperty-peakOk: #0ad45c; diff --git a/include/Fader.h b/include/Fader.h index a3158a8b4..53e353a3d 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -105,6 +105,9 @@ public: setUnit(txt_after); } +signals: + void peakChanged(float peak); + private: void contextMenuEvent(QContextMenuEvent* me) override; void mousePressEvent(QMouseEvent* ev) override; diff --git a/include/MixerChannelView.h b/include/MixerChannelView.h index cbaf0ccc6..7ccb8a24f 100644 --- a/include/MixerChannelView.h +++ b/include/MixerChannelView.h @@ -45,6 +45,8 @@ namespace lmms namespace lmms::gui { + class PeakIndicator; + constexpr int MIXER_CHANNEL_INNER_BORDER_SIZE = 3; constexpr int MIXER_CHANNEL_OUTER_BORDER_SIZE = 1; @@ -90,6 +92,8 @@ namespace lmms::gui QColor strokeInnerInactive() const; void setStrokeInnerInactive(const QColor& c); + void reset(); + public slots: void renameChannel(); void resetColor(); @@ -119,6 +123,7 @@ namespace lmms::gui QLabel* m_receiveArrow; PixmapButton* m_muteButton; PixmapButton* m_soloButton; + PeakIndicator* m_peakIndicator = nullptr; Fader* m_fader; EffectRackView* m_effectRackView; MixerView* m_mixerView; diff --git a/include/PeakIndicator.h b/include/PeakIndicator.h new file mode 100644 index 000000000..2bc912292 --- /dev/null +++ b/include/PeakIndicator.h @@ -0,0 +1,60 @@ +/* + * PeakIndicator.h - Peak indicator widget + * + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef LMMS_GUI_PEAKINDICATOR_H +#define LMMS_GUI_PEAKINDICATOR_H + +#include "lmms_export.h" + +#include + + +namespace lmms::gui +{ + +class LMMS_EXPORT PeakIndicator : public QLabel +{ + Q_OBJECT +public: + PeakIndicator(QWidget* parent); + + void resetPeakToMinusInf(); + +public slots: + void updatePeak(float peak); + +protected: + void mousePressEvent(QMouseEvent* e) override; + +private: + void updatePeakDisplay(); + +private: + float m_peak; +} ; + +} // namespace lmms::gui + +#endif // LMMS_GUI_PEAKINDICATOR_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 2485b92d2..4195ec58c 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -117,6 +117,7 @@ SET(LMMS_SRCS gui/widgets/MixerChannelLcdSpinBox.cpp gui/widgets/NStateButton.cpp gui/widgets/Oscilloscope.cpp + gui/widgets/PeakIndicator.cpp gui/widgets/PixmapButton.cpp gui/widgets/SimpleTextFloat.cpp gui/widgets/TabBar.cpp diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index 0afdb684e..2a1fe0928 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -28,6 +28,7 @@ #include "Mixer.h" #include "MixerChannelView.h" #include "MixerView.h" +#include "PeakIndicator.h" #include "Song.h" #include "ConfigManager.h" @@ -121,6 +122,9 @@ namespace lmms::gui m_fader = new Fader{&mixerChannel->m_volumeModel, tr("Fader %1").arg(channelIndex), this}; + m_peakIndicator = new PeakIndicator(this); + connect(m_fader, &Fader::peakChanged, m_peakIndicator, &PeakIndicator::updatePeak); + m_effectRackView = new EffectRackView{&mixerChannel->m_fxChain, mixerView->m_racksWidget}; m_effectRackView->setFixedWidth(EffectRackView::DEFAULT_WIDTH); @@ -133,6 +137,7 @@ namespace lmms::gui mainLayout->addWidget(m_channelNumberLcd, 0, Qt::AlignHCenter); mainLayout->addWidget(m_renameLineEditView, 0, Qt::AlignHCenter); mainLayout->addLayout(soloMuteLayout, 0); + mainLayout->addWidget(m_peakIndicator); mainLayout->addWidget(m_fader, 1, Qt::AlignHCenter); connect(m_renameLineEdit, &QLineEdit::editingFinished, this, &MixerChannelView::renameFinished); @@ -340,6 +345,11 @@ namespace lmms::gui m_strokeInnerInactive = c; } + void MixerChannelView::reset() + { + m_peakIndicator->resetPeakToMinusInf(); + } + void MixerChannelView::renameChannel() { m_inRename = true; diff --git a/src/gui/MixerView.cpp b/src/gui/MixerView.cpp index b9a698a96..8152509f8 100644 --- a/src/gui/MixerView.cpp +++ b/src/gui/MixerView.cpp @@ -544,6 +544,8 @@ void MixerView::clear() for (auto i = m_mixerChannelViews.size() - 1; i > 0; --i) { deleteChannel(i); } getMixer()->clearChannel(0); + m_mixerChannelViews[0]->reset(); + refreshDisplay(); } diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index d2d7c1c2e..24b16bfe4 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -207,8 +207,6 @@ void Fader::wheelEvent (QWheelEvent* ev) /// void Fader::setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElapsedTimer& lastPeakTimer) { - fPeak = std::clamp(fPeak, m_fMinPeak, m_fMaxPeak); - if (targetPeak != fPeak) { targetPeak = fPeak; @@ -216,6 +214,7 @@ void Fader::setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElap { persistentPeak = targetPeak; lastPeakTimer.restart(); + emit peakChanged(persistentPeak); } update(); } @@ -223,6 +222,7 @@ void Fader::setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElap if (persistentPeak > 0 && lastPeakTimer.elapsed() > 1500) { persistentPeak = qMax(0, persistentPeak-0.05); + emit peakChanged(persistentPeak); update(); } } diff --git a/src/gui/widgets/PeakIndicator.cpp b/src/gui/widgets/PeakIndicator.cpp new file mode 100644 index 000000000..e1278b7ff --- /dev/null +++ b/src/gui/widgets/PeakIndicator.cpp @@ -0,0 +1,84 @@ +/* + * PeakIndicator.cpp - Peak indicator widget + * + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "PeakIndicator.h" + +#include "lmms_math.h" + +#include +#include + + +namespace lmms::gui +{ + +PeakIndicator::PeakIndicator(QWidget* parent) : + QLabel(parent), + m_peak(0.f) +{ + setAlignment(Qt::AlignCenter); + + updatePeakDisplay(); +} + +void PeakIndicator::resetPeakToMinusInf() +{ + m_peak = 0; + updatePeakDisplay(); +} + +void PeakIndicator::updatePeak(float peak) +{ + if (peak > m_peak) + { + m_peak = peak; + updatePeakDisplay(); + } +} + +void PeakIndicator::mousePressEvent(QMouseEvent* e) +{ + if (e->buttons() & Qt::LeftButton) + { + resetPeakToMinusInf(); + } +} + +void PeakIndicator::updatePeakDisplay() +{ + // Treat everything below -144 dbFS as -inf. Otherwise some residual signals show up + // in the form of very small dbFS values, e.g. -857.1 dbFS. + // TODO Make the threshold configurable in the settings? + if (m_peak <= dbfsToAmp(-144.)) + { + setText(tr("-inf")); + } + else + { + auto dbfs = ampToDbfs(m_peak); + setText(QString::number(dbfs, 'f', 1)); + } +} + +} // namespace lmms::gui From 969943b335dcc65b8a71589d12ccbc5fd58dd792 Mon Sep 17 00:00:00 2001 From: Andrew Wiltshire <62200778+AW1534@users.noreply.github.com> Date: Sat, 1 Jun 2024 16:23:21 +0100 Subject: [PATCH 03/31] Change the wording of Instrument Plugin Dialogue (#7301) Drag an instrument into either the Song Editor, the Pattern Editor or ~~into~~ an existing instrument track. The word "into" seems redundant --- src/gui/PluginBrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 963609c43..2594bdab3 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -62,7 +62,7 @@ PluginBrowser::PluginBrowser( QWidget * _parent ) : auto hint = new QLabel( tr( "Drag an instrument " "into either the Song Editor, the " - "Pattern Editor or into an " + "Pattern Editor or an " "existing instrument track." ), m_view ); hint->setWordWrap( true ); From 43fbcca9cb341e7f759faf9070278fcc20b988f7 Mon Sep 17 00:00:00 2001 From: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Date: Sun, 2 Jun 2024 15:22:51 +0530 Subject: [PATCH 04/31] Modernize compiler and linker flags (#7255) --- CMakeLists.txt | 2 +- cmake/modules/BuildPlugin.cmake | 2 +- plugins/GigPlayer/CMakeLists.txt | 6 ++-- plugins/LadspaEffect/caps/CMakeLists.txt | 9 ------ plugins/LadspaEffect/swh/CMakeLists.txt | 28 +++++++++---------- .../VstBase/RemoteVstPlugin/CMakeLists.txt | 5 +--- plugins/ZynAddSubFx/CMakeLists.txt | 4 +-- 7 files changed, 21 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1da10775b..fbd9cdfcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.9) +CMAKE_MINIMUM_REQUIRED(VERSION 3.13) # Set the given policy to NEW. If it does not exist, it will not be set. If it # is already set to NEW (most likely due to predating the minimum required CMake diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index aaccd3c4b..69af41ecb 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -60,7 +60,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) IF(LMMS_BUILD_APPLE) IF ("${PLUGIN_LINK}" STREQUAL "SHARED") - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") + TARGET_LINK_OPTIONS(${PLUGIN_NAME} PRIVATE -undefined dynamic_lookup) ENDIF() ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) diff --git a/plugins/GigPlayer/CMakeLists.txt b/plugins/GigPlayer/CMakeLists.txt index 6ec8fe169..92c80fedc 100644 --- a/plugins/GigPlayer/CMakeLists.txt +++ b/plugins/GigPlayer/CMakeLists.txt @@ -4,13 +4,11 @@ if(LMMS_HAVE_GIG) SET(CMAKE_AUTOUIC ON) # Required for not crashing loading files with libgig - SET(GCC_COVERAGE_COMPILE_FLAGS "-fexceptions") - add_definitions(${GCC_COVERAGE_COMPILE_FLAGS}) + add_compile_options("-fexceptions") # disable deprecated check for mingw-x-libgig if(LMMS_BUILD_WIN32) - SET(GCC_GIG_COMPILE_FLAGS "-Wno-deprecated") - add_definitions(${GCC_GIG_COMPILE_FLAGS}) + add_compile_options("-Wno-deprecated") endif(LMMS_BUILD_WIN32) link_directories(${GIG_LIBRARY_DIRS}) diff --git a/plugins/LadspaEffect/caps/CMakeLists.txt b/plugins/LadspaEffect/caps/CMakeLists.txt index f82fa5ab0..ea2c1b7e9 100644 --- a/plugins/LadspaEffect/caps/CMakeLists.txt +++ b/plugins/LadspaEffect/caps/CMakeLists.txt @@ -27,12 +27,3 @@ IF(LMMS_BUILD_WIN32) COMMAND_EXPAND_LISTS ) ENDIF(LMMS_BUILD_WIN32) - -IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES(caps PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") -ENDIF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) - -IF(LMMS_BUILD_LINUX) - SET_TARGET_PROPERTIES(caps PROPERTIES LINK_FLAGS "${LINK_FLAGS}") -ENDIF(LMMS_BUILD_LINUX) - diff --git a/plugins/LadspaEffect/swh/CMakeLists.txt b/plugins/LadspaEffect/swh/CMakeLists.txt index 3847429d3..c71572bd2 100644 --- a/plugins/LadspaEffect/swh/CMakeLists.txt +++ b/plugins/LadspaEffect/swh/CMakeLists.txt @@ -5,16 +5,17 @@ FILE(WRITE ladspa/config.h "") IF(LMMS_BUILD_WIN32) SET(PIC_FLAGS "") ELSE() - SET(PIC_FLAGS "-fPIC -DPIC") + SET(PIC_FLAGS -fPIC -DPIC) ENDIF() # Additional compile flags if(MSVC) - set(COMPILE_FLAGS "${COMPILE_FLAGS} /wd4244 /wd4273 /wd4305") + set(COMPILE_FLAGS ${COMPILE_FLAGS} /wd4244 /wd4273 /wd4305) else() - set(COMPILE_FLAGS "${COMPILE_FLAGS} -O3 -Wall") - set(COMPILE_FLAGS "${COMPILE_FLAGS} -fomit-frame-pointer -funroll-loops -ffast-math -c -fno-strict-aliasing") - set(COMPILE_FLAGS "${COMPILE_FLAGS} ${PIC_FLAGS}") + set(COMPILE_FLAGS ${COMPILE_FLAGS} -O3 -Wall -c + -fomit-frame-pointer -funroll-loops -ffast-math -fno-strict-aliasing + ${PIC_FLAGS} + ) endif() # Loop over every XML file @@ -61,8 +62,7 @@ FOREACH(_item ${XML_SOURCES}) endif(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES PREFIX "") - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS}") - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS}") + target_compile_options("${_plugin}" PRIVATE "${COMPILE_FLAGS}") INSTALL(TARGETS "${_plugin}" LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") ENDFOREACH() @@ -75,7 +75,7 @@ INCLUDE_DIRECTORIES( ) ADD_LIBRARY(iir STATIC ladspa/util/iir.c) -SET_TARGET_PROPERTIES(iir PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +target_compile_options(iir PRIVATE "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(bandpass_a_iir_1893 iir) TARGET_LINK_LIBRARIES(bandpass_iir_1892 iir) TARGET_LINK_LIBRARIES(butterworth_1902 iir) @@ -86,23 +86,23 @@ TARGET_LINK_LIBRARIES(notch_iir_1894 iir) FILE(GLOB GSM_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/ladspa/gsm/*.c") LIST(SORT GSM_SOURCES) ADD_LIBRARY(gsm STATIC ${GSM_SOURCES}) -SET_TARGET_PROPERTIES(gsm PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +target_compile_options(gsm PRIVATE "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(gsm_1215 gsm) ADD_LIBRARY(gverb STATIC ladspa/gverb/gverb.c ladspa/gverb/gverbdsp.c) -SET_TARGET_PROPERTIES(gverb PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +target_compile_options(gverb PRIVATE "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(gverb_1216 gverb) ADD_LIBRARY(blo STATIC ladspa/util/blo.c) -SET_TARGET_PROPERTIES(blo PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +target_compile_options(blo PRIVATE "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(analogue_osc_1416 blo) TARGET_LINK_LIBRARIES(fm_osc_1415 blo) TARGET_LINK_LIBRARIES(hermes_filter_1200 blo) ADD_LIBRARY(rms STATIC ladspa/util/rms.c) ADD_LIBRARY(db STATIC ladspa/util/db.c) -SET_TARGET_PROPERTIES(rms PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") -SET_TARGET_PROPERTIES(db PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +target_compile_options(rms PRIVATE "${PIC_FLAGS}") +target_compile_options(db PRIVATE "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(sc1_1425 rms db) TARGET_LINK_LIBRARIES(sc2_1426 rms db) TARGET_LINK_LIBRARIES(sc3_1427 rms db) @@ -111,7 +111,7 @@ TARGET_LINK_LIBRARIES(sc4m_1916 rms db) TARGET_LINK_LIBRARIES(se4_1883 rms db) ADD_LIBRARY(pitchscale STATIC ladspa/util/pitchscale.c) -SET_TARGET_PROPERTIES(pitchscale PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +target_compile_options(pitchscale PRIVATE "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(pitchscale ${FFTW3F_LIBRARIES}) TARGET_LINK_LIBRARIES(pitch_scale_1193 pitchscale) TARGET_LINK_LIBRARIES(pitch_scale_1194 pitchscale) diff --git a/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt b/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt index c75b95ab7..5bcf9f065 100644 --- a/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt @@ -61,10 +61,7 @@ target_compile_definitions(${EXE_NAME} PRIVATE BUILD_REMOTE_PLUGIN_CLIENT) # Workaround for missing WinMain if(MSVC) - set_property(TARGET ${EXE_NAME} - APPEND - PROPERTY LINK_FLAGS "/entry:mainCRTStartup" -) + target_link_options(${EXE_NAME} PRIVATE "/entry:mainCRTStartup") endif() if(IS_MINGW) diff --git a/plugins/ZynAddSubFx/CMakeLists.txt b/plugins/ZynAddSubFx/CMakeLists.txt index 35dc08c4d..0f6af20ee 100644 --- a/plugins/ZynAddSubFx/CMakeLists.txt +++ b/plugins/ZynAddSubFx/CMakeLists.txt @@ -164,8 +164,8 @@ SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT "RemoteZynAddSubFx") TARGET_COMPILE_DEFINITIONS(RemoteZynAddSubFx PRIVATE BUILD_REMOTE_PLUGIN_CLIENT) IF(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES(RemoteZynAddSubFx PROPERTIES LINK_FLAGS "${LINK_FLAGS} -mwindows") -ENDIF(LMMS_BUILD_WIN32) + target_link_options(RemoteZynAddSubFx PRIVATE "-mwindows") +ENDIF() # Remove useless dependencies from FLTK. Use fltk-config to avoid static library # in older environments From b1ee6266335298780bcf89fe2b6953a9ef9aac9c Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:18:36 -0700 Subject: [PATCH 05/31] Fix noise generator (#7318) This noise generator doesn't work properly when multiple noise sources are being generated simultaneously. --- include/Oscillator.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/include/Oscillator.h b/include/Oscillator.h index ea0227bd0..e7eccea50 100644 --- a/include/Oscillator.h +++ b/include/Oscillator.h @@ -163,11 +163,7 @@ public: static inline sample_t noiseSample( const float ) { - // Precise implementation -// return 1.0f - rand() * 2.0f / RAND_MAX; - - // Fast implementation - return 1.0f - fast_rand() * 2.0f / FAST_RAND_MAX; + return 1.0f - rand() * 2.0f / RAND_MAX; } static sample_t userWaveSample(const SampleBuffer* buffer, const float sample) From beedbc18a65bda1b5137ed6395b18c82d28eacfd Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 14 Jun 2024 16:22:39 +0200 Subject: [PATCH 06/31] Add support for "factorysample:" prefix / Fix "bassloopes" typo (#7236) ## Add support for "factorysample:" prefix Add support to upgrade files with `src` tags that are prefixed with "factorysample:". ## Fix "bassloopes" typo Fix projects that still reference files with the typo "bassloopes" in their name. The upgrade is implemented in its own method because it is unrelated to the BPM renaming even if it is technically very similar in its solution. Introduce the helper method `mapSrcAttributeInElementsWithResources` which replaces the `src` attribute in elements with resources (samples and AFP) if it can be found in a map. --- include/DataFile.h | 3 + src/core/DataFile.cpp | 158 ++++++++++++++++++++++++++---------------- 2 files changed, 102 insertions(+), 59 deletions(-) diff --git a/include/DataFile.h b/include/DataFile.h index 452481a7f..5005c11bc 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -101,6 +101,8 @@ private: void cleanMetaNodes( QDomElement de ); + void mapSrcAttributeInElementsWithResources(const QMap& map); + // helper upgrade routines void upgrade_0_2_1_20070501(); void upgrade_0_2_1_20070508(); @@ -130,6 +132,7 @@ private: void upgrade_loopsRename(); void upgrade_noteTypes(); void upgrade_fixCMTDelays(); + void upgrade_fixBassLoopsTypo(); // List of all upgrade methods static const std::vector UPGRADE_METHODS; diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index b7fea852e..a55dbd82b 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -84,7 +84,7 @@ const std::vector DataFile::UPGRADE_METHODS = { &DataFile::upgrade_mixerRename , &DataFile::upgrade_bbTcoRename, &DataFile::upgrade_sampleAndHold , &DataFile::upgrade_midiCCIndexing, &DataFile::upgrade_loopsRename , &DataFile::upgrade_noteTypes, - &DataFile::upgrade_fixCMTDelays + &DataFile::upgrade_fixCMTDelays , &DataFile::upgrade_fixBassLoopsTypo, }; // Vector of all versions that have upgrade routines. @@ -640,6 +640,32 @@ void DataFile::cleanMetaNodes( QDomElement _de ) } } +void DataFile::mapSrcAttributeInElementsWithResources(const QMap& map) +{ + for (const auto& [elem, srcAttrs] : ELEMENTS_WITH_RESOURCES) + { + auto elements = elementsByTagName(elem); + + for (const auto& srcAttr : srcAttrs) + { + for (int i = 0; i < elements.length(); ++i) + { + auto item = elements.item(i).toElement(); + + if (item.isNull() || !item.hasAttribute(srcAttr)) { continue; } + + const QString srcVal = item.attribute(srcAttr); + + const auto it = map.constFind(srcVal); + if (it != map.constEnd()) + { + item.setAttribute(srcAttr, *it); + } + } + } + } +} + void DataFile::upgrade_0_2_1_20070501() { @@ -1871,68 +1897,64 @@ void DataFile::upgrade_sampleAndHold() } +static QMap buildReplacementMap() +{ + static constexpr auto loopBPMs = std::array{ + std::pair{"bassloops/briff01", "140"}, + std::pair{"bassloops/briff01", "140"}, + std::pair{"bassloops/rave_bass01", "180"}, + std::pair{"bassloops/rave_bass02", "180"}, + std::pair{"bassloops/tb303_01", "123"}, + std::pair{"bassloops/techno_bass01", "140"}, + std::pair{"bassloops/techno_bass02", "140"}, + std::pair{"bassloops/techno_synth01", "140"}, + std::pair{"bassloops/techno_synth02", "140"}, + std::pair{"bassloops/techno_synth03", "130"}, + std::pair{"bassloops/techno_synth04", "140"}, + std::pair{"beats/909beat01", "122"}, + std::pair{"beats/break01", "168"}, + std::pair{"beats/break02", "141"}, + std::pair{"beats/break03", "168"}, + std::pair{"beats/electro_beat01", "120"}, + std::pair{"beats/electro_beat02", "119"}, + std::pair{"beats/house_loop01", "142"}, + std::pair{"beats/jungle01", "168"}, + std::pair{"beats/rave_hihat01", "180"}, + std::pair{"beats/rave_hihat02", "180"}, + std::pair{"beats/rave_kick01", "180"}, + std::pair{"beats/rave_kick02", "180"}, + std::pair{"beats/rave_snare01", "180"}, + std::pair{"latin/latin_brass01", "140"}, + std::pair{"latin/latin_guitar01", "126"}, + std::pair{"latin/latin_guitar02", "140"}, + std::pair{"latin/latin_guitar03", "120"}, + }; + + QMap namesToNamesWithBPMsMap; + + auto insertEntry = [&namesToNamesWithBPMsMap](const QString& originalName, const QString& bpm, const QString& prefix = "", const QString& extension = "ogg") + { + const QString original = prefix + originalName + "." + extension; + const QString replacement = prefix + originalName + " - " + bpm + " BPM." + extension; + + namesToNamesWithBPMsMap.insert(original, replacement); + }; + + for (const auto & loopBPM : loopBPMs) + { + insertEntry(loopBPM.first, loopBPM.second); + insertEntry(loopBPM.first, loopBPM.second, "factorysample:"); + } + + return namesToNamesWithBPMsMap; +} + // Change loops' filenames in s void DataFile::upgrade_loopsRename() { - auto createEntry = [](const QString& originalName, const QString& bpm, const QString& extension = "ogg") - { - const QString replacement = originalName + " - " + bpm + " BPM." + extension; - return std::pair{originalName + "." + extension, replacement}; - }; + static const QMap namesToNamesWithBPMsMap = buildReplacementMap(); - static const QMap namesToNamesWithBPMsMap { - { createEntry("bassloops/briff01", "140") }, - { createEntry("bassloops/rave_bass01", "180") }, - { createEntry("bassloops/rave_bass02", "180") }, - { createEntry("bassloops/tb303_01", "123") }, - { createEntry("bassloops/techno_bass01", "140") }, - { createEntry("bassloops/techno_bass02", "140") }, - { createEntry("bassloops/techno_synth01", "140") }, - { createEntry("bassloops/techno_synth02", "140") }, - { createEntry("bassloops/techno_synth03", "130") }, - { createEntry("bassloops/techno_synth04", "140") }, - { createEntry("beats/909beat01", "122") }, - { createEntry("beats/break01", "168") }, - { createEntry("beats/break02", "141") }, - { createEntry("beats/break03", "168") }, - { createEntry("beats/electro_beat01", "120") }, - { createEntry("beats/electro_beat02", "119") }, - { createEntry("beats/house_loop01", "142") }, - { createEntry("beats/jungle01", "168") }, - { createEntry("beats/rave_hihat01", "180") }, - { createEntry("beats/rave_hihat02", "180") }, - { createEntry("beats/rave_kick01", "180") }, - { createEntry("beats/rave_kick02", "180") }, - { createEntry("beats/rave_snare01", "180") }, - { createEntry("latin/latin_brass01", "140") }, - { createEntry("latin/latin_guitar01", "126") }, - { createEntry("latin/latin_guitar02", "140") }, - { createEntry("latin/latin_guitar03", "120") } - }; - - // Replace loop sample names - for (const auto& [elem, srcAttrs] : ELEMENTS_WITH_RESOURCES) - { - auto elements = elementsByTagName(elem); - - for (const auto& srcAttr : srcAttrs) - { - for (int i = 0; i < elements.length(); ++i) - { - auto item = elements.item(i).toElement(); - - if (item.isNull() || !item.hasAttribute(srcAttr)) { continue; } - - const QString srcVal = item.attribute(srcAttr); - - const auto it = namesToNamesWithBPMsMap.constFind(srcVal); - if (it != namesToNamesWithBPMsMap.constEnd()) - { - item.setAttribute(srcAttr, *it); - } - } - } - } + mapSrcAttributeInElementsWithResources(namesToNamesWithBPMsMap); } //! Update MIDI CC indexes, so that they are counted from 0. Older releases of LMMS @@ -1957,6 +1979,24 @@ void DataFile::upgrade_midiCCIndexing() } } +void DataFile::upgrade_fixBassLoopsTypo() +{ + static const QMap replacementMap = { + { "bassloopes/briff01.ogg", "bassloops/briff01 - 140 BPM.ogg" }, + { "bassloopes/rave_bass01.ogg", "bassloops/rave_bass01 - 180 BPM.ogg" }, + { "bassloopes/rave_bass02.ogg", "bassloops/rave_bass02 - 180 BPM.ogg" }, + { "bassloopes/tb303_01.ogg","bassloops/tb303_01 - 123 BPM.ogg" }, + { "bassloopes/techno_bass01.ogg", "bassloops/techno_bass01 - 140 BPM.ogg" }, + { "bassloopes/techno_bass02.ogg", "bassloops/techno_bass02 - 140 BPM.ogg" }, + { "bassloopes/techno_synth01.ogg", "bassloops/techno_synth01 - 140 BPM.ogg" }, + { "bassloopes/techno_synth02.ogg", "bassloops/techno_synth02 - 140 BPM.ogg" }, + { "bassloopes/techno_synth03.ogg", "bassloops/techno_synth03 - 130 BPM.ogg" }, + { "bassloopes/techno_synth04.ogg", "bassloops/techno_synth04 - 140 BPM.ogg" } + }; + + mapSrcAttributeInElementsWithResources(replacementMap); +} + void DataFile::upgrade() { // Runs all necessary upgrade methods From 68ea3f5bf21cb744c0f274d84d2f9fa55e5da79b Mon Sep 17 00:00:00 2001 From: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Date: Sat, 15 Jun 2024 08:29:14 +0530 Subject: [PATCH 07/31] Remove `debian` folder (#7311) * removed debian folder * removed debian entries from check-strings * fixup verify script too --- debian/changelog | 382 ------ debian/compat | 1 - debian/control | 126 -- debian/copyright | 1373 --------------------- debian/gbp.conf | 2 - debian/lmms-bin.install | 4 - debian/lmms-bin.lintian-overrides | 9 - debian/lmms-common.docs | 1 - debian/lmms-common.install | 25 - debian/lmms-common.links | 1 - debian/lmms-common.maintscript | 1 - debian/lmms-vst-server.install | 1 - debian/lmms.xpm | 103 -- debian/patches/build-amd64-20181013.patch | 46 - debian/patches/clang.patch | 601 --------- debian/patches/series | 2 - debian/rules | 41 - debian/source/format | 1 - debian/watch | 3 - tests/scripted/check-strings | 20 - tests/scripted/verify | 20 - 21 files changed, 2763 deletions(-) delete mode 100644 debian/changelog delete mode 100644 debian/compat delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/gbp.conf delete mode 100644 debian/lmms-bin.install delete mode 100644 debian/lmms-bin.lintian-overrides delete mode 100644 debian/lmms-common.docs delete mode 100644 debian/lmms-common.install delete mode 100644 debian/lmms-common.links delete mode 100644 debian/lmms-common.maintscript delete mode 100644 debian/lmms-vst-server.install delete mode 100644 debian/lmms.xpm delete mode 100644 debian/patches/build-amd64-20181013.patch delete mode 100644 debian/patches/clang.patch delete mode 100644 debian/patches/series delete mode 100755 debian/rules delete mode 100644 debian/source/format delete mode 100644 debian/watch diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 86f03c427..000000000 --- a/debian/changelog +++ /dev/null @@ -1,382 +0,0 @@ -lmms (@VERSION@) unstable; urgency=low - - * Upstream integration. - * Drop Debian menu entry (policy 9.6). - - -- Javier Serrano Polo Sat, 03 Nov 2018 02:43:42 +0100 - -lmms (1.1.3-8) unstable; urgency=low - - * Fix build (Closes: #897806). - * Allow recommendations (Closes: #891756). - - -- Javier Serrano Polo Sat, 13 Oct 2018 17:05:54 +0200 - -lmms (1.1.3-7.1) unstable; urgency=high - - * Non-maintainer upload. - - [ Javier Serrano Polo ] - * Fix build with Clang. - * Fix build with GCC 7 (Closes: #853527). - - [ Boyuan Yang ] - * Remove Patrick Winnertz from uploaders list. (Closes: #867759) - Thank you for your previous contributions! - - -- Boyuan Yang <073plan@gmail.com> Sat, 10 Mar 2018 11:32:05 +0800 - -lmms (1.1.3-7) unstable; urgency=low - - [ Javier Serrano Polo ] - * Separate flags for WINE_BUILD_FLAGS to fix build problem on i386. - - -- Petter Reinholdtsen Mon, 26 Dec 2016 07:36:54 +0000 - -lmms (1.1.3-6) unstable; urgency=low - - [ Javier Serrano Polo ] - * Build with install RUNPATH (reproducibility). - - -- Petter Reinholdtsen Sun, 25 Dec 2016 09:38:53 +0000 - -lmms (1.1.3-5) unstable; urgency=medium - - [ Javier Serrano Polo ] - * Add Wine stable path to PATH, otherwise wine package would be required. - * Sort plug-in embedded resources (reproducibility). - * Define NDEBUG instead of setting build type to honor optimization choice. - - -- Javier Serrano Polo Sat, 03 Sep 2016 17:31:05 +0200 - -lmms (1.1.3-4) unstable; urgency=medium - - [ Javier Serrano Polo ] - * Sort lists generated from globbing expressions (reproducibility). - * Fixed upgrade that installs recommended packages (Closes: #827039). - * Dropped unused build dependencies. - * Dropped workaround for #824715, wineg++ is fixed. - * Added contributors. - * Honor CONTRIBUTORS override. - * Replace __FILE__ (reproducibility). - * Use build type "Release" (reproducibility). - - -- Javier Serrano Polo Wed, 08 Jun 2016 01:25:37 +0200 - -lmms (1.1.3-3) unstable; urgency=medium - - [ Javier Serrano Polo ] - * Dropped Wine path from PATH. - * Fixed lmms-common upgrade (Closes: #825287). - * Hide vocoder plug-in, it is now in swh-plugins (Closes: #826110). - * Added workaround for #824715 (Closes: #825286). - - -- Petter Reinholdtsen Fri, 03 Jun 2016 08:51:31 +0000 - -lmms (1.1.3-2) unstable; urgency=medium - - [ Javier Serrano Polo ] - * Enabled vst plugin on i386 and amd64 (Closes: #763720). - * Made Calf and vocoder plugins available to other programs (Closes: #758888). - * Fixed version of metalish_dong01.ogg (Closes: #802588). - * Bumped Standards-Version to 3.9.7. Doxygen documentation is not very useful. - * Upgraded to Standards-Version 3.9.8. Ship icons in the default hicolor icon - theme directories. - * Use presets from zynaddsubfx-data. - * Fixed build problems with GCC 6 (Closes: #811697). - * Switch to PulseAudio back end on likely ALSA interception (Closes: #781479). - * Updated copyright information. - * Removed non-free projects. - - -- Petter Reinholdtsen Wed, 18 May 2016 09:09:23 +0000 - -lmms (1.1.3-1) unstable; urgency=low - - * New upstream version 1.1.3 (Closes: #788457). - - Drop well-defined-loop.patch, included upstream. - * Add config for git-buildpackage to use pristine-tar all the time. - * Change homepage url to new http://lmms.io/. - * Added fluid as build-depend. - * New patch find-fluid.patch to find the fluid binary in unstable. - * New patch gcc5.patch to get the code building with gcc 5 in - unstable (Closes: #777989). - * Added man-page-adjustment.patch to fix manpage formatting of AUTHOR - block. Discovered thanks to lintian. - - -- Petter Reinholdtsen Mon, 21 Sep 2015 13:54:02 +0200 - -lmms (1.0.3-5) unstable; urgency=low - - * Make lmms replace and break lmms-common (<< 1.0.0-1) to handle the - fact that /usr/share/menu/lmms moved from lmms-common to lmms in - this version (Closes: #765970). - - -- Petter Reinholdtsen Sun, 19 Oct 2014 23:43:08 +0200 - -lmms (1.0.3-4) unstable; urgency=low - - * Correct watch file to reflect '-src' part of upstream tarball. - * New desktop-argument.patch to let desktops know how to pass files to - lmms. Thanks to lintian for noticing the bug. - * Revert change to enable the vsl plugin in version 1.0.3-3, as it did - not work. Reopen bug #763720. - - -- Petter Reinholdtsen Wed, 08 Oct 2014 19:21:53 +0200 - -lmms (1.0.3-3) unstable; urgency=medium - - * Try to get vsl plugin working on i386 by build depending on libwine-dev - and wine32-dev-tools (Closes: #763720). Unable to get it working on - amd64. - - -- Petter Reinholdtsen Tue, 07 Oct 2014 12:13:16 +0200 - -lmms (1.0.3-2) unstable; urgency=medium - - * Change build rule to only enable ALSA support on Linux (Closes: #754718). - Patch from Steven Chamberlain with input from Guillem Jover. - * Drop libwine-dev build dependency to avoid build failure in the - vst plugin. It should be enabled when we figure out how to do it. - - -- Petter Reinholdtsen Thu, 02 Oct 2014 08:19:53 +0200 - -lmms (1.0.3-1) unstable; urgency=low - - * Move package into Debian Edu git repository and add myself as - co-maintainer. - * Update to upstream version 1.0.3. - * Correct build dependency on i386, use libwine-dev instead of the now - obsolete wine-dev (Closes: #748183). - * Update Standards-Version from 3.9.5 to 3.9.6. - * Add new well-defined-loop.patch to fix compile error triggered by - undefined loop behaviour (Closes: #753177). - - -- Petter Reinholdtsen Wed, 01 Oct 2014 23:00:19 +0200 - -lmms (1.0.0-1) unstable; urgency=low - - * New upstream version (Closes: #703900, #735764, #696271) - * Using a wraped-style control (Closes: #689347) - * Don't suggest vcf as it no longer exists (since a long time) - (Closes: #618350) - * Problems with jack backend were fixed long ago (Closes: #557421) - * No depends/recommends on wine anymore (Closes: #622215, #622080) - - -- Patrick Winnertz Thu, 24 Apr 2014 22:30:17 +0200 - -lmms (0.4.10-2.3) unstable; urgency=low - - * Non maintainer upload. - * Remove wine-related dependencies on amd64, thereby disabling building - VST plugin. (Closes: #676760) - - -- Hilko Bengen Wed, 27 Jun 2012 23:14:40 +0200 - -lmms (0.4.10-2.2) unstable; urgency=low - - * Non maintainer upload. - * Fix build failure with GCC 4.7. Closes: #667265. - * Turn on verbose build. - - -- Matthias Klose Tue, 17 Apr 2012 14:08:53 +0200 - -lmms (0.4.10-2.1) unstable; urgency=low - - * Non-maintainer upload. - * Fix FTBFS on GNU/kFreeBSD. Thanks Pino Toscano. (Closes: #641064) - - -- Robert Millan Fri, 27 Apr 2012 22:55:55 +0200 - -lmms (0.4.10-2) unstable; urgency=low - - * Removed build-dep on libestools2.0-dev (Closes: #614975) - - -- Patrick Winnertz Fri, 11 Mar 2011 09:37:43 +0100 - -lmms (0.4.10-1) unstable; urgency=low - - * Imported Upstream version 0.4.10 - * changed mode of patch - * Add source/format with 3.0 (quilt) and rearrange source a bit - * Bump standarts version to 3.9.1 - no further changes needed - - -- Patrick Winnertz Fri, 11 Feb 2011 20:03:06 +0100 - -lmms (0.4.7-2) unstable; urgency=low - - [ Reinhard Tartler ] - * Depend on wine only on i386 and amd64 (Closes: #590950) - - [ Patrick Winnertz ] - * Uploading patch from siretart, thanks for helping. - - -- Patrick Winnertz Mon, 02 Aug 2010 10:13:28 +0200 - -lmms (0.4.7-1) unstable; urgency=low - - * New upstream version - - -- Patrick Winnertz Thu, 29 Jul 2010 16:24:00 +0200 - -lmms (0.4.6-2) unstable; urgency=low - - * Build-depend on libestools2.0-dev (Closes: #589882) - - -- Patrick Winnertz Wed, 28 Jul 2010 11:55:16 +0200 - -lmms (0.4.6-1) unstable; urgency=low - - * New upstream version (Closes: #565733) - * Bumped standards version to 3.8.3, no further changes needed - - -- Patrick Winnertz Sun, 24 Jan 2010 16:40:39 +0100 - -lmms (0.4.5-1) unstable; urgency=low - - * New upstream version (Closes: #543645) - * Fix FTBFS on amd64 (Closes: #540671 #543017) - - -- Patrick Winnertz Fri, 11 Sep 2009 09:56:45 +0200 - -lmms (0.4.4-1) unstable; urgency=low - - * New upstream version (Closes: #511363) - * Provide menu file (Closes: #514905) - - The menufile is included in lmms-common and not in lmms - as it is not arch specific - * Bumped standards version to 3.8.2 no further changes needed - - -- Patrick Winnertz Wed, 05 Aug 2009 20:46:40 +0200 - -lmms (0.3.2-1) unstable; urgency=low - - * Decrease wine dependency to wine-bin as suggested. (Closes: #446163) - * Acknowlegded NMU from Pierre Habouzit in order to - fix FTBFS with gcc-4.3 which (Closes: #462202) - * Now including the singerbot plugin. (Closes: #443224) - * Add patch to prevent lmms from crashing. - - -- Patrick Winnertz Mon, 17 Mar 2008 10:56:12 +0100 - -lmms (0.3.1-1.1) unstable; urgency=low - - * Non-maintainer upload. - * Add g++-4.3.patch to fix g++-4.3 FTBFS (Closes: 462202). - - -- Pierre Habouzit Sun, 16 Mar 2008 23:21:56 +0000 - -lmms (0.3.1-1) unstable; urgency=low - - * Packaging new upstream release. - * Install Upstream Changelog (Closes: #441477) - Thanks to Felipe Sateler - * Lowered the caps dependency to Recommends (Closes: #446163) - * Added -i/-a to the build targets in rules in order to make sure that only - (in)dep packages are build. - * Changed my maintainer address - * Added patch to remove stereo_enhancer plugin which has a ftbfs with gcc - 4.2.3 - * Added imagemagick as build-dep since we have to convert a .png to a .xpm - via convert - * Doesn't install upstreams menu file, since it's outdated.. instead use - our own. - * Standard-Version bump to 3.7.3 - * Remove Homepage field from Description and create a own Header - * Added postinst and postrm for lmms-common to call update-menu if available - (this has to be done manually, since we doesn't use dh_installmenu to install - the menu file) - - -- Patrick Winnertz Thu, 06 Dec 2007 07:08:04 +0100 - -lmms (0.3.0-1) unstable; urgency=low - - [ Tobias Doerffel ] - * New upstream release. (Closes: #439301) - * Removed patch from Thomas Girard as upstream merged changes - - [ Patrick Winnertz ] - * Moved manpage into correct package (lmms) - * Removed manuall installation of Upstream Changelog, thanks to the power of - debhelper ;-) - * FTBFS with gcc 4.2 is fixed by upstream (Closes: #383295) - * lmms has now a proper menu entry (Closes: #383406) - * lmms depends now on the same version of lmms-common (Closes: #389037) - * fixed by upstream: arpeggio status is now saved (Closes: #433262) - * Added build-depends libqt3-i18n (Closes: #384406) - * Added watch file for lmms (Closes: #439302) - Thanks to Raphael Geissert - * Improved copyright file - * Doesn't build libsingerbot since it is experimental and doesn't work - correct yet - * Added several build-dependencys (libstk0-dev, libestools1.2-dev, ladspa-sdk, - libflac-dev, libwine-dev [i386], libqt3-i18n, libasound2-dev, - festival-dev, dpatch ) - * Take over this package from Florian Ragwitz, so set myself as maintainer - * Add a depends on a specific version of lmms-common - * Added several new dependencys to lmms - * Improved description of lmms and lmms-common - * Die on errors of clean, but don't die if the makefile doesn't exist - * Added watch file - - -- Patrick Winnertz Fri, 24 Aug 2007 08:23:34 +0200 - -lmms (0.2.1-1.1) unstable; urgency=high - - * Non-maintainer Upload - * Add Patch by Thomas Girard for segfault right after - lmms starting up (Closes: 382491) - - -- Michael Ablassmeier Tue, 5 Sep 2006 12:00:40 +0200 - -lmms (0.2.1-1) unstable; urgency=low - - * New upstream release. - * Bump up Standards-Version to 3.7.2 (no changes). - * Use DH_COMPAT 5. - - -- Florian Ragwitz Sun, 13 Aug 2006 14:40:13 +0200 - -lmms (0.1.4-1) unstable; urgency=low - - * New upstream release. - - -- Florian Ragwitz Sat, 4 Feb 2006 07:16:47 +0100 - -lmms (0.1.3-1) unstable; urgency=low - - * New upstream release. - * debian/lmms.1 was included by upstream. Removed it from debian/. - * Install lmms.1 in lmms-common instead of lmms to safe some mirror space. - * Added a lintian override for the above, as lintian is not smart enough to - check for manpages in other packages from the same source package on which - a package with a missing manpage depends. - - -- Florian Ragwitz Wed, 1 Feb 2006 18:28:42 +0100 - -lmms (0.1.2-1) unstable; urgency=low - - * New upstream release. - - -- Florian Ragwitz Thu, 22 Dec 2005 16:22:50 +0100 - -lmms (0.1.1-2) unstable; urgency=low - - * lmms-common doesn't depend on lmms anymore to remove a circular - dependencies (Closes: #339906). - - -- Florian Ragwitz Sun, 20 Nov 2005 12:27:08 +0100 - -lmms (0.1.1-1) unstable; urgency=low - - * New upstream release. - * Changed Maintainer address. - * Added libjack-dev to Build-Depends. - - -- Florian Ragwitz Mon, 31 Oct 2005 10:48:36 +0100 - -lmms (0.0.9+0.1.0rc1-1) unstable; urgency=low - - * Initial Release (Closes: #315976). - - -- Florian Ragwitz Fri, 22 Jul 2005 16:33:17 +0200 - diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec635144f..000000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index 63eba44d2..000000000 --- a/debian/control +++ /dev/null @@ -1,126 +0,0 @@ -Source: lmms -Section: sound -Priority: optional -Maintainer: Debian Edu Packaging Team -Uploaders: - Petter Reinholdtsen , - Israel Dahl , - Javier Serrano Polo , -Build-Depends: - cmake, - debhelper (>= 9.0.0), - fluid, - ladspa-sdk, - libasound2-dev [linux-any], - libfftw3-dev, - libfltk1.3-dev, - libfluidsynth-dev, - libgig-dev, - libjack-jackd2-dev, - liblist-moreutils-perl, - libmp3lame-dev, - libpulse-dev, - libqt5x11extras5-dev, - libsamplerate0-dev, - libsdl1.2-dev, - libsndfile1-dev, - libsndio-dev, - libsoundio-dev, - libstk0-dev, - libvorbis-dev, - libx11-xcb-dev, - libxcb-keysyms1-dev, - libxcb-util0-dev, - libxml-perl, - libxml2-utils, - portaudio19-dev, - qtbase5-private-dev, - qttools5-dev, - wine64-tools [amd64] | wine32-tools [i386] -Standards-Version: 4.2.1.4 -Homepage: https://lmms.io/ -Vcs-Browser: https://salsa.debian.org/debian-edu-pkg-team/lmms.git - -Package: lmms-bin -Architecture: any -Depends: - lmms-common (>= ${source:Version}), - ${shlibs:Depends}, - ${misc:Depends}, - stk, -Recommends: - caps, - lmms-vst-server:i386 (>= ${source:Version}), - lmms-vst-server:amd64 (>= ${source:Version}), - tap-plugins, -Suggests: - fil-plugins, - fluid-soundfont-gm, - freepats, - ladspa-plugin, - mcp-plugins, - omins, -Replaces: lmms-common (<< 1.0.0-1) -Breaks: lmms-common (<< 1.0.0-1) -Multi-Arch: allowed -Description: Linux Multimedia Studio - minimal installation - LMMS aims to be a free alternative to popular (but commercial and closed- - source) programs like FruityLoops, Cubase and Logic giving you the ability of - producing music with your computer by creating cool loops, synthesizing and - mixing sounds, arranging samples, having more fun with your MIDI-keyboard - and much more... - . - LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/ - sample-/song-/effect-management) and those of powerful synthesizers and - samplers in a modern, user-friendly and easy to use graphical user-interface. - . - This package provides the minimal installation. - -Package: lmms -Architecture: any -Depends: - lmms-bin, - ${misc:Depends}, -Description: Linux Multimedia Studio - LMMS aims to be a free alternative to popular (but commercial and closed- - source) programs like FruityLoops, Cubase and Logic giving you the ability of - producing music with your computer by creating cool loops, synthesizing and - mixing sounds, arranging samples, having more fun with your MIDI-keyboard - and much more... - . - LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/ - sample-/song-/effect-management) and those of powerful synthesizers and - samplers in a modern, user-friendly and easy to use graphical user-interface. - . - This package provides the recommended installation. - -Package: lmms-common -Architecture: all -Depends: - ${shlibs:Depends}, - ${misc:Depends}, - zynaddsubfx-data, -Pre-Depends: ${misc:Pre-Depends} -Description: Linux Multimedia Studio - common files - LMMS aims to be a free alternative to popular (but commercial and closed- - source) programs like FruityLoops, Cubase and Logic giving you the ability of - producing music with your computer by creating cool loops, synthesizing and - mixing sounds, arranging samples, having more fun with your MIDI-keyboard - and much more... - . - LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/ - sample-/song-/effect-management) and those of powerful synthesizers and - samplers in a modern, user-friendly and easy to use graphical user-interface. - . - This package contains the platform independent files such as samples, presets - and some example projects. - -Package: lmms-vst-server -Architecture: amd64 i386 -Depends: - wine64 [amd64] | wine64-development [amd64] | wine32 [i386] | wine32-development [i386], - ${shlibs:Depends}, - ${misc:Depends}, -Recommends: lmms-bin:any -Description: Linux Multimedia Studio - VST server - This package contains a helper application that loads VST plugins. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index f4bc9d85c..000000000 --- a/debian/copyright +++ /dev/null @@ -1,1373 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: LMMS -Upstream-Contact: https://github.com/LMMS/lmms -Source: https://github.com/LMMS/lmms/tags -Comment: - This package was debianized by Florian Ragwitz on - Thu, 14 Apr 2005 13:24:57 +0200. - -Files: * -Copyright: - 1998-2000 Paul Kellett (mda-vst.com) - 1999-2004 Dag Lem - 2002 Kjetil S. Matheussen - 2003-2007 Rui Nuno Capela - 2003-2005 Shay Green - 2004-2014 Tobias Doerffel - 2004 Paul Davis - 2004 Torben Hohn - 2005-2008 Danny McRae - 2006-2008 Andreas Brandmaier - 2006-2008 Javier Serrano Polo - 2007-2014 Vesa Kivimäki - 2007-2013 Paul Giblock - 2007 Keith Marshall - 2008-2009 Andrew Kelley - 2008 Attila Herman - 2008 Csaba Hruska - 2013-2014 Raine M. Ekman - 2013 Mike Choi - 2014 David French - 2014 Hannu Haahti - 2014 Lukas Wohlschläger - 2014 Rubén Ibarra Pastor - 2014 Simon Symeonidis - 2014 Wong Cho Ching - Chrissy McManus - Gabriel - Gurjot Singh - Johannes Lorenz - Jonathan Aquilina - Jorrit Rouwe - Juan Fabián Simón - LocoMatt - Oskar Wallgren - Peter Hanappe - Sebastian Tilsch - Tobiasz Karoń (unfa) - Uroš Maravić -License: GPL-2+ - -Files: data/projects/demos/Alf42red-* - data/projects/demos/CapDan/CapDan-TwilightArea-* -Copyright: - 2010-2011 Armin Heller - 2011 Der Daniel (CapDan) -License: CC-BY-SA-3 - -Files: data/projects/demos/AngryLlama-* - data/projects/demos/Ashore.* - data/projects/demos/DnB.* - data/projects/demos/Farbro-* - data/projects/demos/Greippi* - data/projects/demos/Namitryus-* - data/projects/demos/Popsip-* - data/projects/demos/Root84-* - data/projects/demos/Shovon-* - data/projects/demos/Skiessi/* - data/projects/demos/StrictProduction-* - data/projects/demos/Thaledric-* - data/projects/demos/TobyDox-* - data/projects/demos/unfa-* - data/projects/shorties/DirtyLove.* - data/projects/shorties/Root84-* - data/projects/shorties/Skiessi-* - data/projects/shorties/sv-* -Copyright: - LMMS contributors -License: non-free - -Files: data/projects/demos/CapDan/CapDan-ReggaeTry.* - data/projects/demos/CapDan/CapDan-ReggaetonTry.* - data/projects/demos/CapDan/CapDan-ZeroSumGame-* - data/projects/demos/EsoXLB-* - data/projects/demos/Impulslogik-* - data/projects/demos/Momo64-* - data/projects/demos/Oglsdl-* - data/projects/demos/Settel-* - data/projects/demos/Socceroos-* - data/projects/demos/TameAnderson-* - data/projects/demos/Thomasso-* - data/projects/shorties/Crunk* - data/projects/shorties/Greshz-* - data/projects/shorties/Surrender-* -Copyright: - 2009 Achim Settelmeier - 2009 Peter Asplund (Surrender) - 2009 Thomasso - 2010 E.SoX (lowbudget) - 2010 Impulslogik - 2011 Der Daniel (CapDan) - 2011 Sam (socceroos) - 2011 mauro (momo64) - 2011 tame anderson - 2011 Ümit (oglsdl) - Greshz -License: Artistic-2 - -Files: data/projects/demos/Jousboxx-* -Copyright: - Jousboxx -License: CC-BY-SA-4 - -Files: data/projects/demos/Saber-* -Copyright: - Saber Rastikerdar -License: BSD-2-clause - -Files: include/ladspa.h -Copyright: - 2000-2002 Paul Barton-Davis - 2000-2002 Richard W.E. Furse - 2000-2002 Stefan Westerfeld -License: LGPL-2.1+ - -Files: plugins/LadspaEffect/calf/veal/* -Copyright: - 2001-2010 Krzysztof Foltman - 2001-2010 Markus Schmidt - 2001-2010 Thor Harald Johansen - Alexandre Prokoudine - Carl Hetherington - Christian Holschuh - Damien Zammit - Dave Robillard - David Täht - Hans Baier - Hermann Meyer - Thorsten Wilms - Tom Szilagyi - Torben Hohn -License: LGPL-2+ -Comment: - COPYING is the GNU Lesser General Public License. Headers refer to version 2 of - this license instead of version 2.1. - -Files: plugins/LadspaEffect/calf/veal/src/calf/vumeter.h -Copyright: - 2007 Krzysztof Foltman -License: GPL-2+ - -Files: plugins/LadspaEffect/caps/* -Copyright: - 1998 Robert Bristow-Johnson - 2001-2011 Tim Goetze - 2003-2009 David Yeh - 2004-2005 Steve Harris -License: GPL-2+ - -Files: plugins/LadspaEffect/cmt/* -Copyright: - 1998 Andy Sloane - 1999-2001 David A. Bartold - 2000-2002 Richard W.E. Furse - 2000 Jezar - 2002 Nathaniel Virgo -License: GPL-2+ - -Files: plugins/LadspaEffect/swh/ladspa/* -Copyright: - 1999 Juhana Sadeharju - 2000-2003 Alexander Ehlert - 2000-2002 Steve Harris - Andy Wingo - Frank Neumann - Jesse Chappell - Joern Nettingsmeier - Marcus Andersson - Mark Knecht - Matthias Nagorni - Nathaniel Virgo - Pascal Haakmat - Patrick Shirkey - Paul Winkler -License: GPL-2+ - -Files: plugins/LadspaEffect/swh/ladspa/gsm/* -Copyright: - 1992-1994 Carsten Bormann - 1992-1994 Jutta Degener -License: Bormann-Degener - -Files: plugins/LadspaEffect/swh/ladspa/util/pitchscale.c -Copyright: - 1999 Stephan M. Sprenger -License: WOL - -Files: plugins/LadspaEffect/swh/ladspa/vocoder_1337.c -Copyright: - Achim Settelmeier - Hexasoft - Josh Green -License: GPL-2+ - -Files: plugins/LadspaEffect/tap/* -Copyright: - 2004 Tom Szilagyi - Alexander Koenig -License: GPL-2+ - -Files: plugins/MidiImport/portsmf/* -Copyright: - 1999-2000 Phil Burk - 1999-2000 Ross Bencina - 2001-2006 Roger B. Dannenberg -License: Expat -Comment: - The Expat license constitutes the entire Portsmf license; however, - the PortMusic community also makes the following non-binding requests: - . - Any person wishing to distribute modifications to the Software is - requested to send the modifications to the original developer so that - they can be incorporated into the canonical version. It is also - requested that these non-binding requests be included along with the - license above. - -Files: plugins/OpulenZ/adplug/src/fmopl.* - plugins/OpulenZ/adplug/src/mididata.h - plugins/OpulenZ/adplug/src/opl.h - plugins/OpulenZ/adplug/src/temuopl.* -Copyright: - 1999-2007 Simon Peter - 1999-2000 Tatsuyuki Satoh -License: LGPL-2.1+ - -Files: plugins/Sfxr/readme.* - plugins/Sfxr/Sfxr.* -Copyright: - 2007 Tomas Pettersson - 2014 Wong Cho Ching -License: Expat and GPL-2+ - -Files: plugins/ZynAddSubFx/zynaddsubfx/* -Copyright: - 2002-2009 Nasca Octavian Paul - 2009-2010 Mark McCurry - 2009 Alan Calvert - 2012 Jonathan Liles - Achim Settelmeier - Alexis Ballier - Andre Sklenar - Christopher Oliver - Damien Goutte-Gattat - Daniel Clemente - Emmanuel Saracco - Filipe Coelho - Gerald Folcher - Hans Petter Selasky - Harald Hvaal - Ilario Glasgo - James Morris - Johannes Lorenz - Jérémie Andréi - Lars Luthman - Lieven Moors - Olaf Schulz - Ryan Billing - Stephen Parry - Tobias Doerffel -License: GPL-2+ - -License: Artistic-2 - The Artistic License 2.0 - . - Copyright (c) 2000-2006, The Perl Foundation. - . - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - . - Preamble - . - This license establishes the terms under which a given free software - Package may be copied, modified, distributed, and/or redistributed. - The intent is that the Copyright Holder maintains some artistic - control over the development of that Package while still keeping the - Package available as open source and free software. - . - You are always permitted to make arrangements wholly outside of this - license directly with the Copyright Holder of a given Package. If the - terms of this license do not permit the full use that you propose to - make of the Package, you should contact the Copyright Holder and seek - a different licensing arrangement. - . - Definitions - . - "Copyright Holder" means the individual(s) or organization(s) - named in the copyright notice for the entire Package. - . - "Contributor" means any party that has contributed code or other - material to the Package, in accordance with the Copyright Holder's - procedures. - . - "You" and "your" means any person who would like to copy, - distribute, or modify the Package. - . - "Package" means the collection of files distributed by the - Copyright Holder, and derivatives of that collection and/or of - those files. A given Package may consist of either the Standard - Version, or a Modified Version. - . - "Distribute" means providing a copy of the Package or making it - accessible to anyone else, or in the case of a company or - organization, to others outside of your company or organization. - . - "Distributor Fee" means any fee that you charge for Distributing - this Package or providing support for this Package to another - party. It does not mean licensing fees. - . - "Standard Version" refers to the Package if it has not been - modified, or has been modified only in ways explicitly requested - by the Copyright Holder. - . - "Modified Version" means the Package, if it has been changed, and - such changes were not explicitly requested by the Copyright - Holder. - . - "Original License" means this Artistic License as Distributed with - the Standard Version of the Package, in its current version or as - it may be modified by The Perl Foundation in the future. - . - "Source" form means the source code, documentation source, and - configuration files for the Package. - . - "Compiled" form means the compiled bytecode, object code, binary, - or any other form resulting from mechanical transformation or - translation of the Source form. - . - Permission for Use and Modification Without Distribution - . - (1) You are permitted to use the Standard Version and create and use - Modified Versions for any purpose without restriction, provided that - you do not Distribute the Modified Version. - . - Permissions for Redistribution of the Standard Version - . - (2) You may Distribute verbatim copies of the Source form of the - Standard Version of this Package in any medium without restriction, - either gratis or for a Distributor Fee, provided that you duplicate - all of the original copyright notices and associated disclaimers. At - your discretion, such verbatim copies may or may not include a - Compiled form of the Package. - . - (3) You may apply any bug fixes, portability changes, and other - modifications made available from the Copyright Holder. The resulting - Package will still be considered the Standard Version, and as such - will be subject to the Original License. - . - Distribution of Modified Versions of the Package as Source - . - (4) You may Distribute your Modified Version as Source (either gratis - or for a Distributor Fee, and with or without a Compiled form of the - Modified Version) provided that you clearly document how it differs - from the Standard Version, including, but not limited to, documenting - any non-standard features, executables, or modules, and provided that - you do at least ONE of the following: - . - (a) make the Modified Version available to the Copyright Holder - of the Standard Version, under the Original License, so that the - Copyright Holder may include your modifications in the Standard - Version. - . - (b) ensure that installation of your Modified Version does not - prevent the user installing or running the Standard Version. In - addition, the Modified Version must bear a name that is different - from the name of the Standard Version. - . - (c) allow anyone who receives a copy of the Modified Version to - make the Source form of the Modified Version available to others - under - . - (i) the Original License or - . - (ii) a license that permits the licensee to freely copy, - modify and redistribute the Modified Version using the same - licensing terms that apply to the copy that the licensee - received, and requires that the Source form of the Modified - Version, and of any works derived from it, be made freely - available in that license fees are prohibited but Distributor - Fees are allowed. - . - Distribution of Compiled Forms of the Standard Version - or Modified Versions without the Source - . - (5) You may Distribute Compiled forms of the Standard Version without - the Source, provided that you include complete instructions on how to - get the Source of the Standard Version. Such instructions must be - valid at the time of your distribution. If these instructions, at any - time while you are carrying out such distribution, become invalid, you - must provide new instructions on demand or cease further distribution. - If you provide valid instructions or cease distribution within thirty - days after you become aware that the instructions are invalid, then - you do not forfeit any of your rights under this license. - . - (6) You may Distribute a Modified Version in Compiled form without - the Source, provided that you comply with Section 4 with respect to - the Source of the Modified Version. - . - Aggregating or Linking the Package - . - (7) You may aggregate the Package (either the Standard Version or - Modified Version) with other packages and Distribute the resulting - aggregation provided that you do not charge a licensing fee for the - Package. Distributor Fees are permitted, and licensing fees for other - components in the aggregation are permitted. The terms of this license - apply to the use and Distribution of the Standard or Modified Versions - as included in the aggregation. - . - (8) You are permitted to link Modified and Standard Versions with - other works, to embed the Package in a larger work of your own, or to - build stand-alone binary or bytecode versions of applications that - include the Package, and Distribute the result without restriction, - provided the result does not expose a direct interface to the Package. - . - Items That are Not Considered Part of a Modified Version - . - (9) Works (including, but not limited to, modules and scripts) that - merely extend or make use of the Package, do not, by themselves, cause - the Package to be a Modified Version. In addition, such works are not - considered parts of the Package itself, and are not subject to the - terms of this license. - . - General Provisions - . - (10) Any use, modification, and distribution of the Standard or - Modified Versions is governed by this Artistic License. By using, - modifying or distributing the Package, you accept this license. Do not - use, modify, or distribute the Package, if you do not accept this - license. - . - (11) If your Modified Version has been derived from a Modified - Version made by someone other than you, you are nevertheless required - to ensure that your Modified Version complies with the requirements of - this license. - . - (12) This license does not grant you the right to use any trademark, - service mark, tradename, or logo of the Copyright Holder. - . - (13) This license includes the non-exclusive, worldwide, - free-of-charge patent license to make, have made, use, offer to sell, - sell, import and otherwise transfer the Package with respect to any - patent claims licensable by the Copyright Holder that are necessarily - infringed by the Package. If you institute patent litigation - (including a cross-claim or counterclaim) against any party alleging - that the Package constitutes direct or contributory patent - infringement, then this Artistic License to you shall terminate on the - date that such litigation is filed. - . - (14) Disclaimer of Warranty: - THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS - IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR - NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL - LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL - DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -License: BSD-2-clause - All rights reserved. - . - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - . - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - . - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -License: Bormann-Degener - Any use of this software is permitted provided that this notice is not - removed and that neither the authors nor the Technische Universitaet Berlin - are deemed to have made any representations as to the suitability of this - software for any purpose nor are held responsible for any defects of - this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - . - As a matter of courtesy, the authors request to be informed about uses - this software has found, about bugs in this software, and about any - improvements that may be of general interest. - -License: CC-BY-SA-3 - Creative Commons Legal Code - . - Attribution-ShareAlike 3.0 Unported - . - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR - DAMAGES RESULTING FROM ITS USE. - . - License - . - THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE - COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY - COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS - AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - . - BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE - TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY - BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS - CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND - CONDITIONS. - . - 1. Definitions - . - a. "Adaptation" means a work based upon the Work, or upon the Work and - other pre-existing works, such as a translation, adaptation, - derivative work, arrangement of music or other alterations of a - literary or artistic work, or phonogram or performance and includes - cinematographic adaptations or any other form in which the Work may be - recast, transformed, or adapted including in any form recognizably - derived from the original, except that a work that constitutes a - Collection will not be considered an Adaptation for the purpose of - this License. For the avoidance of doubt, where the Work is a musical - work, performance or phonogram, the synchronization of the Work in - timed-relation with a moving image ("synching") will be considered an - Adaptation for the purpose of this License. - b. "Collection" means a collection of literary or artistic works, such as - encyclopedias and anthologies, or performances, phonograms or - broadcasts, or other works or subject matter other than works listed - in Section 1(f) below, which, by reason of the selection and - arrangement of their contents, constitute intellectual creations, in - which the Work is included in its entirety in unmodified form along - with one or more other contributions, each constituting separate and - independent works in themselves, which together are assembled into a - collective whole. A work that constitutes a Collection will not be - considered an Adaptation (as defined below) for the purposes of this - License. - c. "Creative Commons Compatible License" means a license that is listed - at https://creativecommons.org/compatiblelicenses that has been - approved by Creative Commons as being essentially equivalent to this - License, including, at a minimum, because that license: (i) contains - terms that have the same purpose, meaning and effect as the License - Elements of this License; and, (ii) explicitly permits the relicensing - of adaptations of works made available under that license under this - License or a Creative Commons jurisdiction license with the same - License Elements as this License. - d. "Distribute" means to make available to the public the original and - copies of the Work or Adaptation, as appropriate, through sale or - other transfer of ownership. - e. "License Elements" means the following high-level license attributes - as selected by Licensor and indicated in the title of this License: - Attribution, ShareAlike. - f. "Licensor" means the individual, individuals, entity or entities that - offer(s) the Work under the terms of this License. - g. "Original Author" means, in the case of a literary or artistic work, - the individual, individuals, entity or entities who created the Work - or if no individual or entity can be identified, the publisher; and in - addition (i) in the case of a performance the actors, singers, - musicians, dancers, and other persons who act, sing, deliver, declaim, - play in, interpret or otherwise perform literary or artistic works or - expressions of folklore; (ii) in the case of a phonogram the producer - being the person or legal entity who first fixes the sounds of a - performance or other sounds; and, (iii) in the case of broadcasts, the - organization that transmits the broadcast. - h. "Work" means the literary and/or artistic work offered under the terms - of this License including without limitation any production in the - literary, scientific and artistic domain, whatever may be the mode or - form of its expression including digital form, such as a book, - pamphlet and other writing; a lecture, address, sermon or other work - of the same nature; a dramatic or dramatico-musical work; a - choreographic work or entertainment in dumb show; a musical - composition with or without words; a cinematographic work to which are - assimilated works expressed by a process analogous to cinematography; - a work of drawing, painting, architecture, sculpture, engraving or - lithography; a photographic work to which are assimilated works - expressed by a process analogous to photography; a work of applied - art; an illustration, map, plan, sketch or three-dimensional work - relative to geography, topography, architecture or science; a - performance; a broadcast; a phonogram; a compilation of data to the - extent it is protected as a copyrightable work; or a work performed by - a variety or circus performer to the extent it is not otherwise - considered a literary or artistic work. - i. "You" means an individual or entity exercising rights under this - License who has not previously violated the terms of this License with - respect to the Work, or who has received express permission from the - Licensor to exercise rights under this License despite a previous - violation. - j. "Publicly Perform" means to perform public recitations of the Work and - to communicate to the public those public recitations, by any means or - process, including by wire or wireless means or public digital - performances; to make available to the public Works in such a way that - members of the public may access these Works from a place and at a - place individually chosen by them; to perform the Work to the public - by any means or process and the communication to the public of the - performances of the Work, including by public digital performance; to - broadcast and rebroadcast the Work by any means including signs, - sounds or images. - k. "Reproduce" means to make copies of the Work by any means including - without limitation by sound or visual recordings and the right of - fixation and reproducing fixations of the Work, including storage of a - protected performance or phonogram in digital form or other electronic - medium. - . - 2. Fair Dealing Rights. Nothing in this License is intended to reduce, - limit, or restrict any uses free from copyright or rights arising from - limitations or exceptions that are provided for in connection with the - copyright protection under copyright law or other applicable laws. - . - 3. License Grant. Subject to the terms and conditions of this License, - Licensor hereby grants You a worldwide, royalty-free, non-exclusive, - perpetual (for the duration of the applicable copyright) license to - exercise the rights in the Work as stated below: - . - a. to Reproduce the Work, to incorporate the Work into one or more - Collections, and to Reproduce the Work as incorporated in the - Collections; - b. to create and Reproduce Adaptations provided that any such Adaptation, - including any translation in any medium, takes reasonable steps to - clearly label, demarcate or otherwise identify that changes were made - to the original Work. For example, a translation could be marked "The - original work was translated from English to Spanish," or a - modification could indicate "The original work has been modified."; - c. to Distribute and Publicly Perform the Work including as incorporated - in Collections; and, - d. to Distribute and Publicly Perform Adaptations. - e. For the avoidance of doubt: - . - i. Non-waivable Compulsory License Schemes. In those jurisdictions in - which the right to collect royalties through any statutory or - compulsory licensing scheme cannot be waived, the Licensor - reserves the exclusive right to collect such royalties for any - exercise by You of the rights granted under this License; - ii. Waivable Compulsory License Schemes. In those jurisdictions in - which the right to collect royalties through any statutory or - compulsory licensing scheme can be waived, the Licensor waives the - exclusive right to collect such royalties for any exercise by You - of the rights granted under this License; and, - iii. Voluntary License Schemes. The Licensor waives the right to - collect royalties, whether individually or, in the event that the - Licensor is a member of a collecting society that administers - voluntary licensing schemes, via that society, from any exercise - by You of the rights granted under this License. - . - The above rights may be exercised in all media and formats whether now - known or hereafter devised. The above rights include the right to make - such modifications as are technically necessary to exercise the rights in - other media and formats. Subject to Section 8(f), all rights not expressly - granted by Licensor are hereby reserved. - . - 4. Restrictions. The license granted in Section 3 above is expressly made - subject to and limited by the following restrictions: - . - a. You may Distribute or Publicly Perform the Work only under the terms - of this License. You must include a copy of, or the Uniform Resource - Identifier (URI) for, this License with every copy of the Work You - Distribute or Publicly Perform. You may not offer or impose any terms - on the Work that restrict the terms of this License or the ability of - the recipient of the Work to exercise the rights granted to that - recipient under the terms of the License. You may not sublicense the - Work. You must keep intact all notices that refer to this License and - to the disclaimer of warranties with every copy of the Work You - Distribute or Publicly Perform. When You Distribute or Publicly - Perform the Work, You may not impose any effective technological - measures on the Work that restrict the ability of a recipient of the - Work from You to exercise the rights granted to that recipient under - the terms of the License. This Section 4(a) applies to the Work as - incorporated in a Collection, but this does not require the Collection - apart from the Work itself to be made subject to the terms of this - License. If You create a Collection, upon notice from any Licensor You - must, to the extent practicable, remove from the Collection any credit - as required by Section 4(c), as requested. If You create an - Adaptation, upon notice from any Licensor You must, to the extent - practicable, remove from the Adaptation any credit as required by - Section 4(c), as requested. - b. You may Distribute or Publicly Perform an Adaptation only under the - terms of: (i) this License; (ii) a later version of this License with - the same License Elements as this License; (iii) a Creative Commons - jurisdiction license (either this or a later license version) that - contains the same License Elements as this License (e.g., - Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible - License. If you license the Adaptation under one of the licenses - mentioned in (iv), you must comply with the terms of that license. If - you license the Adaptation under the terms of any of the licenses - mentioned in (i), (ii) or (iii) (the "Applicable License"), you must - comply with the terms of the Applicable License generally and the - following provisions: (I) You must include a copy of, or the URI for, - the Applicable License with every copy of each Adaptation You - Distribute or Publicly Perform; (II) You may not offer or impose any - terms on the Adaptation that restrict the terms of the Applicable - License or the ability of the recipient of the Adaptation to exercise - the rights granted to that recipient under the terms of the Applicable - License; (III) You must keep intact all notices that refer to the - Applicable License and to the disclaimer of warranties with every copy - of the Work as included in the Adaptation You Distribute or Publicly - Perform; (IV) when You Distribute or Publicly Perform the Adaptation, - You may not impose any effective technological measures on the - Adaptation that restrict the ability of a recipient of the Adaptation - from You to exercise the rights granted to that recipient under the - terms of the Applicable License. This Section 4(b) applies to the - Adaptation as incorporated in a Collection, but this does not require - the Collection apart from the Adaptation itself to be made subject to - the terms of the Applicable License. - c. If You Distribute, or Publicly Perform the Work or any Adaptations or - Collections, You must, unless a request has been made pursuant to - Section 4(a), keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) the - name of the Original Author (or pseudonym, if applicable) if supplied, - and/or if the Original Author and/or Licensor designate another party - or parties (e.g., a sponsor institute, publishing entity, journal) for - attribution ("Attribution Parties") in Licensor's copyright notice, - terms of service or by other reasonable means, the name of such party - or parties; (ii) the title of the Work if supplied; (iii) to the - extent reasonably practicable, the URI, if any, that Licensor - specifies to be associated with the Work, unless such URI does not - refer to the copyright notice or licensing information for the Work; - and (iv) , consistent with Ssection 3(b), in the case of an - Adaptation, a credit identifying the use of the Work in the Adaptation - (e.g., "French translation of the Work by Original Author," or - "Screenplay based on original Work by Original Author"). The credit - required by this Section 4(c) may be implemented in any reasonable - manner; provided, however, that in the case of a Adaptation or - Collection, at a minimum such credit will appear, if a credit for all - contributing authors of the Adaptation or Collection appears, then as - part of these credits and in a manner at least as prominent as the - credits for the other contributing authors. For the avoidance of - doubt, You may only use the credit required by this Section for the - purpose of attribution in the manner set out above and, by exercising - Your rights under this License, You may not implicitly or explicitly - assert or imply any connection with, sponsorship or endorsement by the - Original Author, Licensor and/or Attribution Parties, as appropriate, - of You or Your use of the Work, without the separate, express prior - written permission of the Original Author, Licensor and/or Attribution - Parties. - d. Except as otherwise agreed in writing by the Licensor or as may be - otherwise permitted by applicable law, if You Reproduce, Distribute or - Publicly Perform the Work either by itself or as part of any - Adaptations or Collections, You must not distort, mutilate, modify or - take other derogatory action in relation to the Work which would be - prejudicial to the Original Author's honor or reputation. Licensor - agrees that in those jurisdictions (e.g. Japan), in which any exercise - of the right granted in Section 3(b) of this License (the right to - make Adaptations) would be deemed to be a distortion, mutilation, - modification or other derogatory action prejudicial to the Original - Author's honor and reputation, the Licensor will waive or not assert, - as appropriate, this Section, to the fullest extent permitted by the - applicable national law, to enable You to reasonably exercise Your - right under Section 3(b) of this License (right to make Adaptations) - but not otherwise. - . - 5. Representations, Warranties and Disclaimer - . - UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR - OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY - KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, - INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, - FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF - LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, - WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION - OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - . - 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE - LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR - ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES - ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS - BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - . - 7. Termination - . - a. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Adaptations or Collections - from You under this License, however, will not have their licenses - terminated provided such individuals or entities remain in full - compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will - survive any termination of this License. - b. Subject to the above terms and conditions, the license granted here is - perpetual (for the duration of the applicable copyright in the Work). - Notwithstanding the above, Licensor reserves the right to release the - Work under different license terms or to stop distributing the Work at - any time; provided, however that any such election will not serve to - withdraw this License (or any other license that has been, or is - required to be, granted under the terms of this License), and this - License will continue in full force and effect unless terminated as - stated above. - . - 8. Miscellaneous - . - a. Each time You Distribute or Publicly Perform the Work or a Collection, - the Licensor offers to the recipient a license to the Work on the same - terms and conditions as the license granted to You under this License. - b. Each time You Distribute or Publicly Perform an Adaptation, Licensor - offers to the recipient a license to the original Work on the same - terms and conditions as the license granted to You under this License. - c. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of - the remainder of the terms of this License, and without further action - by the parties to this agreement, such provision shall be reformed to - the minimum extent necessary to make such provision valid and - enforceable. - d. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in writing - and signed by the party to be charged with such waiver or consent. - e. This License constitutes the entire agreement between the parties with - respect to the Work licensed here. There are no understandings, - agreements or representations with respect to the Work not specified - here. Licensor shall not be bound by any additional provisions that - may appear in any communication from You. This License may not be - modified without the mutual written agreement of the Licensor and You. - f. The rights granted under, and the subject matter referenced, in this - License were drafted utilizing the terminology of the Berne Convention - for the Protection of Literary and Artistic Works (as amended on - September 28, 1979), the Rome Convention of 1961, the WIPO Copyright - Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 - and the Universal Copyright Convention (as revised on July 24, 1971). - These rights and subject matter take effect in the relevant - jurisdiction in which the License terms are sought to be enforced - according to the corresponding provisions of the implementation of - those treaty provisions in the applicable national law. If the - standard suite of rights granted under applicable copyright law - includes additional rights not granted under this License, such - additional rights are deemed to be included in the License; this - License is not intended to restrict the license of any rights under - applicable law. - . - Creative Commons Notice - . - Creative Commons is not a party to this License, and makes no warranty - whatsoever in connection with the Work. Creative Commons will not be - liable to You or any party on any legal theory for any damages - whatsoever, including without limitation any general, special, - incidental or consequential damages arising in connection to this - license. Notwithstanding the foregoing two (2) sentences, if Creative - Commons has expressly identified itself as the Licensor hereunder, it - shall have all rights and obligations of Licensor. - . - Except for the limited purpose of indicating to the public that the - Work is licensed under the CCPL, Creative Commons does not authorize - the use by either party of the trademark "Creative Commons" or any - related trademark or logo of Creative Commons without the prior - written consent of Creative Commons. Any permitted use will be in - compliance with Creative Commons' then-current trademark usage - guidelines, as may be published on its website or otherwise made - available upon request from time to time. For the avoidance of doubt, - this trademark restriction does not form part of the License. - . - Creative Commons may be contacted at https://creativecommons.org/. - -License: CC-BY-SA-4 - Attribution-ShareAlike 4.0 International - . - ======================================================================= - . - Creative Commons Corporation ("Creative Commons") is not a law firm and - does not provide legal services or legal advice. Distribution of - Creative Commons public licenses does not create a lawyer-client or - other relationship. Creative Commons makes its licenses and related - information available on an "as-is" basis. Creative Commons gives no - warranties regarding its licenses, any material licensed under their - terms and conditions, or any related information. Creative Commons - disclaims all liability for damages resulting from their use to the - fullest extent possible. - . - Using Creative Commons Public Licenses - . - Creative Commons public licenses provide a standard set of terms and - conditions that creators and other rights holders may use to share - original works of authorship and other material subject to copyright - and certain other rights specified in the public license below. The - following considerations are for informational purposes only, are not - exhaustive, and do not form part of our licenses. - . - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - . - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - . - ======================================================================= - . - Creative Commons Attribution-ShareAlike 4.0 International Public - License - . - By exercising the Licensed Rights (defined below), You accept and agree - to be bound by the terms and conditions of this Creative Commons - Attribution-ShareAlike 4.0 International Public License ("Public - License"). To the extent this Public License may be interpreted as a - contract, You are granted the Licensed Rights in consideration of Your - acceptance of these terms and conditions, and the Licensor grants You - such rights in consideration of benefits the Licensor receives from - making the Licensed Material available under these terms and - conditions. - . - . - Section 1 -- Definitions. - . - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - . - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - . - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - . - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - . - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - . - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - . - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - . - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - . - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - . - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - . - k. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - . - l. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - . - m. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - . - . - Section 2 -- Scope. - . - a. License grant. - . - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - . - a. reproduce and Share the Licensed Material, in whole or - in part; and - . - b. produce, reproduce, and Share Adapted Material. - . - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - . - 3. Term. The term of this Public License is specified in Section - 6(a). - . - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - . - 5. Downstream recipients. - . - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - . - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - . - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - . - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - . - b. Other rights. - . - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - . - 2. Patent and trademark rights are not licensed under this - Public License. - . - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - . - . - Section 3 -- License Conditions. - . - Your exercise of the Licensed Rights is expressly made subject to the - following conditions. - . - a. Attribution. - . - 1. If You Share the Licensed Material (including in modified - form), You must: - . - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - . - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - . - ii. a copyright notice; - . - iii. a notice that refers to this Public License; - . - iv. a notice that refers to the disclaimer of - warranties; - . - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - . - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - . - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - . - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - . - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - . - b. ShareAlike. - . - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - . - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - . - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - . - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - . - . - Section 4 -- Sui Generis Database Rights. - . - Where the Licensed Rights include Sui Generis Database Rights that - apply to Your use of the Licensed Material: - . - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - . - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - . - including for purposes of Section 3(b); and - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - . - For the avoidance of doubt, this Section 4 supplements and does not - replace Your obligations under this Public License where the Licensed - Rights include other Copyright and Similar Rights. - . - . - Section 5 -- Disclaimer of Warranties and Limitation of Liability. - . - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - . - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - . - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - . - . - Section 6 -- Term and Termination. - . - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - . - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - . - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - . - 2. upon express reinstatement by the Licensor. - . - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - . - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - . - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - . - . - Section 7 -- Other Terms and Conditions. - . - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - . - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - . - . - Section 8 -- Interpretation. - . - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - . - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - . - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - . - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - . - . - ======================================================================= - . - Creative Commons is not a party to its public - licenses. Notwithstanding, Creative Commons may elect to apply one of - its public licenses to material it publishes and in those instances - will be considered the “Licensor.” The text of the Creative Commons - public licenses is dedicated to the public domain under the CC0 Public - Domain Dedication. Except for the limited purpose of indicating that - material is shared under a Creative Commons public license or as - otherwise permitted by the Creative Commons policies published at - creativecommons.org/policies, Creative Commons does not authorize the - use of the trademark "Creative Commons" or any other trademark or logo - of Creative Commons without its prior written consent including, - without limitation, in connection with any unauthorized modifications - to any of its public licenses or any other arrangements, - understandings, or agreements concerning use of licensed material. For - the avoidance of doubt, this paragraph does not form part of the - public licenses. - . - Creative Commons may be contacted at creativecommons.org. - -License: Expat - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - . - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -License: GPL-2+ - This program 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. - . - This program 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 this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - . - On Debian systems, the complete text of the GNU General Public License - can be found in `/usr/share/common-licenses/GPL-2'. - -License: LGPL-2+ - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - . - This library 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 - Library General Public License for more details. - . - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - . - On Debian systems, the complete text of the GNU Library General Public License - can be found in `/usr/share/common-licenses/LGPL-2'. - -License: LGPL-2.1+ - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - . - This library 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 - Lesser General Public License for more details. - . - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - . - On Debian systems, the complete text of the GNU Lesser General Public License - can be found in `/usr/share/common-licenses/LGPL-2.1'. - -License: WOL - Permission to use, copy, modify, distribute and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice and this license appear in all source copies. - THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF - ANY KIND. See https://www.dspguru.com/wol.htm for more information. - -License: non-free - This license does not comply with Debian Free Software Guidelines. diff --git a/debian/gbp.conf b/debian/gbp.conf deleted file mode 100644 index cec628c74..000000000 --- a/debian/gbp.conf +++ /dev/null @@ -1,2 +0,0 @@ -[DEFAULT] -pristine-tar = True diff --git a/debian/lmms-bin.install b/debian/lmms-bin.install deleted file mode 100644 index 229fa02e3..000000000 --- a/debian/lmms-bin.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/bin/lmms -usr/lib/*/lmms/ladspa/* -usr/lib/*/lmms/lib* -usr/lib/*/lmms/RemoteZynAddSubFx diff --git a/debian/lmms-bin.lintian-overrides b/debian/lmms-bin.lintian-overrides deleted file mode 100644 index 45e07c39d..000000000 --- a/debian/lmms-bin.lintian-overrides +++ /dev/null @@ -1,9 +0,0 @@ -lmms: pkg-has-shlibs-control-file-but-no-actual-shared-libs -lmms: postinst-has-useless-call-to-ldconfig -lmms: postrm-has-useless-call-to-ldconfig - -# env is used to set the environment, then lmms is called. -lmms: desktop-command-not-in-package usr/share/applications/lmms.desktop env - -# Icon is in lmms-common. -lmms: menu-icon-missing usr/share/pixmaps/lmms.xpm diff --git a/debian/lmms-common.docs b/debian/lmms-common.docs deleted file mode 100644 index a7b624a0a..000000000 --- a/debian/lmms-common.docs +++ /dev/null @@ -1 +0,0 @@ -plugins/LadspaEffect/caps/caps.html diff --git a/debian/lmms-common.install b/debian/lmms-common.install deleted file mode 100644 index 467ee8798..000000000 --- a/debian/lmms-common.install +++ /dev/null @@ -1,25 +0,0 @@ -usr/share/applications -usr/share/bash-completion -usr/share/icons -usr/share/lmms/[a-o]* -usr/share/lmms/presets/[A-Y]* -usr/share/lmms/projects/demos/Alf42red-* -usr/share/lmms/projects/demos/CapDan -usr/share/lmms/projects/demos/EsoXLB-* -usr/share/lmms/projects/demos/Impulslogik-* -usr/share/lmms/projects/demos/Jousboxx-* -usr/share/lmms/projects/demos/Momo64-* -usr/share/lmms/projects/demos/Oglsdl-* -usr/share/lmms/projects/demos/Settel-* -usr/share/lmms/projects/demos/Socceroos-* -usr/share/lmms/projects/demos/TameAnderson-* -usr/share/lmms/projects/demos/Thomasso-* -usr/share/lmms/projects/shorties/Crunk* -usr/share/lmms/projects/shorties/Greshz-* -usr/share/lmms/projects/shorties/Surrender-* -usr/share/lmms/projects/templates -usr/share/lmms/projects/tutorials -usr/share/lmms/[q-z]* -usr/share/man -usr/share/mime -debian/lmms.xpm usr/share/pixmaps/ diff --git a/debian/lmms-common.links b/debian/lmms-common.links deleted file mode 100644 index 75596233c..000000000 --- a/debian/lmms-common.links +++ /dev/null @@ -1 +0,0 @@ -usr/share/zynaddsubfx/banks usr/share/lmms/presets/ZynAddSubFX diff --git a/debian/lmms-common.maintscript b/debian/lmms-common.maintscript deleted file mode 100644 index 15d673556..000000000 --- a/debian/lmms-common.maintscript +++ /dev/null @@ -1 +0,0 @@ -dir_to_symlink /usr/share/lmms/presets/ZynAddSubFX ../../zynaddsubfx/banks 1.1.3-2~ diff --git a/debian/lmms-vst-server.install b/debian/lmms-vst-server.install deleted file mode 100644 index 60efaed7b..000000000 --- a/debian/lmms-vst-server.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/lmms/{32/,}RemoteVstPlugin* diff --git a/debian/lmms.xpm b/debian/lmms.xpm deleted file mode 100644 index 425e3156d..000000000 --- a/debian/lmms.xpm +++ /dev/null @@ -1,103 +0,0 @@ -/* XPM */ -static char * lmms_xpm[] = { -"24 24 76 1", -" c None", -". c #208B4D", -"+ c #208C4D", -"@ c #229452", -"# c #239654", -"$ c #239754", -"% c #299557", -"& c #2A9658", -"* c #239B56", -"= c #249B56", -"- c #249C57", -"; c #249D57", -"> c #259E58", -", c #259F59", -"' c #25A059", -") c #25A15A", -"! c #25A25A", -"~ c #25A35A", -"{ c #26A35B", -"] c #26A45B", -"^ c #26A55C", -"/ c #26A65C", -"( c #26A65D", -"_ c #3E9E67", -": c #26A75D", -"< c #28A75E", -"[ c #28A75F", -"} c #27A85E", -"| c #27A95E", -"1 c #27AA5F", -"2 c #27AB5F", -"3 c #29AC60", -"4 c #2AAC61", -"5 c #2FAC64", -"6 c #54A275", -"7 c #33AE67", -"8 c #56A477", -"9 c #2AB365", -"0 c #5BA67B", -"a c #3CB36F", -"b c #41B572", -"c c #64B285", -"d c #50BA7D", -"e c #58B881", -"f c #5CBA84", -"g c #56BC82", -"h c #5FBB86", -"i c #34D07B", -"j c #34D17A", -"k c #34D17B", -"l c #68C28F", -"m c #77C899", -"n c #7DCD9F", -"o c #90C7A8", -"p c #8CD2AA", -"q c #9AD7B4", -"r c #A9DDBF", -"s c #B0E0C5", -"t c #BDDDCB", -"u c #C3DFCF", -"v c #BFE6CF", -"w c #CBE3D5", -"x c #C5E6D3", -"y c #CDE9D9", -"z c #D1EDDD", -"A c #D7EFE2", -"B c #E1F0E8", -"C c #E6F5EC", -"D c #EAF6EF", -"E c #F3FAF6", -"F c #F7FBF9", -"G c #F8FBFA", -"H c #F6FCF9", -"I c #FCFEFD", -"J c #FDFEFE", -"K c #FFFFFF", -" ", -" kiiiiiiiiiiiiiiiiiij ", -" j92222222222222222229i ", -" i22222222222222222222i ", -" i22222222asvb22222222i ", -" i2222223nEKKHp4222222i ", -" i11111dzKKKKKKAg11111i ", -" i|||5qIKKBccBKKJr7|||i ", -" i}}lCKKFo%))&oGKKDm}}i ", -" i::KKKt_*(::(*_tKKK::i ", -" i//KKK@~//////~@KKK//i ", -" i^^KKK^^^^^^^^^^KKK^^i ", -" i]]KKK]]]]]]]]]]KKK]]i ", -" i{{KKKf{{{{{{{{fKKK{{i ", -" i!!KKKKyh!!!!exKKKK!!i ", -" i))KKKKKK))))KKKKKK))i ", -" i''KKKKKK''''KKKKKK''i ", -" i,,KKKKKK,,,,KKKKKK,,i ", -" i>>6uKKw0>>>>6uKKw0>>i ", -" i;;$+88.$;;;;$+88.$;;i ", -" i----##--------##----i ", -" j<==================[i ", -" jiiiiiiiiiiiiiiiiiii ", -" "}; diff --git a/debian/patches/build-amd64-20181013.patch b/debian/patches/build-amd64-20181013.patch deleted file mode 100644 index a9bb61da4..000000000 --- a/debian/patches/build-amd64-20181013.patch +++ /dev/null @@ -1,46 +0,0 @@ -Description: Fix build as of 2018-10-13 - Fix build errors, possibly introduced with GCC 8. -Author: Javier Serrano Polo -Bug-Debian: https://bugs.debian.org/897806 - -Index: lmms-1.1.3/plugins/LadspaEffect/caps/dsp/FPTruncateMode.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/caps/dsp/FPTruncateMode.h -+++ lmms-1.1.3/plugins/LadspaEffect/caps/dsp/FPTruncateMode.h -@@ -40,9 +40,11 @@ class FPTruncateMode - - FPTruncateMode() - { -+#ifdef __i386__ - fstcw (cw0); - cw1 = cw0 | 0xC00; - fldcw (cw1); -+#endif - } - - ~FPTruncateMode() -Index: lmms-1.1.3/plugins/ZynAddSubFx/zynaddsubfx/src/Synth/OscilGen.cpp -=================================================================== ---- lmms-1.1.3.orig/plugins/ZynAddSubFx/zynaddsubfx/src/Synth/OscilGen.cpp -+++ lmms-1.1.3/plugins/ZynAddSubFx/zynaddsubfx/src/Synth/OscilGen.cpp -@@ -33,7 +33,8 @@ - //operations on FFTfreqs - inline void clearAll(fft_t *freqs) - { -- memset(freqs, 0, synth->oscilsize / 2 * sizeof(fft_t)); -+ for(int i = 0; i < synth->oscilsize / 2; ++i) -+ freqs[i] = fft_t(0.0f, 0.0f); - } - - inline void clearDC(fft_t *freqs) -@@ -928,8 +929,8 @@ void OscilGen::getspectrum(int n, float - if(what == 0) { - for(int i = 0; i < n; ++i) - outoscilFFTfreqs[i] = fft_t(spc[i], spc[i]); -- memset(outoscilFFTfreqs + n, 0, -- (synth->oscilsize / 2 - n) * sizeof(fft_t)); -+ for(int i = n; i < synth->oscilsize / 2; ++i) -+ outoscilFFTfreqs[i] = fft_t(0.0f, 0.0f); - adaptiveharmonic(outoscilFFTfreqs, 0.0f); - adaptiveharmonicpostprocess(outoscilFFTfreqs, n - 1); - for(int i = 0; i < n; ++i) diff --git a/debian/patches/clang.patch b/debian/patches/clang.patch deleted file mode 100644 index 7bbd15cd8..000000000 --- a/debian/patches/clang.patch +++ /dev/null @@ -1,601 +0,0 @@ -Description: Fix build with Clang - Several issues are present: - - Unused private elements. - - Wrong use of delete. - - Unsupported compiler options. - - Shifting negative values. - - Possible truncations. - - Uninitialized variables. - - Unused code. - - Hiding overloaded virtual functions. - - Declarations outside namespace. - - Mismatched class tag. - . - Be careful editing this patch because allegrosmfwr.cpp has CRLF terminators. -Author: Javier Serrano Polo -Bug: https://github.com/LMMS/lmms/issues/3073 - -Index: lmms-1.1.3/include/AutomatableModel.h -=================================================================== ---- lmms-1.1.3.orig/include/AutomatableModel.h 2017-01-03 13:01:47.000000000 +0100 -+++ lmms-1.1.3/include/AutomatableModel.h 2017-01-03 13:11:25.000000000 +0100 -@@ -307,7 +307,6 @@ - - // most objects will need this temporarily (until sampleExact is - // standard) -- float m_oldValue; - int m_setValueDepth; - - AutoModelVector m_linkedModels; -Index: lmms-1.1.3/plugins/LadspaEffect/calf/CMakeLists.txt -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/CMakeLists.txt 2017-01-03 16:03:14.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/CMakeLists.txt 2017-01-03 16:14:28.000000000 +0100 -@@ -7,11 +7,22 @@ - "${CMAKE_CURRENT_SOURCE_DIR}/src") - INSTALL(TARGETS calf LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") - SET_TARGET_PROPERTIES(calf PROPERTIES PREFIX "") -+ - SET(INLINE_FLAGS "") --IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") --SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") -+ -+INCLUDE(CheckCXXCompilerFlag) -+CHECK_CXX_COMPILER_FLAG(-finline-functions CXX_HAVE_INLINE_FUNCTIONS) -+IF(${CXX_HAVE_INLINE_FUNCTIONS}) -+ SET(INLINE_FLAGS "${INLINE_FLAGS} -finline-functions") - ENDIF() --SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-O2 -finline-functions ${INLINE_FLAGS}") -+CHECK_CXX_COMPILER_FLAG(-finline-functions-called-once -+ CXX_HAVE_INLINE_FUNCTIONS_CALLED_ONCE) -+IF(${CXX_HAVE_INLINE_FUNCTIONS_CALLED_ONCE}) -+ SET(INLINE_FLAGS "${INLINE_FLAGS} -finline-functions-called-once \ -+ -finline-limit=80") -+ENDIF() -+ -+SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-O2 ${INLINE_FLAGS}") - - IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/calf.dll\"") -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/metadata.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/metadata.h 2017-01-03 17:41:17.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/metadata.h 2017-01-03 17:50:40.000000000 +0100 -@@ -51,7 +51,7 @@ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = false, support_midi = false }; - PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter") - /// do not export mode and inertia as CVs, as those are settings and not parameters -- bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } -+ bool is_cv(int param_no) const { return param_no != par_mode && param_no != par_inertia; } - }; - - /// Filterclavier - metadata -@@ -61,7 +61,7 @@ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = true, support_midi = true }; - PLUGIN_NAME_ID_LABEL("filterclavier", "filterclavier", "Filterclavier") - /// do not export mode and inertia as CVs, as those are settings and not parameters -- bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } -+ bool is_cv(int param_no) const { return param_no != par_mode && param_no != par_inertia; } - }; - - struct reverb_metadata: public plugin_metadata -@@ -499,7 +499,7 @@ - PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ") - - public: -- plugin_command_info *get_commands(); -+ plugin_command_info *get_commands() const; - const char *const *get_configure_vars() const; - }; - -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/modules.h 2017-01-03 19:02:59.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules.h 2017-01-03 19:30:35.000000000 +0100 -@@ -89,13 +89,14 @@ - using audio_module::ins; - using audio_module::outs; - using audio_module::params; -+ using FilterClass::calculate_filter; - - dsp::inertia inertia_cutoff, inertia_resonance, inertia_gain; - dsp::once_per_n timer; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - -- filter_module_with_inertia(float **ins, float **outs, float **params) -+ filter_module_with_inertia() - : inertia_cutoff(dsp::exponential_ramp(128), 20) - , inertia_resonance(dsp::exponential_ramp(128), 20) - , inertia_gain(dsp::exponential_ramp(128), 1.0) -@@ -193,7 +194,7 @@ - mutable float old_cutoff, old_resonance, old_mode; - public: - filter_audio_module() -- : filter_module_with_inertia(ins, outs, params) -+ : filter_module_with_inertia() - { - last_generation = 0; - old_mode = old_resonance = old_cutoff = -1; -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules_comp.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/modules_comp.h 2017-01-03 19:35:53.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules_comp.h 2017-01-03 19:38:06.000000000 +0100 -@@ -39,10 +39,10 @@ - class gain_reduction_audio_module - { - private: -- float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; -+ float linSlope, detected, kneeStart, linKneeStart, kneeStop; - float compressedKneeStop, adjKneeStart, thres; - float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp; -- mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; -+ mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection; - mutable volatile int last_generation; - uint32_t srate; - bool is_active; -@@ -69,7 +69,7 @@ - /// Main gate routine by Damien called by various audio modules - class expander_audio_module { - private: -- float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, linKneeStop; -+ float linSlope, detected, kneeStart, linKneeStart, kneeStop, linKneeStop; - float compressedKneeStop, adjKneeStart, range, thres, attack_coeff, release_coeff; - float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_gate; - mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_range, old_trigger, old_mute, old_detection, old_stereo_link; -@@ -142,7 +142,7 @@ - mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; - mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; - CalfScModes sc_mode; -- mutable CalfScModes sc_mode_old, sc_mode_old1; -+ mutable CalfScModes sc_mode_old1; - float f1_active, f2_active; - stereo_in_out_metering meters; - gain_reduction_audio_module compressor; -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules_limit.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/modules_limit.h 2017-01-03 19:39:00.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules_limit.h 2017-01-03 19:40:20.000000000 +0100 -@@ -37,7 +37,6 @@ - private: - typedef limiter_audio_module AM; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR, asc_led; -- int mode, mode_old; - float meter_inL, meter_inR, meter_outL, meter_outR; - dsp::lookahead_limiter limiter; - public: -@@ -73,7 +72,6 @@ - unsigned int overall_buffer_size; - float *buffer; - int channels; -- float striprel[strips]; - float weight[strips]; - float weight_old[strips]; - float limit_old; -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules_mod.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/modules_mod.h 2017-01-03 19:41:55.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/modules_mod.h 2017-01-03 19:42:19.000000000 +0100 -@@ -160,8 +160,6 @@ - typedef pulsator_audio_module AM; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR; - float meter_inL, meter_inR, meter_outL, meter_outR; -- float offset_old; -- int mode_old; - bool clear_reset; - dsp::simple_lfo lfoL, lfoR; - public: -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/organ.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/organ.h 2017-01-03 19:43:08.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/organ.h 2017-01-03 19:53:55.000000000 +0100 -@@ -318,6 +318,7 @@ - using drawbar_organ::note_on; - using drawbar_organ::note_off; - using drawbar_organ::control_change; -+ using drawbar_organ::pitch_bend; - enum { param_count = drawbar_organ::param_count}; - dsp::organ_parameters par_values; - uint32_t srate; -@@ -338,9 +339,9 @@ - void deactivate(); - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); - /// No CV inputs for now -- bool is_cv(int param_no) { return false; } -+ bool is_cv(int param_no) const { return false; } - /// Practically all the stuff here is noisy -- bool is_noisy(int param_no) { return true; } -+ bool is_noisy(int param_no) const { return true; } - void execute(int cmd_no); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - char *configure(const char *key, const char *value); -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/preset.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/preset.h 2017-01-03 19:57:02.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/preset.h 2017-01-03 20:00:25.000000000 +0100 -@@ -27,7 +27,7 @@ - - namespace calf_plugins { - --class plugin_ctl_iface; -+struct plugin_ctl_iface; - - /// Contents of single preset - struct plugin_preset -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/primitives.h -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/calf/primitives.h 2017-01-03 17:36:12.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/calf/primitives.h 2017-01-03 16:22:16.000000000 +0100 -@@ -370,11 +370,6 @@ - next_task = (unsigned)-1; - eob = false; - } -- inline bool is_next_tick() { -- if (time < next_task) -- return true; -- do_tasks(); -- } - inline void next_tick() { - time++; - } -@@ -382,14 +377,6 @@ - timeline.insert(std::pair(time+pos, t)); - next_task = timeline.begin()->first; - } -- void do_tasks() { -- std::multimap::iterator i = timeline.begin(); -- while(i != timeline.end() && i->first == time) { -- i->second->execute(this); -- i->second->dispose(); -- timeline.erase(i); -- } -- } - bool is_eob() { - return eob; - } -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/metadata.cpp -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/metadata.cpp 2017-01-03 17:52:03.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/metadata.cpp 2017-01-03 18:49:18.000000000 +0100 -@@ -29,6 +29,8 @@ - - const char *calf_plugins::calf_copyright_info = "(C) 2001-2009 Krzysztof Foltman, Thor Harald Johanssen, Markus Schmidt and others; license: LGPL"; - -+namespace calf_plugins { -+ - //////////////////////////////////////////////////////////////////////////// - - CALF_PORT_NAMES(flanger) = {"In L", "In R", "Out L", "Out R"}; -@@ -1105,7 +1107,7 @@ - - CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; - --plugin_command_info *organ_metadata::get_commands() -+plugin_command_info *organ_metadata::get_commands() const - { - static plugin_command_info cmds[] = { - { "cmd_panic", "Panic!", "Stop all sounds and reset all controllers" }, -@@ -1439,6 +1441,8 @@ - - //////////////////////////////////////////////////////////////////////////// - -+}; // namespace calf_plugins -+ - calf_plugins::plugin_registry::plugin_registry() - { - #define PER_MODULE_ITEM(name, isSynth, jackname) plugins.push_back((new name##_metadata)); -Index: lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/modules.cpp -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/calf/veal/src/modules.cpp 2017-01-03 19:32:38.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/calf/veal/src/modules.cpp 2017-01-03 19:33:13.000000000 +0100 -@@ -339,7 +339,7 @@ - /////////////////////////////////////////////////////////////////////////////////////////////// - - filterclavier_audio_module::filterclavier_audio_module() --: filter_module_with_inertia(ins, outs, params) -+: filter_module_with_inertia() - , min_gain(1.0) - , max_gain(32.0) - , last_note(-1) -Index: lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/flanger_1191.c -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/swh/ladspa/flanger_1191.c 2017-01-03 15:44:13.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/flanger_1191.c 2017-01-03 15:45:17.000000000 +0100 -@@ -266,7 +266,7 @@ - - // Calculate position in delay table - d_base = LIN_INTERP(frac, old_d_base, new_d_base); -- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; -+ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; - p_ph = n_ph + 0.5f; - while (p_ph > 1.0f) { - p_ph -= 1.0f; -@@ -392,7 +392,7 @@ - - // Calculate position in delay table - d_base = LIN_INTERP(frac, old_d_base, new_d_base); -- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; -+ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; - p_ph = n_ph + 0.5f; - while (p_ph > 1.0f) { - p_ph -= 1.0f; -Index: lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/gsm/short_term.c -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/swh/ladspa/gsm/short_term.c 2017-01-03 15:35:13.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/gsm/short_term.c 2017-01-03 15:35:55.000000000 +0100 -@@ -53,7 +53,7 @@ - #undef STEP - #define STEP( B, MIC, INVA ) \ - temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ -- temp1 = GSM_SUB( temp1, B << 1 ); \ -+ temp1 = GSM_SUB( temp1, B * 2 ); \ - temp1 = GSM_MULT_R( INVA, temp1 ); \ - *LARpp++ = GSM_ADD( temp1, temp1 ); - -Index: lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/multivoice_chorus_1201.c -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/swh/ladspa/multivoice_chorus_1201.c 2017-01-03 15:47:51.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/multivoice_chorus_1201.c 2017-01-03 15:48:18.000000000 +0100 -@@ -345,7 +345,7 @@ - if (count % 16 < laws) { - unsigned int t = count % 16; - // Calculate sinus phases -- float n_ph = (float)(law_p - abs(next_peak_pos[t] - count))/law_p; -+ float n_ph = (float)(law_p - labs(next_peak_pos[t] - count))/law_p; - float p_ph = n_ph + 0.5f; - if (p_ph > 1.0f) { - p_ph -= 1.0f; -@@ -488,7 +488,7 @@ - if (count % 16 < laws) { - unsigned int t = count % 16; - // Calculate sinus phases -- float n_ph = (float)(law_p - abs(next_peak_pos[t] - count))/law_p; -+ float n_ph = (float)(law_p - labs(next_peak_pos[t] - count))/law_p; - float p_ph = n_ph + 0.5f; - if (p_ph > 1.0f) { - p_ph -= 1.0f; -Index: lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/retro_flange_1208.c -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/swh/ladspa/retro_flange_1208.c 2017-01-03 15:46:35.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/retro_flange_1208.c 2017-01-03 15:47:02.000000000 +0100 -@@ -321,7 +321,7 @@ - prev_law_pos = count + law_p; - } - -- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; -+ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; - p_ph = n_ph + 0.5f; - if (p_ph > 1.0f) { - p_ph -= 1.0f; -@@ -446,7 +446,7 @@ - prev_law_pos = count + law_p; - } - -- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; -+ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; - p_ph = n_ph + 0.5f; - if (p_ph > 1.0f) { - p_ph -= 1.0f; -Index: lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/vynil_1905.c -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/swh/ladspa/vynil_1905.c 2017-01-03 15:51:56.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/swh/ladspa/vynil_1905.c 2017-01-03 16:01:32.000000000 +0100 -@@ -243,6 +243,8 @@ - buffer_s = malloc(sizeof(LADSPA_Data) * buffer_size); - buffer_mask = buffer_size - 1; - buffer_pos = 0; -+ click_buffer_omega.all = 0; -+ click_buffer_pos.all = 0; - click_gain = 0; - phi = 0.0f; /* Angular phase */ - -Index: lmms-1.1.3/plugins/LadspaEffect/tap/CMakeLists.txt -=================================================================== ---- lmms-1.1.3.orig/plugins/LadspaEffect/tap/CMakeLists.txt 2017-01-03 13:52:28.000000000 +0100 -+++ lmms-1.1.3/plugins/LadspaEffect/tap/CMakeLists.txt 2017-01-03 15:12:14.000000000 +0100 -@@ -1,7 +1,15 @@ - INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") - FILE(GLOB PLUGIN_SOURCES *.c) - LIST(SORT PLUGIN_SOURCES) --SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wno-write-strings -fomit-frame-pointer -fno-strict-aliasing -fstrength-reduce -funroll-loops -ffast-math") -+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wno-write-strings \ -+ -fomit-frame-pointer -fno-strict-aliasing -funroll-loops -ffast-math") -+ -+INCLUDE(CheckCCompilerFlag) -+CHECK_C_COMPILER_FLAG(-fstrength-reduce C_HAVE_STRENGTH_REDUCE) -+IF(${C_HAVE_STRENGTH_REDUCE}) -+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstrength-reduce") -+ENDIF() -+ - FOREACH(_item ${PLUGIN_SOURCES}) - GET_FILENAME_COMPONENT(_plugin "${_item}" NAME_WE) - ADD_LIBRARY("${_plugin}" MODULE "${_item}") -Index: lmms-1.1.3/plugins/MidiImport/portsmf/allegro.h -=================================================================== ---- lmms-1.1.3.orig/plugins/MidiImport/portsmf/allegro.h 2017-01-03 20:02:37.000000000 +0100 -+++ lmms-1.1.3/plugins/MidiImport/portsmf/allegro.h 2017-01-03 20:06:48.000000000 +0100 -@@ -842,6 +842,8 @@ - Alg_event_ptr write_track_name(std::ostream &file, int n, - Alg_events &events); - public: -+ using Alg_track::paste; -+ - int channel_offset_per_track; // used to encode track_num into channel - Alg_tracks track_list; // array of Alg_events - Alg_time_sigs time_sig; -Index: lmms-1.1.3/plugins/MidiImport/portsmf/allegrosmfwr.cpp -=================================================================== ---- lmms-1.1.3.orig/plugins/MidiImport/portsmf/allegrosmfwr.cpp 2017-01-03 20:07:50.000000000 +0100 -+++ lmms-1.1.3/plugins/MidiImport/portsmf/allegrosmfwr.cpp 2017-01-03 20:08:34.000000000 +0100 -@@ -57,13 +57,11 @@ - - Alg_seq_ptr seq; - -- int num_tracks; // number of tracks not counting tempo track - int division; // divisions per quarter note, default = 120 - int initial_tempo; - - int timesig_num; // numerator of time signature - int timesig_den; // denominator of time signature -- double timesig_when; // time of time signature - - int keysig; // number of sharps (+) or flats (-), -99 for undefined - char keysig_mode; // 'M' or 'm' for major/minor -Index: lmms-1.1.3/plugins/Delay/StereoDelay.cpp -=================================================================== ---- lmms-1.1.3.orig/plugins/Delay/StereoDelay.cpp 2017-01-03 13:40:27.000000000 +0100 -+++ lmms-1.1.3/plugins/Delay/StereoDelay.cpp 2017-01-03 13:42:16.000000000 +0100 -@@ -48,7 +48,7 @@ - { - if( m_buffer ) - { -- delete m_buffer; -+ delete[] m_buffer; - } - } - -@@ -84,7 +84,7 @@ - { - if( m_buffer ) - { -- delete m_buffer; -+ delete[] m_buffer; - } - - int bufferSize = ( int )( sampleRate * m_maxTime ); -Index: lmms-1.1.3/plugins/OpulenZ/adplug/src/fmopl.c -=================================================================== ---- lmms-1.1.3.orig/plugins/OpulenZ/adplug/src/fmopl.c 2017-01-03 20:11:03.000000000 +0100 -+++ lmms-1.1.3/plugins/OpulenZ/adplug/src/fmopl.c 2017-01-03 20:22:23.000000000 +0100 -@@ -70,7 +70,7 @@ - /* final output shift , limit minimum and maximum */ - #define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ - #define OPL_MAXOUT (0x7fff<\n' ' \n' @@ -131,24 +129,6 @@ with tempfile.TemporaryDirectory() as tmpdir: test.expect('Error: data/themes/classic/style.css: Class does not exist in source code: NonExistentClass') test.expect('1 errors') - with ScriptTest(check_strings) as test: - create_file('debian/patches/clang.patch', '/plugins/non-existent-file') - test.run() - test.expect('Error: debian/patches/clang.patch: Source file does not exist: plugins/non-existent-file') - test.expect('1 errors') - - with ScriptTest(check_strings) as test: - create_file('debian/lmms-common.docs', '/plugins/caps.html') - test.run() - test.expect('Error: debian/lmms-common.docs: Path does not exist: /plugins/caps.html') - test.expect('1 errors') - - with ScriptTest(check_strings) as test: - create_file('debian/copyright', 'Files: NonExistent') - test.run() - test.expect('Error: debian/copyright: Glob/Path does not exist: NonExistent') - test.expect('1 errors') - with ScriptTest(check_namespace) as test: # minimal working example test.run(0) # exitcode 0 - no errors expected From 01ffa9557806ecd9b2ecd5763aba16367e5f9935 Mon Sep 17 00:00:00 2001 From: saker Date: Sat, 15 Jun 2024 18:34:10 -0400 Subject: [PATCH 08/31] Use `src_set_ratio` to fix artifacts within `Sample` playback (#7321) --- include/AudioResampler.h | 1 + src/core/AudioResampler.cpp | 5 +++++ src/core/Sample.cpp | 2 ++ 3 files changed, 8 insertions(+) diff --git a/include/AudioResampler.h b/include/AudioResampler.h index 379146962..6dd6fcc60 100644 --- a/include/AudioResampler.h +++ b/include/AudioResampler.h @@ -52,6 +52,7 @@ public: auto resample(const float* in, long inputFrames, float* out, long outputFrames, double ratio) -> ProcessResult; auto interpolationMode() const -> int { return m_interpolationMode; } auto channels() const -> int { return m_channels; } + void setRatio(double ratio); private: int m_interpolationMode = -1; diff --git a/src/core/AudioResampler.cpp b/src/core/AudioResampler.cpp index 5f6b6a239..8fb7d95a2 100644 --- a/src/core/AudioResampler.cpp +++ b/src/core/AudioResampler.cpp @@ -61,4 +61,9 @@ auto AudioResampler::resample(const float* in, long inputFrames, float* out, lon return {src_process(m_state, &data), data.input_frames_used, data.output_frames_gen}; } +void AudioResampler::setRatio(double ratio) +{ + src_set_ratio(m_state, ratio); +} + } // namespace lmms diff --git a/src/core/Sample.cpp b/src/core/Sample.cpp index 584d1bc13..f1fe1ec1a 100644 --- a/src/core/Sample.cpp +++ b/src/core/Sample.cpp @@ -134,6 +134,8 @@ bool Sample::play(sampleFrame* dst, PlaybackState* state, size_t numFrames, floa auto playBuffer = std::vector(numFrames / resampleRatio + marginSize); playRaw(playBuffer.data(), playBuffer.size(), state, loopMode); + state->resampler().setRatio(resampleRatio); + const auto resampleResult = state->resampler().resample(&playBuffer[0][0], playBuffer.size(), &dst[0][0], numFrames, resampleRatio); advance(state, resampleResult.inputFramesUsed, loopMode); From 2adbb166b5514ad0d4c9e18a4f86759d042526d8 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:11:55 +0200 Subject: [PATCH 09/31] arpeggiator sorted mode fixed (#7025) Fixes an issue where sorted arpeggios over multiple notes used a largely unusable algorithm. piano-octave-arp instead of octave-arp-piano. Fixes #6499 Fixes #4491 --- src/core/InstrumentFunctions.cpp | 67 +++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 549d658fc..3687c0b74 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -31,6 +31,9 @@ #include "InstrumentTrack.h" #include "PresetPreviewPlayHandle.h" +#include +#include + namespace lmms { @@ -348,10 +351,11 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) _n->setMasterNote(); const int selected_arp = m_arpModel.value(); + const auto arpMode = static_cast(m_arpModeModel.value()); - ConstNotePlayHandleList cnphv = NotePlayHandle::nphsOfInstrumentTrack( _n->instrumentTrack() ); + ConstNotePlayHandleList cnphv = NotePlayHandle::nphsOfInstrumentTrack(_n->instrumentTrack()); - if( static_cast(m_arpModeModel.value()) != ArpMode::Free && cnphv.size() == 0 ) + if(arpMode != ArpMode::Free && cnphv.size() == 0 ) { // maybe we're playing only a preset-preview-note? cnphv = PresetPreviewPlayHandle::nphsOfInstrumentTrack( _n->instrumentTrack() ); @@ -363,10 +367,25 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) } } + // avoid playing same key for all + // currently playing notes if sort mode is enabled + if (arpMode == ArpMode::Sort && _n != cnphv.first()) { return; } + const InstrumentFunctionNoteStacking::ChordTable & chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance(); const int cur_chord_size = chord_table.chords()[selected_arp].size(); - const int range = static_cast(cur_chord_size * m_arpRangeModel.value() * m_arpRepeatsModel.value()); - const int total_range = range * cnphv.size(); + const int total_chord_size = cur_chord_size * cnphv.size(); + // how many notes are in a single chord (multiplied by range) + const int singleNoteRange = static_cast(cur_chord_size * m_arpRangeModel.value() * m_arpRepeatsModel.value()); + // how many notes are in the final chord + const int range = arpMode == ArpMode::Sort ? singleNoteRange * cnphv.size() : singleNoteRange; + + if (arpMode == ArpMode::Sort) + { + std::sort(cnphv.begin(), cnphv.end(), [](const NotePlayHandle* a, const NotePlayHandle* b) + { + return a->key() < b->key(); + }); + } // number of frames that every note should be played const auto arp_frames = (f_cnt_t)(m_arpTimeModel.value() / 1000.0f * Engine::audioEngine()->outputSampleRate()); @@ -375,11 +394,11 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) // used for calculating remaining frames for arp-note, we have to add // arp_frames-1, otherwise the first arp-note will not be setup // correctly... -> arp_frames frames silence at the start of every note! - int cur_frame = ( ( static_cast(m_arpModeModel.value()) != ArpMode::Free ) ? + int cur_frame = (arpMode != ArpMode::Free ? cnphv.first()->totalFramesPlayed() : - _n->totalFramesPlayed() ) + arp_frames - 1; + _n->totalFramesPlayed()) + arp_frames - 1; // used for loop - f_cnt_t frames_processed = ( static_cast(m_arpModeModel.value()) != ArpMode::Free ) ? cnphv.first()->noteOffset() : _n->noteOffset(); + f_cnt_t frames_processed = arpMode != ArpMode::Free ? cnphv.first()->noteOffset() : _n->noteOffset(); while( frames_processed < Engine::audioEngine()->framesPerPeriod() ) { @@ -395,17 +414,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) frames_processed += remaining_frames_for_cur_arp; - // in sorted mode: is it our turn or do we have to be quiet for - // now? - if( static_cast(m_arpModeModel.value()) == ArpMode::Sort && - ( ( cur_frame / arp_frames ) % total_range ) / range != (f_cnt_t) _n->index() ) - { - // update counters - frames_processed += arp_frames; - cur_frame += arp_frames; - continue; - } - // Skip notes randomly if( m_arpSkipModel.value() ) { @@ -435,7 +443,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) // process according to arpeggio-direction... if (dir == ArpDirection::Up || dir == ArpDirection::Down) { - cur_arp_idx = ( cur_frame / arp_frames ) % range; + cur_arp_idx = (cur_frame / arp_frames) % range; } else if ((dir == ArpDirection::UpAndDown || dir == ArpDirection::DownAndUp) && range > 1) { @@ -454,7 +462,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) else if( dir == ArpDirection::Random ) { // just pick a random chord-index - cur_arp_idx = (int)( range * ( (float) rand() / (float) RAND_MAX ) ); + cur_arp_idx = static_cast(range * static_cast(rand()) / static_cast(RAND_MAX)); } // Divide cur_arp_idx with wanted repeats. The repeat feature will not affect random notes. @@ -464,7 +472,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) if( m_arpCycleModel.value() && dir != ArpDirection::Random ) { cur_arp_idx *= m_arpCycleModel.value() + 1; - cur_arp_idx %= static_cast( range / m_arpRepeatsModel.value() ); + cur_arp_idx %= static_cast(range / m_arpRepeatsModel.value()); } // If ArpDirection::Down or ArpDirection::DownAndUp, invert the final range. @@ -474,8 +482,23 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) } // now calculate final key for our arp-note - const int sub_note_key = base_note_key + (cur_arp_idx / cur_chord_size ) * + int sub_note_key = 0; + if (arpMode != ArpMode::Sort) + { + sub_note_key = base_note_key + (cur_arp_idx / cur_chord_size) * KeysPerOctave + chord_table.chords()[selected_arp][cur_arp_idx % cur_chord_size]; + } + else + { + const auto octaveDiv = std::div(cur_arp_idx, total_chord_size); + const int octave = octaveDiv.quot; + const auto arpDiv = std::div(octaveDiv.rem, cnphv.size()); + const int arpIndex = arpDiv.rem; + const int chordIndex = arpDiv.quot; + sub_note_key = cnphv[arpIndex]->key() + + chord_table.chords()[selected_arp][chordIndex] + + octave * KeysPerOctave; + } // range-checking if( sub_note_key >= NumKeys || From e76a99ee7608edbd96a693f5d6d65057951cf6b8 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Mon, 17 Jun 2024 22:48:04 +0100 Subject: [PATCH 10/31] Suppress warnings in third-party code (#7319) --- CMakeLists.txt | 98 +++++++----- cmake/modules/StaticDependencies.cmake | 141 ++++++++++++++++++ include/AudioJack.h | 2 +- include/LocklessRingBuffer.h | 4 +- include/Lv2Proc.h | 3 +- include/MidiJack.h | 2 +- plugins/CarlaBase/CMakeLists.txt | 4 +- plugins/CarlaBase/Carla.h | 10 +- plugins/CarlaBase/DummyCarla.cpp | 2 +- plugins/CarlaPatchbay/CMakeLists.txt | 3 +- plugins/CarlaRack/CMakeLists.txt | 3 +- plugins/Eq/CMakeLists.txt | 2 +- plugins/FreeBoy/CMakeLists.txt | 25 ++-- plugins/FreeBoy/FreeBoy.h | 3 +- plugins/FreeBoy/GbApuWrapper.h | 4 +- plugins/GigPlayer/CMakeLists.txt | 2 +- plugins/LadspaEffect/calf/CMakeLists.txt | 10 +- plugins/LadspaEffect/caps/CMakeLists.txt | 8 +- plugins/LadspaEffect/cmt/CMakeLists.txt | 8 +- plugins/LadspaEffect/swh/CMakeLists.txt | 8 +- plugins/LadspaEffect/tap/CMakeLists.txt | 6 +- plugins/Lv2Effect/CMakeLists.txt | 6 +- plugins/Lv2Instrument/CMakeLists.txt | 6 +- plugins/OpulenZ/CMakeLists.txt | 22 ++- plugins/OpulenZ/OpulenZ.cpp | 6 +- plugins/Sid/SidInstrument.cpp | 2 +- plugins/Sid/resid/CMakeLists.txt | 2 + plugins/SlicerT/CMakeLists.txt | 22 ++- plugins/SpectrumAnalyzer/CMakeLists.txt | 2 +- .../VstBase/RemoteVstPlugin/CMakeLists.txt | 2 +- plugins/VstBase/VstPlugin.cpp | 2 +- plugins/Xpressive/CMakeLists.txt | 14 +- plugins/Xpressive/ExprSynth.cpp | 4 +- plugins/ZynAddSubFx/CMakeLists.txt | 49 ++++-- plugins/ZynAddSubFx/LocalZynAddSubFx.cpp | 8 +- plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp | 4 +- plugins/ZynAddSubFx/ZynAddSubFx.h | 4 +- src/3rdparty/CMakeLists.txt | 30 +++- src/3rdparty/weakjack/CMakeLists.txt | 22 +-- src/CMakeLists.txt | 43 ++---- tests/CMakeLists.txt | 5 +- 41 files changed, 396 insertions(+), 207 deletions(-) create mode 100644 cmake/modules/StaticDependencies.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fbd9cdfcf..6aa53d982 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,7 @@ function(enable_policy_if_exists id) endif() endfunction() -# Needed for the SWH Ladspa plugins. See below. -enable_policy_if_exists(CMP0074) # find_package() uses _ROOT variables. +enable_policy_if_exists(CMP0092) # MSVC warning flags are not in CMAKE__FLAGS by default. # Needed for ccache support with MSVC enable_policy_if_exists(CMP0141) # MSVC debug information format flags are selected by an abstraction. @@ -43,6 +42,7 @@ INCLUDE(AddFileDependencies) INCLUDE(CheckIncludeFiles) INCLUDE(FindPkgConfig) INCLUDE(GenerateExportHeader) +include(StaticDependencies) STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE) @@ -172,7 +172,7 @@ LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}") FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml REQUIRED) FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET) -INCLUDE_DIRECTORIES( +include_directories(SYSTEM ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} @@ -410,7 +410,7 @@ IF(WANT_SOUNDIO) IF(SOUNDIO_FOUND) SET(LMMS_HAVE_SOUNDIO TRUE) SET(STATUS_SOUNDIO "OK") - INCLUDE_DIRECTORIES("${SOUNDIO_INCLUDE_DIR}") + include_directories(SYSTEM "${SOUNDIO_INCLUDE_DIR}") ELSE(SOUNDIO_FOUND) SET(SOUNDIO_INCLUDE_DIR "") SET(STATUS_SOUNDIO "not found, please install libsoundio if you require libsoundio support") @@ -491,11 +491,9 @@ ENDIF(NOT LMMS_HAVE_ALSA) IF(WANT_JACK) IF(WANT_WEAKJACK) SET(LMMS_HAVE_WEAKJACK TRUE) - SET(WEAKJACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack) - SET(JACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/jack2/common) SET(STATUS_JACK "OK (weak linking enabled)") - # use dlsym instead - SET(JACK_LIBRARIES ${CMAKE_DL_LIBS}) + set(JACK_INCLUDE_DIRS "") + set(JACK_LIBRARIES weakjack) SET(LMMS_HAVE_JACK TRUE) SET(LMMS_HAVE_JACK_PRENAME TRUE) SET(JACK_FOUND TRUE) @@ -631,28 +629,63 @@ ENDIF(WANT_DEBUG_FPE) # check for libsamplerate FIND_PACKAGE(Samplerate 0.1.8 MODULE REQUIRED) -# set compiler flags -IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - SET(WERROR_FLAGS "-Wall -Werror=unused-function -Wno-sign-compare -Wno-strict-overflow") - OPTION(USE_WERROR "Add -werror to the build flags. Stops the build on warnings" OFF) - IF(${USE_WERROR}) - SET(WERROR_FLAGS "${WERROR_FLAGS} -Werror") - ENDIF() +# Shim the SYSTEM property for older CMake versions +if(CMAKE_VERSION VERSION_LESS "3.25") + define_property(TARGET + PROPERTY SYSTEM + INHERITED + BRIEF_DOCS "Shim of built-in SYSTEM property for CMake versions less than 3.25" + FULL_DOCS "Non-functional, but allows the property to be inherited properly." + "See the CMake documentation at https://cmake.org/cmake/help/latest/prop_tgt/SYSTEM.html." + ) +endif() + +# Add warning and error flags +option(USE_WERROR "Treat compiler warnings as errors" OFF) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(COMPILE_ERROR_FLAGS + "-Wall" # Enable most warnings by default + "-Werror=unused-function" # Unused functions are an error + # TODO: Fix the code and remove the following: + "-Wno-sign-compare" # Permit comparisons between signed and unsigned integers + "-Wno-strict-overflow" # Permit optimisations assuming no signed overflow + ) + set(THIRD_PARTY_COMPILE_ERROR_FLAGS + "-w" # Disable all warnings + ) # Due to a regression in gcc-4.8.X, we need to disable array-bounds check - IF (CMAKE_COMPILER_IS_GNUCXX AND ((CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "4.8.0") OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.8.0") OR LMMS_BUILD_WIN32)) - SET(WERROR_FLAGS "${WERROR_FLAGS} -Wno-array-bounds -Wno-attributes") - ENDIF() -ELSEIF(MSVC) - # Remove any existing /W flags - string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) - STRING(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - SET(WERROR_FLAGS "/W2") - IF(${USE_WERROR}) - SET(WERROR_FLAGS "${WERROR_FLAGS} /WX") - ENDIF() -ENDIF() + # TODO: Is this still necessary? + if(CMAKE_COMPILER_IS_GNUCXX) + list(APPEND COMPILE_ERROR_FLAGS + "-Wno-array-bounds" # Permit out-of-bounds array subscripts + "-Wno-attributes" # Permit unrecognised attributes + ) + endif() + if(USE_WERROR) + list(APPEND COMPILE_ERROR_FLAGS + "-Werror" # Treat warnings as errors + ) + endif() +elseif(MSVC) + set(COMPILE_ERROR_FLAGS + "/W2" # Enable some warnings by default + "/external:W0" # Don't emit warnings for third-party code + "/external:anglebrackets" # Consider headers included with angle brackets to be third-party + "/external:templates-" # Still emit warnings from first-party instantiations of third-party templates + ) + set(THIRD_PARTY_COMPILE_ERROR_FLAGS + "/W0" # Disable all warnings + ) + + if(USE_WERROR) + list(APPEND COMPILE_ERROR_FLAGS + "/WX" # Treat warnings as errors + ) + endif() +endif() +add_compile_options("$>,${THIRD_PARTY_COMPILE_ERROR_FLAGS},${COMPILE_ERROR_FLAGS}>") IF(NOT CMAKE_BUILD_TYPE) message(STATUS "Setting build type to 'Release' as none was specified.") @@ -662,8 +695,6 @@ IF(NOT CMAKE_BUILD_TYPE) "MinSizeRel" "RelWithDebInfo") ENDIF() -SET(CMAKE_C_FLAGS "${WERROR_FLAGS} ${CMAKE_C_FLAGS}") -SET(CMAKE_CXX_FLAGS "${WERROR_FLAGS} ${CMAKE_CXX_FLAGS}") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DLMMS_DEBUG") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLMMS_DEBUG") @@ -705,12 +736,9 @@ ENDIF() # we somehow have to make LMMS-binary depend on MOC-files ADD_FILE_DEPENDENCIES("${CMAKE_BINARY_DIR}/lmmsconfig.h") -IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - IF(WIN32) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes") - ELSE(WIN32) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DPIC") - ENDIF(WIN32) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND NOT WIN32) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -DPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DPIC") elseif(MSVC) # Use UTF-8 as the source and execution character set add_compile_options("/utf-8") diff --git a/cmake/modules/StaticDependencies.cmake b/cmake/modules/StaticDependencies.cmake new file mode 100644 index 000000000..d12c47d12 --- /dev/null +++ b/cmake/modules/StaticDependencies.cmake @@ -0,0 +1,141 @@ +# StaticDependencies.cmake - adds features similar to interface properties that +# are only transitive over static dependencies. +# +# Copyright (c) 2024 Dominic Clark +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +define_property(TARGET + PROPERTY STATIC_COMPILE_DEFINITIONS + BRIEF_DOCS "Compile definitions to be used by targets linking statically to this one" + FULL_DOCS "Behaves similarly to INTERFACE_COMPILE_DEFINITIONS, but only over static dependencies." + "Effectively becomes private once an executable module is reached." +) + +define_property(TARGET + PROPERTY STATIC_LINK_LIBRARIES + BRIEF_DOCS "Link libraries to be included in targets linking statically to this one" + FULL_DOCS "Behaves similarly to INTERFACE_LINK_LIBRARIES, but only over static dependencies." + "Effectively becomes private once an executable module is reached." +) + +# Link a target statically to a set of libraries. Forward the given arguments to +# `target_link_libraries`, but also perform two additional functions. Firstly, +# ensure that the given libraries will be linked into any module that also +# links the given target (allowing, for example, object libraries and private +# static libraries to be used transitively). Secondly, add any static compile +# definitions from the given libraries to the set of compile definitions used +# to build the given target. +# +# This function must be used in order for static requirements as defined in this +# module to be inherited transitively. Using `target_link_libraries` instead +# will break the chain for static link libraries and static compile definitions. +# +# Usage: +# target_static_libraries( +# # The target to which to add the libraries +# [] # Optionally, the scope to use for the following libraries +# ... # The libraries to which to link +# [ ...]... +# ) +function(target_static_libraries target) + # Target types that have a link step + set(linked_target_types "MODULE_LIBRARY" "SHARED_LIBRARY" "EXECUTABLE") + # Possible scopes for dependencies + set(scopes "PRIVATE" "PUBLIC" "INTERFACE") + + get_target_property(target_type "${target}" TYPE) + set(scope "") + + # Iterate over the dependencies (and possibly scopes) that we were given + foreach(dependency IN LISTS ARGN) + # If we have a scope, store it so we can apply it to upcoming libraries + if(dependency IN_LIST scopes) + set(scope "${dependency}") + continue() + endif() + + # Link the target to the current dependency. (Note: `${scope}` is + # unquoted so that the argument disappears if no scope was given.) + target_link_libraries("${target}" ${scope} "${dependency}") + + # Store the dependency so it can be linked in with this target later + set_property( + TARGET "${target}" + APPEND + PROPERTY STATIC_LINK_LIBRARIES + "${dependency}" + ) + + # If the dependency is a target, it may have some of our custom + # properties defined on it, so we have a bit more work to do + if(TARGET "${dependency}") + # Ensure it makes sense to link statically to this dependency + get_target_property(dependency_type "${dependency}" TYPE) + if(dependency_type IN_LIST linked_target_types) + message(SEND_ERROR "Cannot link statically to shared module ${dependency}") + endif() + + # Transitively include static definitions and libraries + set(defs "$>") + set(libs "$>") + set_property( + TARGET "${target}" + APPEND + PROPERTY STATIC_COMPILE_DEFINITIONS + "${defs}" + ) + set_property( + TARGET "${target}" + APPEND + PROPERTY STATIC_LINK_LIBRARIES + "${libs}" + ) + + # Add the dependency's transitive static compile definitions. + # (Note: definitions are private so dynamically linked dependents + # won't pick them up; a static dependent will have them set when + # this function is called for it.) + target_compile_definitions("${target}" PRIVATE "${defs}") + + # If the target has a link step, add the transitive static + # dependencies. (Note: we use `LINK_ONLY` so the caller can still + # control usage requirements through the normal use of scopes. Only + # transitive dependencies are needed here: the direct dependency was + # added earlier on. We have to append to `LINK_LIBRARIES` directly, + # rather than use `target_link_libraries(PRIVATE)`, in order to + # remain compatible with the scopeless signature of that command.) + if(target_type IN_LIST linked_target_types) + set_property( + TARGET "${target}" + APPEND + PROPERTY LINK_LIBRARIES + "$" + ) + endif() + endif() + endforeach() +endfunction() + +# Add compile definitions to a target only for use with dependents linking +# statically to it. +# +# Behaves like `target_compile_definitions(INTERFACE)`, except the definitions +# will not be inherited beyond any executable module into which the target is +# actually linked. The definitions are added to the `STATIC_COMPILE_DEFINITIONS` +# property on the target. +# +# Usage: +# target_static_definitions( +# # The target to which to add the definitions +# ... # The definitions to add to the target +# ) +function(target_static_definitions target) + set_property( + TARGET "${target}" + APPEND + PROPERTY STATIC_COMPILE_DEFINITIONS + "${ARGN}" + ) +endfunction() diff --git a/include/AudioJack.h b/include/AudioJack.h index 01f41f092..a1f9b777b 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -31,7 +31,7 @@ #ifndef LMMS_HAVE_WEAKJACK #include #else -#include "weak_libjack.h" +#include #endif #include diff --git a/include/LocklessRingBuffer.h b/include/LocklessRingBuffer.h index 2d65badfe..ec3f4fc52 100644 --- a/include/LocklessRingBuffer.h +++ b/include/LocklessRingBuffer.h @@ -28,9 +28,9 @@ #include #include -#include "lmms_basics.h" -#include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h" +#include +#include "lmms_basics.h" namespace lmms { diff --git a/include/Lv2Proc.h b/include/Lv2Proc.h index 65bd90698..36b0fa600 100644 --- a/include/Lv2Proc.h +++ b/include/Lv2Proc.h @@ -33,6 +33,8 @@ #include #include +#include + #include "LinkedModelGroups.h" #include "LmmsSemaphore.h" #include "Lv2Basics.h" @@ -40,7 +42,6 @@ #include "Lv2Options.h" #include "Lv2Worker.h" #include "Plugin.h" -#include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h" #include "TimePos.h" diff --git a/include/MidiJack.h b/include/MidiJack.h index e2b38e290..e61db26dd 100644 --- a/include/MidiJack.h +++ b/include/MidiJack.h @@ -32,7 +32,7 @@ #include #include #else -#include "weak_libjack.h" +#include #endif #include diff --git a/plugins/CarlaBase/CMakeLists.txt b/plugins/CarlaBase/CMakeLists.txt index 8f9e14dd1..6533055a4 100644 --- a/plugins/CarlaBase/CMakeLists.txt +++ b/plugins/CarlaBase/CMakeLists.txt @@ -15,7 +15,7 @@ if(LMMS_HAVE_WEAKCARLA) SET(CARLA_NATIVE_LIB carla_native-plugin) ADD_LIBRARY(${CARLA_NATIVE_LIB} SHARED DummyCarla.cpp) - TARGET_INCLUDE_DIRECTORIES(${CARLA_NATIVE_LIB} PUBLIC ${CARLA_INCLUDE_DIRS}) + target_include_directories(${CARLA_NATIVE_LIB} SYSTEM PUBLIC ${CARLA_INCLUDE_DIRS}) INSTALL(TARGETS ${CARLA_NATIVE_LIB} LIBRARY DESTINATION "${PLUGIN_DIR}/optional" RUNTIME DESTINATION "${PLUGIN_DIR}/optional" @@ -31,7 +31,7 @@ if(LMMS_HAVE_CARLA OR LMMS_HAVE_WEAKCARLA) SET(CARLA_INCLUDE_DIRS ${CARLA_INCLUDE_DIRS} PARENT_SCOPE) INCLUDE(BuildPlugin) - INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS}) + include_directories(SYSTEM ${CARLA_INCLUDE_DIRS}) LINK_DIRECTORIES(${CARLA_LIBRARY_DIRS}) LINK_LIBRARIES(${CARLA_LIBRARIES}) BUILD_PLUGIN(carlabase Carla.cpp Carla.h diff --git a/plugins/CarlaBase/Carla.h b/plugins/CarlaBase/Carla.h index 76a9b45b7..c1190e5e7 100644 --- a/plugins/CarlaBase/Carla.h +++ b/plugins/CarlaBase/Carla.h @@ -37,13 +37,13 @@ // carla/source/includes #include "carlabase_export.h" -#include "CarlaDefines.h" +#include #if CARLA_VERSION_HEX >= 0x010911 - #include "CarlaNativePlugin.h" + #include #else - #include "CarlaBackend.h" - #include "CarlaNative.h" - #include "CarlaUtils.h" + #include + #include + #include CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay_plugin(); diff --git a/plugins/CarlaBase/DummyCarla.cpp b/plugins/CarlaBase/DummyCarla.cpp index 572bdf4bc..9a5a13761 100644 --- a/plugins/CarlaBase/DummyCarla.cpp +++ b/plugins/CarlaBase/DummyCarla.cpp @@ -1,6 +1,6 @@ // A dummy Carla interface #define BUILDING_CARLA -#include "CarlaNativePlugin.h" +#include #ifndef CARLA_PLUGIN_EXPORT #define CARLA_PLUGIN_EXPORT CARLA_EXPORT diff --git a/plugins/CarlaPatchbay/CMakeLists.txt b/plugins/CarlaPatchbay/CMakeLists.txt index 457e61e6a..8f6efd5ea 100644 --- a/plugins/CarlaPatchbay/CMakeLists.txt +++ b/plugins/CarlaPatchbay/CMakeLists.txt @@ -1,7 +1,8 @@ if(LMMS_HAVE_CARLA OR LMMS_HAVE_WEAKCARLA) ADD_DEFINITIONS(-DCARLA_PLUGIN_PATCHBAY -DCARLA_PLUGIN_SYNTH) INCLUDE(BuildPlugin) - INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/../CarlaBase") + include_directories(SYSTEM ${CARLA_INCLUDE_DIRS}) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../CarlaBase") LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/../CarlaBase" ${CARLA_LIBRARY_DIRS}) LINK_LIBRARIES(carlabase) diff --git a/plugins/CarlaRack/CMakeLists.txt b/plugins/CarlaRack/CMakeLists.txt index 8373688c1..d53285624 100644 --- a/plugins/CarlaRack/CMakeLists.txt +++ b/plugins/CarlaRack/CMakeLists.txt @@ -1,7 +1,8 @@ if(LMMS_HAVE_CARLA OR LMMS_HAVE_WEAKCARLA) ADD_DEFINITIONS(-DCARLA_PLUGIN_RACK -DCARLA_PLUGIN_SYNTH) INCLUDE(BuildPlugin) - INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/../CarlaBase") + include_directories(SYSTEM ${CARLA_INCLUDE_DIRS}) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../CarlaBase") LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/../CarlaBase" ${CARLA_LIBRARY_DIRS}) LINK_LIBRARIES(carlabase) diff --git a/plugins/Eq/CMakeLists.txt b/plugins/Eq/CMakeLists.txt index 899dde5ec..68edb034b 100644 --- a/plugins/Eq/CMakeLists.txt +++ b/plugins/Eq/CMakeLists.txt @@ -1,5 +1,5 @@ INCLUDE(BuildPlugin) -INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) +include_directories(SYSTEM ${FFTW3F_INCLUDE_DIRS}) LINK_LIBRARIES(${FFTW3F_LIBRARIES}) BUILD_PLUGIN(eq EqEffect.cpp EqCurve.cpp EqCurve.h EqControls.cpp EqControlsDialog.cpp EqFilter.h EqParameterWidget.cpp EqFader.h EqSpectrumView.h EqSpectrumView.cpp MOCFILES EqControls.h EqControlsDialog.h EqCurve.h EqParameterWidget.h EqFader.h EqSpectrumView.h EMBEDDED_RESOURCES *.png) diff --git a/plugins/FreeBoy/CMakeLists.txt b/plugins/FreeBoy/CMakeLists.txt index 485ed3cc2..a08dfa439 100644 --- a/plugins/FreeBoy/CMakeLists.txt +++ b/plugins/FreeBoy/CMakeLists.txt @@ -1,21 +1,20 @@ -INCLUDE(BuildPlugin) -INCLUDE_DIRECTORIES(game-music-emu/gme) +include(BuildPlugin) -BUILD_PLUGIN(freeboy +add_library(gme STATIC + game-music-emu/gme/Gb_Apu.cpp + game-music-emu/gme/Gb_Oscs.cpp + game-music-emu/gme/Blip_Buffer.cpp + game-music-emu/gme/Multi_Buffer.cpp +) +target_include_directories(gme PUBLIC game-music-emu/gme) +set_target_properties(gme PROPERTIES SYSTEM TRUE) + +build_plugin(freeboy FreeBoy.cpp FreeBoy.h GbApuWrapper.cpp GbApuWrapper.h - game-music-emu/gme/Gb_Apu.cpp - game-music-emu/gme/Gb_Apu.h - game-music-emu/gme/Gb_Oscs.cpp - game-music-emu/gme/Blip_Buffer.cpp - game-music-emu/gme/Gb_Oscs.h - game-music-emu/gme/blargg_common.h - game-music-emu/gme/Blip_Buffer.h - game-music-emu/gme/Multi_Buffer.cpp - game-music-emu/gme/blargg_source.h - game-music-emu/gme/Multi_Buffer.h MOCFILES FreeBoy.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png" ) +target_link_libraries(freeboy gme) diff --git a/plugins/FreeBoy/FreeBoy.h b/plugins/FreeBoy/FreeBoy.h index 501377715..bba00efbf 100644 --- a/plugins/FreeBoy/FreeBoy.h +++ b/plugins/FreeBoy/FreeBoy.h @@ -26,8 +26,9 @@ #ifndef LMMS_FREEBOY_H #define LMMS_FREEBOY_H +#include + #include "AutomatableModel.h" -#include "Blip_Buffer.h" #include "Instrument.h" #include "InstrumentView.h" #include "Graph.h" diff --git a/plugins/FreeBoy/GbApuWrapper.h b/plugins/FreeBoy/GbApuWrapper.h index 3b95869d5..88dc82610 100644 --- a/plugins/FreeBoy/GbApuWrapper.h +++ b/plugins/FreeBoy/GbApuWrapper.h @@ -24,8 +24,8 @@ #ifndef LMMS_GB_APU_WRAPPER_H #define LMMS_GB_APU_WRAPPER_H -#include "Gb_Apu.h" -#include "Multi_Buffer.h" +#include +#include namespace lmms { diff --git a/plugins/GigPlayer/CMakeLists.txt b/plugins/GigPlayer/CMakeLists.txt index 92c80fedc..69ac1b80c 100644 --- a/plugins/GigPlayer/CMakeLists.txt +++ b/plugins/GigPlayer/CMakeLists.txt @@ -1,6 +1,6 @@ if(LMMS_HAVE_GIG) INCLUDE(BuildPlugin) - INCLUDE_DIRECTORIES(${GIG_INCLUDE_DIRS}) + include_directories(SYSTEM ${GIG_INCLUDE_DIRS}) SET(CMAKE_AUTOUIC ON) # Required for not crashing loading files with libgig diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 038fa6afb..23f93da7a 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -1,6 +1,8 @@ # Note: # The last version of Calf that was LADSPA-capable is version 0.0.18.2 +set_directory_properties(PROPERTIES SYSTEM TRUE) + # Parse version info from autoconf FILE(READ veal/configure.ac VERSION_FILE) STRING(REPLACE "[" ";" VERSION_FILE ${VERSION_FILE} ) @@ -35,16 +37,12 @@ SET_TARGET_PROPERTIES(veal PROPERTIES PREFIX "") TARGET_COMPILE_DEFINITIONS(veal PRIVATE DISABLE_OSC=1) SET(INLINE_FLAGS "") -SET(OTHER_FLAGS "") IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") SET(INLINE_FLAGS -finline-functions-called-once -finline-limit=80) - SET(OTHER_FLAGS -Wno-format-overflow) ENDIF() -if(MSVC) - target_compile_options(veal PRIVATE /wd4099 /wd4244 /wd4305) -else() - target_compile_options(veal PRIVATE -fexceptions -O2 -finline-functions ${INLINE_FLAGS} ${OTHER_FLAGS}) +if(NOT MSVC) + target_compile_options(veal PRIVATE -fexceptions -O2 -finline-functions ${INLINE_FLAGS}) endif() if(MSVC) diff --git a/plugins/LadspaEffect/caps/CMakeLists.txt b/plugins/LadspaEffect/caps/CMakeLists.txt index ea2c1b7e9..379413ae4 100644 --- a/plugins/LadspaEffect/caps/CMakeLists.txt +++ b/plugins/LadspaEffect/caps/CMakeLists.txt @@ -1,3 +1,5 @@ +set_directory_properties(PROPERTIES SYSTEM TRUE) + INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") FILE(GLOB SOURCES *.cc) LIST(SORT SOURCES) @@ -8,10 +10,8 @@ ADD_DEFINITIONS(-DLMMS_BUILD_WIN64) ENDIF(LMMS_BUILD_WIN64) SET_TARGET_PROPERTIES(caps PROPERTIES PREFIX "") -if(MSVC) - target_compile_options(caps PRIVATE /wd4244 /wd4305) -else() - target_compile_options(caps PRIVATE -O2 -funroll-loops -Wno-write-strings) +if(NOT MSVC) + target_compile_options(caps PRIVATE -O2 -funroll-loops) endif() if(MSVC) diff --git a/plugins/LadspaEffect/cmt/CMakeLists.txt b/plugins/LadspaEffect/cmt/CMakeLists.txt index 65430d109..dbc3c9de6 100644 --- a/plugins/LadspaEffect/cmt/CMakeLists.txt +++ b/plugins/LadspaEffect/cmt/CMakeLists.txt @@ -1,3 +1,5 @@ +set_directory_properties(PROPERTIES SYSTEM TRUE) + INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") FILE(GLOB_RECURSE SOURCES cmt/src/*.cpp) LIST(SORT SOURCES) @@ -6,10 +8,8 @@ INSTALL(TARGETS cmt LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") SET_TARGET_PROPERTIES(cmt PROPERTIES PREFIX "") -if(MSVC) - target_compile_options(cmt PRIVATE /wd4244 /wd4305) -else() - target_compile_options(cmt PRIVATE -Wall -O3 -fno-strict-aliasing) +if(NOT MSVC) + target_compile_options(cmt PRIVATE -O3 -fno-strict-aliasing) endif() if(LMMS_BUILD_WIN32) diff --git a/plugins/LadspaEffect/swh/CMakeLists.txt b/plugins/LadspaEffect/swh/CMakeLists.txt index c71572bd2..203c3168f 100644 --- a/plugins/LadspaEffect/swh/CMakeLists.txt +++ b/plugins/LadspaEffect/swh/CMakeLists.txt @@ -1,3 +1,5 @@ +set_directory_properties(PROPERTIES SYSTEM TRUE) + # Create blank config.h FILE(WRITE ladspa/config.h "") @@ -9,10 +11,8 @@ ELSE() ENDIF() # Additional compile flags -if(MSVC) - set(COMPILE_FLAGS ${COMPILE_FLAGS} /wd4244 /wd4273 /wd4305) -else() - set(COMPILE_FLAGS ${COMPILE_FLAGS} -O3 -Wall -c +if(NOT MSVC) + set(COMPILE_FLAGS ${COMPILE_FLAGS} -O3 -c -fomit-frame-pointer -funroll-loops -ffast-math -fno-strict-aliasing ${PIC_FLAGS} ) diff --git a/plugins/LadspaEffect/tap/CMakeLists.txt b/plugins/LadspaEffect/tap/CMakeLists.txt index b895c7531..84c469465 100644 --- a/plugins/LadspaEffect/tap/CMakeLists.txt +++ b/plugins/LadspaEffect/tap/CMakeLists.txt @@ -1,10 +1,12 @@ +set_directory_properties(PROPERTIES SYSTEM TRUE) + INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") FILE(GLOB PLUGIN_SOURCES tap-plugins/*.c) LIST(SORT PLUGIN_SOURCES) if(MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244 /fp:fast") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fp:fast") else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wno-write-strings -fomit-frame-pointer -fno-strict-aliasing -funroll-loops -ffast-math") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fomit-frame-pointer -fno-strict-aliasing -funroll-loops -ffast-math") endif() FOREACH(_item ${PLUGIN_SOURCES}) GET_FILENAME_COMPONENT(_plugin "${_item}" NAME_WE) diff --git a/plugins/Lv2Effect/CMakeLists.txt b/plugins/Lv2Effect/CMakeLists.txt index 915751797..e0427eaa3 100644 --- a/plugins/Lv2Effect/CMakeLists.txt +++ b/plugins/Lv2Effect/CMakeLists.txt @@ -1,7 +1,7 @@ IF(LMMS_HAVE_LV2) - INCLUDE_DIRECTORIES(${LV2_INCLUDE_DIRS}) - INCLUDE_DIRECTORIES(${LILV_INCLUDE_DIRS}) - INCLUDE_DIRECTORIES(${SUIL_INCLUDE_DIRS}) + include_directories(SYSTEM ${LV2_INCLUDE_DIRS}) + include_directories(SYSTEM ${LILV_INCLUDE_DIRS}) + include_directories(SYSTEM ${SUIL_INCLUDE_DIRS}) INCLUDE(BuildPlugin) BUILD_PLUGIN(lv2effect Lv2Effect.cpp Lv2FxControls.cpp Lv2FxControlDialog.cpp Lv2Effect.h Lv2FxControls.h Lv2FxControlDialog.h MOCFILES Lv2Effect.h Lv2FxControls.h Lv2FxControlDialog.h diff --git a/plugins/Lv2Instrument/CMakeLists.txt b/plugins/Lv2Instrument/CMakeLists.txt index 290bd84e8..e10eff692 100644 --- a/plugins/Lv2Instrument/CMakeLists.txt +++ b/plugins/Lv2Instrument/CMakeLists.txt @@ -1,7 +1,7 @@ IF(LMMS_HAVE_LV2) - INCLUDE_DIRECTORIES(${LV2_INCLUDE_DIRS}) - INCLUDE_DIRECTORIES(${LILV_INCLUDE_DIRS}) - INCLUDE_DIRECTORIES(${SUIL_INCLUDE_DIRS}) + include_directories(SYSTEM ${LV2_INCLUDE_DIRS}) + include_directories(SYSTEM ${LILV_INCLUDE_DIRS}) + include_directories(SYSTEM ${SUIL_INCLUDE_DIRS}) INCLUDE(BuildPlugin) BUILD_PLUGIN(lv2instrument Lv2Instrument.cpp Lv2Instrument.h MOCFILES Lv2Instrument.h EMBEDDED_RESOURCES logo.png) ENDIF(LMMS_HAVE_LV2) diff --git a/plugins/OpulenZ/CMakeLists.txt b/plugins/OpulenZ/CMakeLists.txt index 58f661406..fcfce7819 100644 --- a/plugins/OpulenZ/CMakeLists.txt +++ b/plugins/OpulenZ/CMakeLists.txt @@ -1,20 +1,16 @@ -INCLUDE(BuildPlugin) +include(BuildPlugin) -# Avoid unused warnings for mididata.h -IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-variable") -ENDIF() +add_library(adplug STATIC + adplug/src/fmopl.c + adplug/src/temuopl.cpp +) +target_include_directories(adplug PUBLIC adplug/src) +set_target_properties(adplug PROPERTIES SYSTEM TRUE) -INCLUDE_DIRECTORIES(adplug/src) - -BUILD_PLUGIN(opulenz +build_plugin(opulenz OpulenZ.cpp OpulenZ.h - adplug/src/opl.h - adplug/src/fmopl.c - adplug/src/fmopl.h - adplug/src/temuopl.cpp - adplug/src/temuopl.h MOCFILES OpulenZ.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png" ) +target_link_libraries(opulenz adplug) diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index 260ba353d..607d40883 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -46,9 +46,9 @@ #include #include -#include "opl.h" -#include "temuopl.h" -#include "mididata.h" +#include +#include +#include #include "embed.h" #include "debug.h" diff --git a/plugins/Sid/SidInstrument.cpp b/plugins/Sid/SidInstrument.cpp index b745075aa..0048092ae 100644 --- a/plugins/Sid/SidInstrument.cpp +++ b/plugins/Sid/SidInstrument.cpp @@ -29,7 +29,7 @@ #include #include -#include "sid.h" +#include #include "SidInstrument.h" #include "AudioEngine.h" diff --git a/plugins/Sid/resid/CMakeLists.txt b/plugins/Sid/resid/CMakeLists.txt index bb39e3d16..e882679a8 100644 --- a/plugins/Sid/resid/CMakeLists.txt +++ b/plugins/Sid/resid/CMakeLists.txt @@ -1,3 +1,5 @@ +set_directory_properties(PROPERTIES SYSTEM TRUE) + # These are the defaults set(RESID_INLINING 1) set(RESID_INLINE inline) diff --git a/plugins/SlicerT/CMakeLists.txt b/plugins/SlicerT/CMakeLists.txt index 49a80ca03..fa7ce3c11 100644 --- a/plugins/SlicerT/CMakeLists.txt +++ b/plugins/SlicerT/CMakeLists.txt @@ -1,10 +1,16 @@ -INCLUDE(BuildPlugin) +include(BuildPlugin) -INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) -LINK_LIBRARIES(${FFTW3F_LIBRARIES}) +include_directories(SYSTEM ${FFTW3F_INCLUDE_DIRS}) +link_libraries(${FFTW3F_LIBRARIES}) -INCLUDE_DIRECTORIES(${SAMPLERATE_INCLUDE_DIRS}) -LINK_DIRECTORIES(${SAMPLERATE_LIBRARY_DIRS}) -LINK_LIBRARIES(${SAMPLERATE_LIBRARIES}) - -BUILD_PLUGIN(slicert SlicerT.cpp SlicerT.h SlicerTView.cpp SlicerTView.h SlicerTWaveform.cpp SlicerTWaveform.h MOCFILES SlicerT.h SlicerTView.h SlicerTWaveform.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png") \ No newline at end of file +build_plugin(slicert + SlicerT.cpp + SlicerT.h + SlicerTView.cpp + SlicerTView.h + SlicerTWaveform.cpp + SlicerTWaveform.h + MOCFILES SlicerT.h SlicerTView.h SlicerTWaveform.h + EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png" +) +target_link_libraries(slicert SampleRate::samplerate) diff --git a/plugins/SpectrumAnalyzer/CMakeLists.txt b/plugins/SpectrumAnalyzer/CMakeLists.txt index 488495a9e..4b3d2ed69 100644 --- a/plugins/SpectrumAnalyzer/CMakeLists.txt +++ b/plugins/SpectrumAnalyzer/CMakeLists.txt @@ -1,5 +1,5 @@ INCLUDE(BuildPlugin) -INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) +include_directories(SYSTEM ${FFTW3F_INCLUDE_DIRS}) LINK_LIBRARIES(${FFTW3F_LIBRARIES}) diff --git a/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt b/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt index 5bcf9f065..a3cd517ff 100644 --- a/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt @@ -76,7 +76,7 @@ if(IS_MINGW) " HAS_STD_MUTEX) if(NOT HAS_STD_MUTEX) - target_include_directories(${EXE_NAME} PRIVATE + target_include_directories(${EXE_NAME} SYSTEM PRIVATE "${LMMS_SOURCE_DIR}/src/3rdparty/mingw-std-threads") target_compile_definitions(${EXE_NAME} PRIVATE -DUSE_MINGW_THREADS_REPLACEMENT) diff --git a/plugins/VstBase/VstPlugin.cpp b/plugins/VstBase/VstPlugin.cpp index 0361d4c25..5dbe7a698 100644 --- a/plugins/VstBase/VstPlugin.cpp +++ b/plugins/VstBase/VstPlugin.cpp @@ -36,7 +36,7 @@ #ifdef LMMS_BUILD_LINUX # include -# include "X11EmbedContainer.h" +# include #endif #include diff --git a/plugins/Xpressive/CMakeLists.txt b/plugins/Xpressive/CMakeLists.txt index 366381e62..f5f1e7161 100644 --- a/plugins/Xpressive/CMakeLists.txt +++ b/plugins/Xpressive/CMakeLists.txt @@ -1,6 +1,5 @@ INCLUDE(BuildPlugin) -INCLUDE_DIRECTORIES(exprtk) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_sc_andor") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_return_statement") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_break_continue") @@ -8,7 +7,7 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_comments") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_string_capabilities") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_rtl_io_file") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dexprtk_disable_rtl_vecops") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WERROR_FLAGS} -fexceptions") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions") IF(LMMS_BUILD_WIN32 AND NOT MSVC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -Dexprtk_disable_enhanced_features") @@ -16,13 +15,16 @@ ELSEIF(LMMS_BUILD_WIN32 AND MSVC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") ENDIF() -BUILD_PLUGIN(xpressive +add_library(exprtk INTERFACE) +target_include_directories(exprtk INTERFACE exprtk) +set_target_properties(exprtk PROPERTIES SYSTEM TRUE) + +build_plugin(xpressive Xpressive.cpp ExprSynth.cpp Xpressive.h - exprtk/exprtk.hpp + ExprSynth.h MOCFILES Xpressive.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png" ) - - +target_link_libraries(xpressive exprtk) diff --git a/plugins/Xpressive/ExprSynth.cpp b/plugins/Xpressive/ExprSynth.cpp index 736b47598..0dde9ff96 100644 --- a/plugins/Xpressive/ExprSynth.cpp +++ b/plugins/Xpressive/ExprSynth.cpp @@ -36,7 +36,7 @@ #include "NotePlayHandle.h" -#include "exprtk.hpp" +#include #define WARN_EXPRTK qWarning("ExprTk exception") @@ -820,4 +820,4 @@ void ExprSynth::renderOutput(fpp_t frames, sampleFrame *buf) } -} // namespace lmms \ No newline at end of file +} // namespace lmms diff --git a/plugins/ZynAddSubFx/CMakeLists.txt b/plugins/ZynAddSubFx/CMakeLists.txt index 0f6af20ee..a0eb6f36a 100644 --- a/plugins/ZynAddSubFx/CMakeLists.txt +++ b/plugins/ZynAddSubFx/CMakeLists.txt @@ -12,7 +12,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # definitions for ZynAddSubFX IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD) FIND_PACKAGE(X11) - INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR}) + include_directories(SYSTEM ${X11_INCLUDE_DIR}) ADD_DEFINITIONS(-DOS_LINUX) ELSE() ADD_DEFINITIONS(-DOS_WINDOWS) @@ -44,21 +44,21 @@ IF(NOT EXISTS ${FLTK_FLUID_EXECUTABLE}) ENDIF() ENDIF() -include_directories( +include_directories(SYSTEM "${FLTK_INCLUDE_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}" ${FFTW3F_INCLUDE_DIRS} +) +include_directories( + "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_BINARY_DIR}" - "${CMAKE_SOURCE_DIR}/src/3rdparty/mingw-std-threads" - "${CMAKE_CURRENT_SOURCE_DIR}/zynaddsubfx/src/UI" ) ADD_DEFINITIONS(-DPLUGINVERSION) # removes exit confirmation dialogs etc. in MasterUI.fl add_subdirectory(zynaddsubfx/src/Nio) add_subdirectory(zynaddsubfx/src/UI) -SET(zynaddsubfx_core_SRCS +add_library(zynaddsubfx_synth OBJECT zynaddsubfx/src/DSP/AnalogFilter.cpp zynaddsubfx/src/DSP/FFTwrapper.cpp zynaddsubfx/src/DSP/Filter.cpp @@ -107,13 +107,32 @@ SET(zynaddsubfx_core_SRCS zynaddsubfx/src/Synth/SUBnote.cpp ) -add_library(ZynAddSubFxCoreObjs OBJECT LocalZynAddSubFx.cpp ${zynaddsubfx_core_SRCS}) -add_library(ZynAddSubFxCore INTERFACE) -target_sources(ZynAddSubFxCore INTERFACE - $ - $ -) +set_target_properties(zynaddsubfx_nio PROPERTIES SYSTEM TRUE) +set_target_properties(zynaddsubfx_gui PROPERTIES SYSTEM TRUE) +set_target_properties(zynaddsubfx_synth PROPERTIES SYSTEM TRUE) +if(MINGW) + target_link_libraries(zynaddsubfx_nio PUBLIC mingw_stdthreads) + target_link_libraries(zynaddsubfx_gui PUBLIC mingw_stdthreads) + target_link_libraries(zynaddsubfx_synth PUBLIC mingw_stdthreads) +endif() + +# Relative include paths don't work automatically for the GUI, because the +# generated C++ files aren't in the source directory. Thus, add the expected +# source directory as an additional include directory. +target_include_directories(zynaddsubfx_gui PUBLIC zynaddsubfx/src/UI) + +add_library(ZynAddSubFxCore STATIC + LocalZynAddSubFx.cpp +) +target_include_directories(ZynAddSubFxCore SYSTEM PUBLIC + zynaddsubfx/src + "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfx/src" +) +target_static_libraries(ZynAddSubFxCore PUBLIC + zynaddsubfx_nio + zynaddsubfx_synth +) target_link_libraries(ZynAddSubFxCore INTERFACE ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} @@ -132,7 +151,7 @@ ELSE() SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PLUGIN_DIR}") ENDIF() BUILD_PLUGIN(zynaddsubfx ZynAddSubFx.cpp ZynAddSubFx.h MOCFILES ZynAddSubFx.h EMBEDDED_RESOURCES artwork.png logo.png) -target_link_libraries(zynaddsubfx ZynAddSubFxCore) +target_static_libraries(zynaddsubfx ZynAddSubFxCore) if(MSVC) set(WINRC "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfx.rc") @@ -155,8 +174,8 @@ add_executable(RemoteZynAddSubFx RemoteZynAddSubFx.cpp ${LMMS_COMMON_SRCS} "${WINRC}" - $ ) +target_static_libraries(RemoteZynAddSubFx ZynAddSubFxCore zynaddsubfx_gui) INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION "${PLUGIN_DIR}") # Needed to deploy dependencies of RemoteZynAddSubFx SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT "RemoteZynAddSubFx") @@ -176,7 +195,7 @@ IF(FLTK_CONFIG AND NOT (LMMS_BUILD_APPLE OR LMMS_BUILD_WIN32)) STRING(REPLACE " " ";" FLTK_FILTERED_LDFLAGS ${FLTK_FILTERED_LDFLAGS}) LIST(REMOVE_ITEM FLTK_FILTERED_LDFLAGS -lX11) ENDIF() -target_link_libraries(RemoteZynAddSubFx ZynAddSubFxCore ${FLTK_FILTERED_LDFLAGS}) +target_link_libraries(RemoteZynAddSubFx ${FLTK_FILTERED_LDFLAGS}) if(LMMS_HAVE_LIBRT) target_link_libraries(RemoteZynAddSubFx rt) diff --git a/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp b/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp index 83ef3e9a2..a98cfa1e1 100644 --- a/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp @@ -37,10 +37,10 @@ #include "MidiEvent.h" -#include "zynaddsubfx/src/Nio/NulEngine.h" -#include "zynaddsubfx/src/Misc/Master.h" -#include "zynaddsubfx/src/Misc/Part.h" -#include "zynaddsubfx/src/Misc/Util.h" +#include +#include +#include +#include // Global variable in zynaddsubfx/src/globals.h SYNTH_T* synth = nullptr; diff --git a/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp b/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp index c4d6b71a1..104be5cac 100644 --- a/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp @@ -37,8 +37,8 @@ #include "RemotePluginClient.h" #include "LocalZynAddSubFx.h" -#include "zynaddsubfx/src/Nio/Nio.h" -#include "zynaddsubfx/src/UI/MasterUI.h" +#include +#include using namespace lmms; diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.h b/plugins/ZynAddSubFx/ZynAddSubFx.h index b4f7c434c..2b30c6a3e 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.h +++ b/plugins/ZynAddSubFx/ZynAddSubFx.h @@ -28,12 +28,12 @@ #include #include +#include + #include "AutomatableModel.h" #include "Instrument.h" #include "InstrumentView.h" #include "RemotePlugin.h" -#include "zynaddsubfx/src/globals.h" - class QPushButton; diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 3339eb926..4467cd075 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,8 +1,13 @@ +set_directory_properties(PROPERTIES SYSTEM TRUE) + if(LMMS_BUILD_LINUX AND LMMS_HAVE_VST) set(BUILD_SHARED_LIBS OFF) add_subdirectory(qt5-x11embed) ENDIF() +add_library(jack_headers INTERFACE) +target_include_directories(jack_headers INTERFACE jack2/common) + ADD_SUBDIRECTORY(hiir) ADD_SUBDIRECTORY(weakjack) @@ -12,13 +17,22 @@ if(MINGW) set(LMMS_USE_MINGW_STD_THREADS ON PARENT_SCOPE) endif() -# The lockless ring buffer library is compiled as part of the core -SET(RINGBUFFER_DIR "${CMAKE_SOURCE_DIR}/src/3rdparty/ringbuffer/") -SET(RINGBUFFER_DIR ${RINGBUFFER_DIR} PARENT_SCOPE) +# The lockless ring buffer library is linked as part of the core +add_library(ringbuffer OBJECT + ringbuffer/src/lib/ringbuffer.cpp +) +target_compile_features(ringbuffer PUBLIC cxx_std_17) +target_include_directories(ringbuffer PUBLIC + ringbuffer/include + "${CMAKE_CURRENT_BINARY_DIR}" +) # Create a dummy ringbuffer_export.h, since ringbuffer is not compiled as a library -FILE(WRITE ${CMAKE_BINARY_DIR}/src/ringbuffer_export.h - "#include \"${CMAKE_BINARY_DIR}/src/lmms_export.h\"\n - #define RINGBUFFER_EXPORT LMMS_EXPORT") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ringbuffer_export.h.in" [[ + #include "${CMAKE_BINARY_DIR}/src/lmms_export.h" + #define RINGBUFFER_EXPORT LMMS_EXPORT +]]) +configure_file("${CMAKE_CURRENT_BINARY_DIR}/ringbuffer_export.h.in" ringbuffer_export.h) +target_compile_definitions(ringbuffer PRIVATE lmmsobjs_EXPORTS) # Enable MLOCK support for ringbuffer if available INCLUDE(CheckIncludeFiles) CHECK_INCLUDE_FILES(sys/mman.h HAVE_SYS_MMAN) @@ -28,5 +42,5 @@ ELSE() SET(USE_MLOCK OFF) ENDIF() # Generate ringbuffer configuration headers -CONFIGURE_FILE(${RINGBUFFER_DIR}/src/ringbuffer-config.h.in ${CMAKE_BINARY_DIR}/src/ringbuffer-config.h) -CONFIGURE_FILE(${RINGBUFFER_DIR}/src/ringbuffer-version.h.in ${CMAKE_BINARY_DIR}/src/ringbuffer-version.h) +configure_file(ringbuffer/src/ringbuffer-config.h.in ringbuffer-config.h) +configure_file(ringbuffer/src/ringbuffer-version.h.in ringbuffer-version.h) diff --git a/src/3rdparty/weakjack/CMakeLists.txt b/src/3rdparty/weakjack/CMakeLists.txt index 7600c3915..15c6d953e 100644 --- a/src/3rdparty/weakjack/CMakeLists.txt +++ b/src/3rdparty/weakjack/CMakeLists.txt @@ -1,12 +1,14 @@ # Use weak jack library linking -IF(LMMS_HAVE_WEAKJACK) - SET(CMAKE_C_FLAGS "-std=c11") - +if(LMMS_HAVE_WEAKJACK) + add_library(weakjack STATIC + weakjack/weak_libjack.c + ) + target_include_directories(weakjack PUBLIC weakjack) + target_link_libraries(weakjack PUBLIC jack_headers ${CMAKE_DL_LIBS}) + target_compile_features(weakjack PRIVATE c_std_11) # Enable weakjack, disable metadata support - ADD_DEFINITIONS(-DUSE_WEAK_JACK=1 -DNO_JACK_METADATA=1) - - # Library stub for AppImages running on systems without jack - ADD_LIBRARY(weakjack MODULE weakjack/weak_libjack.c weakjack/weak_libjack.h) - TARGET_INCLUDE_DIRECTORIES(weakjack PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/weakjack ${JACK_INCLUDE_DIRS}) - INSTALL(TARGETS weakjack LIBRARY DESTINATION "${PLUGIN_DIR}/optional") -ENDIF() + target_compile_definitions(weakjack PUBLIC + USE_WEAK_JACK=1 + NO_JACK_METADATA=1 + ) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 294ae1a07..940d485f9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,7 +29,6 @@ INCLUDE_DIRECTORIES( "${CMAKE_BINARY_DIR}/include" "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/include" - "${RINGBUFFER_DIR}/include" ) IF(WIN32 AND MSVC) @@ -55,39 +54,31 @@ ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc FILE(RELATIVE_PATH LIB_DIR_RELATIVE "/${BIN_DIR}" "/${LIB_DIR}") FILE(RELATIVE_PATH PLUGIN_DIR_RELATIVE "/${BIN_DIR}" "/${PLUGIN_DIR}") ADD_DEFINITIONS(-DLIB_DIR="${LIB_DIR_RELATIVE}" -DPLUGIN_DIR="${PLUGIN_DIR_RELATIVE}" ${PULSEAUDIO_DEFINITIONS}) -INCLUDE_DIRECTORIES( +include_directories(SYSTEM ${JACK_INCLUDE_DIRS} ${SNDIO_INCLUDE_DIRS} ${FFTW3F_INCLUDE_DIRS} ) IF(NOT LMMS_HAVE_SDL2 AND NOT ("${SDL_INCLUDE_DIR}" STREQUAL "")) - INCLUDE_DIRECTORIES("${SDL_INCLUDE_DIR}") -ENDIF() - -IF(LMMS_HAVE_WEAKJACK) - LIST(APPEND LMMS_SRCS "${WEAKJACK_INCLUDE_DIRS}/weak_libjack.c") - LIST(APPEND LMMS_INCLUDES "${WEAKJACK_INCLUDE_DIRS}/weak_libjack.h") - INCLUDE_DIRECTORIES("${WEAKJACK_INCLUDE_DIRS}") - ADD_DEFINITIONS(-DUSE_WEAK_JACK=1 -DNO_JACK_METADATA=1) + include_directories(SYSTEM "${SDL_INCLUDE_DIR}") ENDIF() IF(NOT ("${PULSEAUDIO_INCLUDE_DIR}" STREQUAL "")) - INCLUDE_DIRECTORIES("${PULSEAUDIO_INCLUDE_DIR}") + include_directories(SYSTEM "${PULSEAUDIO_INCLUDE_DIR}") ENDIF() IF(NOT ("${LV2_INCLUDE_DIRS}" STREQUAL "")) - INCLUDE_DIRECTORIES(${LV2_INCLUDE_DIRS}) + include_directories(SYSTEM ${LV2_INCLUDE_DIRS}) ENDIF() IF(NOT ("${LILV_INCLUDE_DIRS}" STREQUAL "")) - INCLUDE_DIRECTORIES(${LILV_INCLUDE_DIRS}) + include_directories(SYSTEM ${LILV_INCLUDE_DIRS}) ENDIF() IF(NOT ("${SUIL_INCLUDE_DIRS}" STREQUAL "")) - INCLUDE_DIRECTORIES(${SUIL_INCLUDE_DIRS}) + include_directories(SYSTEM ${SUIL_INCLUDE_DIRS}) ENDIF() -LIST(APPEND LMMS_SRCS "${RINGBUFFER_DIR}/src/lib/ringbuffer.cpp") # Use libraries in non-standard directories (e.g., another version of Qt) IF(LMMS_BUILD_LINUX) @@ -108,23 +99,20 @@ GENERATE_EXPORT_HEADER(lmmsobjs ADD_EXECUTABLE(lmms core/main.cpp - $ "${WINRC}" ) TARGET_INCLUDE_DIRECTORIES(lmms PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) +target_static_libraries(lmms PUBLIC lmmsobjs) # CMake doesn't define target_EXPORTS for OBJECT libraries. # See the documentation of DEFINE_SYMBOL for details. # Also add LMMS_STATIC_DEFINE for targets linking against it. TARGET_COMPILE_DEFINITIONS(lmmsobjs PRIVATE -Dlmmsobjs_EXPORTS - INTERFACE -DLMMS_STATIC_DEFINE -) -TARGET_COMPILE_DEFINITIONS(lmms - PRIVATE $ ) +target_static_definitions(lmmsobjs LMMS_STATIC_DEFINE) # Set Visual Studio startup project to lmms # https://stackoverflow.com/a/37994396/8166701 @@ -189,21 +177,10 @@ SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} ${EXTRA_LIBRARIES} ) -# Expose required libs for tests binary -SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} PARENT_SCOPE) - -TARGET_LINK_LIBRARIES(lmms +target_link_libraries(lmmsobjs ${LMMS_REQUIRED_LIBS} ) - -FOREACH(LIB ${LMMS_REQUIRED_LIBS}) - IF(TARGET ${LIB}) - GET_TARGET_PROPERTY(INCLUDE_DIRS ${LIB} INTERFACE_INCLUDE_DIRECTORIES) - IF(INCLUDE_DIRS) - TARGET_INCLUDE_DIRECTORIES(lmmsobjs PRIVATE ${INCLUDE_DIRS}) - ENDIF() - ENDIF() -ENDFOREACH() +target_static_libraries(lmmsobjs ringbuffer) set_target_properties(lmms PROPERTIES ENABLE_EXPORTS ON diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9a609922c..625601a3e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,18 +16,17 @@ foreach(LMMS_TEST_SRC IN LISTS LMMS_TESTS) # TODO CMake 3.20: Use cmake_path get_filename_component(LMMS_TEST_NAME ${LMMS_TEST_SRC} NAME_WE) - add_executable(${LMMS_TEST_NAME} $ ${LMMS_TEST_SRC}) + add_executable(${LMMS_TEST_NAME} ${LMMS_TEST_SRC}) add_test(NAME ${LMMS_TEST_NAME} COMMAND ${LMMS_TEST_NAME}) # TODO CMake 3.12: Propagate usage requirements by linking to lmmsobjs target_include_directories(${LMMS_TEST_NAME} PRIVATE $) + target_static_libraries("${LMMS_TEST_NAME}" PRIVATE lmmsobjs) target_link_libraries(${LMMS_TEST_NAME} PRIVATE - ${LMMS_REQUIRED_LIBS} ${QT_LIBRARIES} ${QT_QTTEST_LIBRARY} ) target_compile_features(${LMMS_TEST_NAME} PRIVATE cxx_std_17) - target_compile_definitions(${LMMS_TEST_NAME} PRIVATE $) endforeach() From e400d81eccce56b700a1b1434cd2d993019b801b Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 18 Jun 2024 12:21:07 +0300 Subject: [PATCH 11/31] set "child subreaper" process attribute on Linux (#7315) When launching the wine VST process various wrappers may be involved, when they exit the VST process becomes orphaned. This breaks the PollParentThread mechanism which is responsible for cleaning up processes in case of a crash. Because of this 64bit VST process exits prematurely, in other words 64bit VST is currently broken in a typical wine configuration. A solution suggested by Lukas W is to set the PR_SET_CHILD_SUBREAPER flag which makes the kernel reparent such process to lmms and PollParentThread then works as intended. Co-authored-by: Lukas W --- CMakeLists.txt | 1 + src/core/main.cpp | 13 +++++++++++++ src/lmmsconfig.h.in | 1 + 3 files changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6aa53d982..9da4fc243 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ CHECK_INCLUDE_FILES(sys/types.h LMMS_HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILES(sys/ipc.h LMMS_HAVE_SYS_IPC_H) CHECK_INCLUDE_FILES(sys/time.h LMMS_HAVE_SYS_TIME_H) CHECK_INCLUDE_FILES(sys/times.h LMMS_HAVE_SYS_TIMES_H) +CHECK_INCLUDE_FILES(sys/prctl.h LMMS_HAVE_SYS_PRCTL_H) CHECK_INCLUDE_FILES(sched.h LMMS_HAVE_SCHED_H) CHECK_INCLUDE_FILES(sys/soundcard.h LMMS_HAVE_SYS_SOUNDCARD_H) CHECK_INCLUDE_FILES(soundcard.h LMMS_HAVE_SOUNDCARD_H) diff --git a/src/core/main.cpp b/src/core/main.cpp index 650ceab57..b970997ef 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -55,6 +55,10 @@ #include #endif +#ifdef LMMS_HAVE_SYS_PRCTL_H +#include +#endif + #include #include "MainApplication.h" @@ -293,6 +297,15 @@ int main( int argc, char * * argv ) qInstallMessageHandler(consoleMessageHandler); #endif +#if defined(LMMS_HAVE_SYS_PRCTL_H) && defined(PR_SET_CHILD_SUBREAPER) + // Set the "child subreaper" attribute so that plugin child processes remain as lmms' + // children even when some wrapper process exits, as it may happen with wine + if (prctl(PR_SET_CHILD_SUBREAPER, 1)) + { + perror("prctl(PR_SET_CHILD_SUBREAPER)"); + } +#endif + // initialize memory managers NotePlayHandleManager::init(); diff --git a/src/lmmsconfig.h.in b/src/lmmsconfig.h.in index 89db21a7b..1510a36ec 100644 --- a/src/lmmsconfig.h.in +++ b/src/lmmsconfig.h.in @@ -45,6 +45,7 @@ #cmakedefine LMMS_HAVE_SEMAPHORE_H #cmakedefine LMMS_HAVE_SYS_TIME_H #cmakedefine LMMS_HAVE_SYS_TIMES_H +#cmakedefine LMMS_HAVE_SYS_PRCTL_H #cmakedefine LMMS_HAVE_SCHED_H #cmakedefine LMMS_HAVE_SYS_SOUNDCARD_H #cmakedefine LMMS_HAVE_SOUNDCARD_H From 39b7d16f15f20c429e264040547755afda7eac98 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Tue, 18 Jun 2024 21:56:19 +0100 Subject: [PATCH 12/31] Fix caching for macOS CI jobs (#7326) * Add architecture to macOS cache keys * Only save Homebrew cache if lock file has changed --- .github/workflows/build.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b80d5df75..eee7ae803 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,19 +95,21 @@ jobs: - name: Clean up Homebrew download cache run: rm -rf ~/Library/Caches/Homebrew/downloads - name: Restore Homebrew download cache + id: cache-homebrew uses: actions/cache/restore@v3 with: key: n/a - only restore from restore-keys restore-keys: | - homebrew- + homebrew-${{ matrix.arch }}- path: ~/Library/Caches/Homebrew/downloads - name: Cache ccache data uses: actions/cache@v3 with: - key: ccache-${{ github.job }}-${{ github.ref }}-${{ github.run_id }} + key: "ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}\ + -${{ github.run_id }}" restore-keys: | - ccache-${{ github.job }}-${{ github.ref }}- - ccache-${{ github.job }}- + ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}- + ccache-${{ github.job }}-${{ matrix.arch }}- path: ~/Library/Caches/ccache - name: Install dependencies run: | @@ -154,10 +156,14 @@ jobs: env: CCACHE_MAXSIZE: 500MB - name: Save Homebrew download cache + if: ${{ steps.cache-homebrew.outputs.cache-matched-key != env.key }} uses: actions/cache/save@v3 with: - key: homebrew-${{ hashFiles('Brewfile.lock.json') }} + key: ${{ env.key }} path: ~/Library/Caches/Homebrew/downloads + env: + key: "homebrew-${{ matrix.arch }}\ + -${{ hashFiles('Brewfile.lock.json') }}" mingw: strategy: fail-fast: false From 26646c653cf5d41dfb4eafe366e8218929861144 Mon Sep 17 00:00:00 2001 From: Monospace-V <76674645+Monospace-V@users.noreply.github.com> Date: Sat, 22 Jun 2024 10:38:01 +0530 Subject: [PATCH 13/31] Style format `DrumSynth` (#7189) Co-authored-by: saker --- include/DrumSynth.h | 34 +- src/core/DrumSynth.cpp | 1347 +++++++++++++++++++++++----------------- 2 files changed, 801 insertions(+), 580 deletions(-) diff --git a/include/DrumSynth.h b/include/DrumSynth.h index 750055ddb..3b418abd6 100644 --- a/include/DrumSynth.h +++ b/include/DrumSynth.h @@ -27,33 +27,33 @@ #define LMMS_DRUM_SYNTH_H #include + #include "lmms_basics.h" class QString; -namespace lmms +namespace lmms { + +class DrumSynth { +public: + DrumSynth() = default; + int GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sample_rate_t Fs); -class DrumSynth { - public: - DrumSynth() = default; - int GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs); +private: + float LoudestEnv(); + int LongestEnv(); + void UpdateEnv(int e, long t); + void GetEnv(int env, const char* sec, const char* key, QString ini); - private: - float LoudestEnv(); - int LongestEnv(); - void UpdateEnv(int e, long t); - void GetEnv(int env, const char *sec, const char *key, QString ini); - - float waveform(float ph, int form); - - int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file); - int GetPrivateProfileInt(const char *sec, const char *key, int def, QString file); - float GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file); + float waveform(float ph, int form); + int GetPrivateProfileString( + const char* sec, const char* key, const char* def, char* buffer, int size, QString file); + int GetPrivateProfileInt(const char* sec, const char* key, int def, QString file); + float GetPrivateProfileFloat(const char* sec, const char* key, float def, QString file); }; - } // namespace lmms #endif // LMMS_DRUM_SYNTH_H diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index 031b19c1c..f855639cb 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -23,49 +23,42 @@ * */ - #include "DrumSynth.h" -#include -#include - -#include //sin(), exp(), etc. - #include - +#include +#include +#include #ifdef _MSC_VER -//not #if LMMS_BUILD_WIN32 because we have strncasecmp in mingw +// not #if LMMS_BUILD_WIN32 because we have strncasecmp in mingw #define strcasecmp _stricmp #endif // _MSC_VER -namespace lmms -{ - +namespace lmms { using namespace std; // const int Fs = 44100; -const float TwoPi = 6.2831853f; -const int MAX = 0; -const int ENV = 1; -const int PNT = 2; -const int dENV = 3; -const int NEXTT = 4; +const float TwoPi = 6.2831853f; +const int MAX = 0; +const int ENV = 1; +const int PNT = 2; +const int dENV = 3; +const int NEXTT = 4; // Bah, I'll move these into the class once I sepearate DrumsynthFile from DrumSynth // llama -float envpts[8][3][32]; //envelope/time-level/point -float envData[8][6]; //envelope running status -int chkOn[8], sliLev[8]; //section on/off and level -float timestretch; //overall time scaling +float envpts[8][3][32]; // envelope/time-level/point +float envData[8][6]; // envelope running status +int chkOn[8], sliLev[8]; // section on/off and level +float timestretch; // overall time scaling short DD[1200], clippoint; float DF[1200]; float phi[1200]; -long wavewords, wavemode=0; -float mem_t=1.0f, mem_o=1.0f, mem_n=1.0f, mem_b=1.0f, mem_tune=1.0f, mem_time=1.0f; - +long wavewords, wavemode = 0; +float mem_t = 1.0f, mem_o = 1.0f, mem_n = 1.0f, mem_b = 1.0f, mem_tune = 1.0f, mem_time = 1.0f; int DrumSynth::LongestEnv() { @@ -74,78 +67,107 @@ int DrumSynth::LongestEnv() for (long e = 1; e < 7; e++) // 3 { long eon = e - 1; - if (eon > 2) { eon = eon - 1; } + if (eon > 2) + { + eon = eon - 1; + } long p = 0; - while (envpts[e][0][p + 1] >= 0.f) { p++; } + while (envpts[e][0][p + 1] >= 0.f) + { + p++; + } envData[e][MAX] = envpts[e][0][p] * timestretch; - if (chkOn[eon] == 1 && envData[e][MAX] > l) { l = envData[e][MAX]; } - } - //l *= timestretch; + if (chkOn[eon] == 1 && envData[e][MAX] > l) + { + l = envData[e][MAX]; + } + } + // l *= timestretch; - return 2400 + (1200 * (int)(l / 1200)); + return 2400 + (1200 * static_cast(l / 1200)); } - float DrumSynth::LoudestEnv() { - float loudest=0.f; - int i=0; + float loudest = 0.f; + int i = 0; - while (i<5) //2 - { - if(chkOn[i]==1) if(sliLev[i]>loudest) loudest=(float)sliLev[i]; - i++; - } - return (loudest * loudest); + while (i < 5) // 2 + { + if ((chkOn[i] == 1) && (sliLev[i] > loudest)) + { + loudest = static_cast(sliLev[i]); + } + i++; + } + return loudest * loudest; } - void DrumSynth::UpdateEnv(int e, long t) { // 0.2's added envData[e][NEXTT] = envpts[e][0][static_cast(envData[e][PNT] + 1.f)] * timestretch; // get next point - if (envData[e][NEXTT] < 0) { envData[e][NEXTT] = 442000 * timestretch; } // if end point, hold - envData[e][ENV] = envpts[e][1][static_cast(envData[e][PNT] + 0.f)] * 0.01f; // this level - float endEnv = envpts[e][1][static_cast(envData[e][PNT] + 1.f)] * 0.01f; // next level + if (envData[e][NEXTT] < 0) + { + envData[e][NEXTT] = 442000 * timestretch; // if end point, hold + } + envData[e][ENV] = envpts[e][1][static_cast(envData[e][PNT] + 0.f)] * 0.01f; // this level + float endEnv = envpts[e][1][static_cast(envData[e][PNT] + 1.f)] * 0.01f; // next level float dT = envData[e][NEXTT] - static_cast(t); - if (dT < 1.0) { dT = 1.0; } + if (dT < 1.0) + { + dT = 1.0; + } envData[e][dENV] = (endEnv - envData[e][ENV]) / dT; envData[e][PNT] = envData[e][PNT] + 1.0f; } - -void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini) +void DrumSynth::GetEnv(int env, const char* sec, const char* key, QString ini) { - char en[256], s[8]; - int i=0, o=0, ep=0; - GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini); + char en[256], s[8]; + int i = 0, o = 0, ep = 0; + GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini); - //be safe! - en[255]=0; - s[0]=0; + // be safe! + en[255] = 0; + s[0] = 0; - while(en[i]!=0) - { - if(en[i] == ',') - { - if(sscanf(s, "%f", &envpts[env][0][ep])==0) envpts[env][0][ep] = 0.f; - o=0; - } - else if(en[i] == ' ') - { - if(sscanf(s, "%f", &envpts[env][1][ep])==0) envpts[env][1][ep] = 0.f; - o=0; ep++; - } - else { s[o]=en[i]; o++; s[o]=0; } - i++; - } - if(sscanf(s, "%f", &envpts[env][1][ep])==0) envpts[env][1][ep] = 0.f; - envpts[env][0][ep + 1] = -1; + while (en[i] != 0) + { + if (en[i] == ',') + { + if (sscanf(s, "%f", &envpts[env][0][ep]) == 0) + { + envpts[env][0][ep] = 0.f; + } + o = 0; + } + else if (en[i] == ' ') + { + if (sscanf(s, "%f", &envpts[env][1][ep]) == 0) + { + envpts[env][1][ep] = 0.f; + } + o = 0; + ep++; + } + else + { + s[o] = en[i]; + o++; + s[o] = 0; + } + i++; + } + if (sscanf(s, "%f", &envpts[env][1][ep]) == 0) + { + envpts[env][1][ep] = 0.f; + } + envpts[env][0][ep + 1] = -1; - envData[env][MAX] = envpts[env][0][ep]; + envData[env][MAX] = envpts[env][0][ep]; } - float DrumSynth::waveform(float ph, int form) { float w; @@ -159,9 +181,15 @@ float DrumSynth::waveform(float ph, int form) w = static_cast(fabs(2.0f * static_cast(sin(fmod(0.5f * ph, TwoPi))) - 1.f)); break; // sine^2 case 2: - while (ph < TwoPi) { ph += TwoPi; } + while (ph < TwoPi) + { + ph += TwoPi; + } w = 0.6366197f * static_cast(fmod(ph, TwoPi) - 1.f); // tri - if (w > 1.f) { w = 2.f - w; } + if (w > 1.f) + { + w = 2.f - w; + } break; case 3: w = ph - TwoPi * static_cast(static_cast(ph / TwoPi)); // saw @@ -175,8 +203,8 @@ float DrumSynth::waveform(float ph, int form) return w; } - -int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file) +int DrumSynth::GetPrivateProfileString( + const char* sec, const char* key, const char* def, char* buffer, int size, QString file) { stringstream is; bool inSection = false; @@ -184,572 +212,765 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c char* line = static_cast(malloc(200)); - // Use QFile to handle unicode file name on Windows - // Previously we used ifstream directly - QFile f(file); - f.open(QIODevice::ReadOnly); - QByteArray dat = f.readAll().constData(); - is.str(string(dat.constData(), dat.size())); + // Use QFile to handle unicode file name on Windows + // Previously we used ifstream directly + QFile f(file); + f.open(QIODevice::ReadOnly); + QByteArray dat = f.readAll().constData(); + is.str(string(dat.constData(), dat.size())); - while (is.good()) { - if (!inSection) { - is.ignore( numeric_limits::max(), '['); + while (is.good()) + { + if (!inSection) + { + is.ignore(numeric_limits::max(), '['); - if (!is.eof()) { - is.getline(line, 200, ']'); - if (strcasecmp(line, sec)==0) { - inSection = true; - } - } - } - else if (!is.eof()) { - is.getline(line, 200); - if (line[0] == '[') - break; + if (!is.eof()) + { + is.getline(line, 200, ']'); + if (strcasecmp(line, sec) == 0) + { + inSection = true; + } + } + } + else if (!is.eof()) + { + is.getline(line, 200); + if (line[0] == '[') + { + break; + } - char* k = strtok(line, " \t="); - char* b = strtok(nullptr, "\n\r\0"); + char* k = strtok(line, " \t="); + char* b = strtok(nullptr, "\n\r\0"); - if (k != 0 && strcasecmp(k, key)==0) { - if (b==0) { - len = 0; - buffer[0] = 0; - } - else { - k = (char *)(b + strlen(b)-1); - while ( (k>=b) && (*k==' ' || *k=='\t') ) - --k; - *(k+1) = '\0'; + if (k != 0 && strcasecmp(k, key) == 0) + { + if (b == 0) + { + len = 0; + buffer[0] = 0; + } + else + { + k = static_cast(b + strlen(b) - 1); + while ((k >= b) && (*k == ' ' || *k == '\t')) + { + --k; + } + *(k + 1) = '\0'; - len = strlen(b); - if (len > size-1) len = size-1; - strncpy(buffer, b, len+1); - } - break; - } - } - } + len = strlen(b); + if (len > size - 1) + { + len = size - 1; + } + strncpy(buffer, b, len + 1); + } + break; + } + } + } - if (len == 0) { - len = strlen(def); - strncpy(buffer, def, size); - } + if (len == 0) + { + len = strlen(def); + strncpy(buffer, def, size); + } - free(line); + free(line); - return len; + return len; } -int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, QString file) +int DrumSynth::GetPrivateProfileInt(const char* sec, const char* key, int def, QString file) { - char tmp[16]; - int i=0; + char tmp[16]; + int i = 0; - GetPrivateProfileString(sec, key, "", tmp, sizeof(tmp), file); - sscanf(tmp, "%d", &i); if(tmp[0]==0) i=def; + GetPrivateProfileString(sec, key, "", tmp, sizeof(tmp), file); + sscanf(tmp, "%d", &i); + if (tmp[0] == 0) + { + i = def; + } - return i; + return i; } -float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file) +float DrumSynth::GetPrivateProfileFloat(const char* sec, const char* key, float def, QString file) { - char tmp[16]; - float f=0.f; + char tmp[16]; + float f = 0.f; - GetPrivateProfileString(sec, key, "", tmp, sizeof(tmp), file); - sscanf(tmp, "%f", &f); if(tmp[0]==0) f=def; + GetPrivateProfileString(sec, key, "", tmp, sizeof(tmp), file); + sscanf(tmp, "%f", &f); + if (tmp[0] == 0) + { + f = def; + } - return f; + return f; } - // Constantly opening and scanning each file for the setting really sucks. // But, the original did this, and we know it works. Will store file into // an associative array or something once we have a datastructure to load in to. // llama -int DrumSynth::GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs) +int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sample_rate_t Fs) { - //input file - char sec[32]; - char ver[32]; - char comment[256]; - int commentLen=0; + // input file + char sec[32]; + char ver[32]; + char comment[256]; + int commentLen = 0; - //generation - long Length, tpos=0, tplus, totmp, t, i, j; - float x[3] = {0.f, 0.f, 0.f}; - float MasterTune; - constexpr float randmax = 1.f / static_cast(RAND_MAX); - constexpr float randmax2 = 2.f / static_cast(RAND_MAX); - int MainFilter, HighPass; + // generation + long Length, tpos = 0, tplus, totmp, t, i, j; + float x[3] = {0.f, 0.f, 0.f}; + float MasterTune; + constexpr float randmax = 1.f / static_cast(RAND_MAX); + constexpr float randmax2 = 2.f / static_cast(RAND_MAX); + int MainFilter, HighPass; - long NON, NT, TON, DiON, TDroop=0, DStep; - float a, b=0.f, c=0.f, d=0.f, g, TT=0.f, TL, NL, F1, F2; - float TphiStart=0.f, Tphi, TDroopRate, ddF, DAtten, DGain; + long NON, NT, TON, DiON, TDroop = 0, DStep; + float a, b = 0.f, c = 0.f, d = 0.f, g, TT = 0.f, TL, NL, F1, F2; + float TphiStart = 0.f, Tphi, TDroopRate, ddF, DAtten, DGain; - long BON, BON2, BFStep, BFStep2, botmp; - float BdF=0.f, BdF2=0.f, BPhi, BPhi2, BF, BF2, BQ, BQ2, BL, BL2; + long BON, BON2, BFStep, BFStep2, botmp; + float BdF = 0.f, BdF2 = 0.f, BPhi, BPhi2, BF, BF2, BQ, BQ2, BL, BL2; - long OON, OF1Sync=0, OF2Sync=0, OMode, OW1, OW2; - float Ophi1, Ophi2, OF1, OF2, OL, Ot=0 /*PG: init */, OBal1, OBal2, ODrive; - float Ocf1, Ocf2, OcF, OcQ, OcA, Oc[6][2]; //overtone cymbal mode - float Oc0=0.0f, Oc1=0.0f, Oc2=0.0f; + long OON, OF1Sync = 0, OF2Sync = 0, OMode, OW1, OW2; + float Ophi1, Ophi2, OF1, OF2, OL, Ot = 0 /*PG: init */, OBal1, OBal2, ODrive; + float Ocf1, Ocf2, OcF, OcQ, OcA, Oc[6][2]; // overtone cymbal mode + float Oc0 = 0.0f, Oc1 = 0.0f, Oc2 = 0.0f; - float MFfb, MFtmp, MFres, MFin=0.f, MFout=0.f; - float DownAve; - long DownStart, DownEnd, jj; + float MFfb, MFtmp, MFres, MFin = 0.f, MFout = 0.f; + float DownAve; + long DownStart, DownEnd, jj; + if (wavemode == 0) // semi-real-time adjustments if working in memory!! + { + mem_t = 1.0f; + mem_o = 1.0f; + mem_n = 1.0f; + mem_b = 1.0f; + mem_tune = 0.0f; + mem_time = 1.0f; + } - if(wavemode==0) //semi-real-time adjustments if working in memory!! - { - mem_t = 1.0f; - mem_o = 1.0f; - mem_n = 1.0f; - mem_b = 1.0f; - mem_tune = 0.0f; - mem_time = 1.0f; - } + // try to read version from input file + strcpy(sec, "General"); + GetPrivateProfileString(sec, "Version", "", ver, sizeof(ver), dsfile); + ver[9] = 0; + if ((strcasecmp(ver, "DrumSynth") != 0) // input fail + || (ver[11] != '1' && ver[11] != '2')) // version fail + { + return 0; + } - //try to read version from input file - strcpy(sec, "General"); - GetPrivateProfileString(sec,"Version","",ver,sizeof(ver),dsfile); - ver[9]=0; - if(strcasecmp(ver, "DrumSynth") != 0) {return 0;} //input fail - if(ver[11] != '1' && ver[11] != '2') {return 0;} //version fail + // read master parameters + GetPrivateProfileString(sec, "Comment", "", comment, sizeof(comment), dsfile); + while ((comment[commentLen] != 0) && (commentLen < 254)) + { + commentLen++; + } + if (commentLen == 0) + { + comment[0] = 32; + comment[1] = 0; + commentLen = 1; + } + comment[commentLen + 1] = 0; + commentLen++; + if ((commentLen % 2) == 1) + { + commentLen++; + } + timestretch = .01f * mem_time * GetPrivateProfileFloat(sec, "Stretch", 100.0, dsfile); + if (timestretch < 0.2f) + { + timestretch = 0.2f; + } + if (timestretch > 10.f) + { + timestretch = 10.f; + } + // the unit of envelope lengths is a sample in 44100Hz sample rate, so correct it + timestretch *= Fs / 44100.f; - //read master parameters - GetPrivateProfileString(sec,"Comment","",comment,sizeof(comment),dsfile); - while((comment[commentLen]!=0) && (commentLen<254)) commentLen++; - if(commentLen==0) { comment[0]=32; comment[1]=0; commentLen=1;} - comment[commentLen+1]=0; commentLen++; - if((commentLen % 2)==1) commentLen++; + DGain = 1.0f; // leave this here! + DGain = static_cast(std::pow(10.0, 0.05 * GetPrivateProfileFloat(sec, "Level", 0, dsfile))); - timestretch = .01f * mem_time * GetPrivateProfileFloat(sec,"Stretch",100.0,dsfile); - if(timestretch<0.2f) timestretch=0.2f; - if(timestretch>10.f) timestretch=10.f; - // the unit of envelope lengths is a sample in 44100Hz sample rate, so correct it - timestretch *= Fs / 44100.f; + MasterTune = GetPrivateProfileFloat(sec, "Tuning", 0.0, dsfile); + MasterTune = static_cast(std::pow(1.0594631f, MasterTune + mem_tune)); + MainFilter = 2 * GetPrivateProfileInt(sec, "Filter", 0, dsfile); + MFres = 0.0101f * GetPrivateProfileFloat(sec, "Resonance", 0.0, dsfile); + MFres = static_cast(std::pow(MFres, 0.5f)); - DGain = 1.0f; //leave this here! - DGain = static_cast(std::pow(10.0, 0.05 * GetPrivateProfileFloat(sec,"Level",0,dsfile))); + HighPass = GetPrivateProfileInt(sec, "HighPass", 0, dsfile); + GetEnv(7, sec, "FilterEnv", dsfile); - MasterTune = GetPrivateProfileFloat(sec,"Tuning",0.0,dsfile); - MasterTune = static_cast(std::pow(1.0594631f, MasterTune + mem_tune)); - MainFilter = 2 * GetPrivateProfileInt(sec,"Filter",0,dsfile); - MFres = 0.0101f * GetPrivateProfileFloat(sec,"Resonance",0.0,dsfile); - MFres = static_cast(std::pow(MFres, 0.5f)); + // read noise parameters + strcpy(sec, "Noise"); + chkOn[1] = GetPrivateProfileInt(sec, "On", 0, dsfile); + sliLev[1] = GetPrivateProfileInt(sec, "Level", 0, dsfile); + NT = GetPrivateProfileInt(sec, "Slope", 0, dsfile); + GetEnv(2, sec, "Envelope", dsfile); + NON = chkOn[1]; + NL = static_cast(sliLev[1] * sliLev[1]) * mem_n; + if (NT < 0) + { + a = 1.f + (NT / 105.f); + d = -NT / 105.f; + g = (1.f + 0.0005f * NT * NT) * NL; + } + else + { + a = 1.f; + b = -NT / 50.f; + c = static_cast(fabs(static_cast(NT))) / 100.f; + g = NL; + } - HighPass = GetPrivateProfileInt(sec,"HighPass",0,dsfile); - GetEnv(7, sec, "FilterEnv", dsfile); + // if(GetPrivateProfileInt(sec,"FixedSeq",0,dsfile)!=0) + // srand(1); //fixed random sequence + // read tone parameters + strcpy(sec, "Tone"); + chkOn[0] = GetPrivateProfileInt(sec, "On", 0, dsfile); + TON = chkOn[0]; + sliLev[0] = GetPrivateProfileInt(sec, "Level", 128, dsfile); + TL = static_cast(sliLev[0] * sliLev[0]) * mem_t; + GetEnv(1, sec, "Envelope", dsfile); + F1 = MasterTune * TwoPi * GetPrivateProfileFloat(sec, "F1", 200.0, dsfile) / Fs; + if (fabs(F1) < 0.001f) + { + F1 = 0.001f; // to prevent overtone ratio div0 + } + F2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec, "F2", 120.0, dsfile) / Fs; + TDroopRate = GetPrivateProfileFloat(sec, "Droop", 0.f, dsfile); + if (TDroopRate > 0.f) + { + TDroopRate = static_cast(std::pow(10.0f, (TDroopRate - 20.0f) / 30.0f)); + TDroopRate = TDroopRate * -4.f / envData[1][MAX]; + TDroop = 1; + F2 = F1 + ((F2 - F1) / (1.f - static_cast(exp(TDroopRate * envData[1][MAX])))); + ddF = F1 - F2; + } + else + { + ddF = F2 - F1; + } - //read noise parameters - strcpy(sec, "Noise"); - chkOn[1] = GetPrivateProfileInt(sec,"On",0,dsfile); - sliLev[1] = GetPrivateProfileInt(sec,"Level",0,dsfile); - NT = GetPrivateProfileInt(sec,"Slope",0,dsfile); - GetEnv(2, sec, "Envelope", dsfile); - NON = chkOn[1]; - NL = (float)(sliLev[1] * sliLev[1]) * mem_n; - if(NT<0) - { a = 1.f + (NT / 105.f); d = -NT / 105.f; - g = (1.f + 0.0005f * NT * NT) * NL; } - else - { a = 1.f; b = -NT / 50.f; c = (float)fabs((float)NT) / 100.f; g = NL; } + Tphi = GetPrivateProfileFloat(sec, "Phase", 90.f, dsfile) / 57.29578f; // degrees>radians - //if(GetPrivateProfileInt(sec,"FixedSeq",0,dsfile)!=0) - //srand(1); //fixed random sequence + // read overtone parameters + strcpy(sec, "Overtones"); + chkOn[2] = GetPrivateProfileInt(sec, "On", 0, dsfile); + OON = chkOn[2]; + sliLev[2] = GetPrivateProfileInt(sec, "Level", 128, dsfile); + OL = static_cast(sliLev[2] * sliLev[2]) * mem_o; + GetEnv(3, sec, "Envelope1", dsfile); + GetEnv(4, sec, "Envelope2", dsfile); + OMode = GetPrivateProfileInt(sec, "Method", 2, dsfile); + OF1 = MasterTune * TwoPi * GetPrivateProfileFloat(sec, "F1", 200.0, dsfile) / Fs; + OF2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec, "F2", 120.0, dsfile) / Fs; + OW1 = GetPrivateProfileInt(sec, "Wave1", 0, dsfile); + OW2 = GetPrivateProfileInt(sec, "Wave2", 0, dsfile); + OBal2 = static_cast(GetPrivateProfileInt(sec, "Param", 50, dsfile)); + ODrive = static_cast(std::pow(OBal2, 3.0f)) / std::pow(50.0f, 3.0f); + OBal2 *= 0.01f; + OBal1 = 1.f - OBal2; + Ophi1 = Tphi; + Ophi2 = Tphi; + if (MainFilter == 0) + { + MainFilter = GetPrivateProfileInt(sec, "Filter", 0, dsfile); + } + if ((GetPrivateProfileInt(sec, "Track1", 0, dsfile) == 1) && (TON == 1)) + { + OF1Sync = 1; + OF1 = OF1 / F1; + } + if ((GetPrivateProfileInt(sec, "Track2", 0, dsfile) == 1) && (TON == 1)) + { + OF2Sync = 1; + OF2 = OF2 / F1; + } - //read tone parameters - strcpy(sec, "Tone"); - chkOn[0] = GetPrivateProfileInt(sec,"On",0,dsfile); TON = chkOn[0]; - sliLev[0] = GetPrivateProfileInt(sec,"Level",128,dsfile); - TL = (float)(sliLev[0] * sliLev[0]) * mem_t; - GetEnv(1, sec, "Envelope", dsfile); - F1 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F1",200.0,dsfile) / Fs; - if(fabs(F1)<0.001f) F1=0.001f; //to prevent overtone ratio div0 - F2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F2",120.0,dsfile) / Fs; - TDroopRate = GetPrivateProfileFloat(sec,"Droop",0.f,dsfile); - if(TDroopRate>0.f) - { - TDroopRate = static_cast(std::pow(10.0f, (TDroopRate - 20.0f) / 30.0f)); - TDroopRate = TDroopRate * -4.f / envData[1][MAX]; - TDroop = 1; - F2 = F1+((F2-F1)/(1.f-(float)exp(TDroopRate * envData[1][MAX]))); - ddF = F1 - F2; - } - else ddF = F2-F1; + OcA = 0.28f + OBal1 * OBal1; // overtone cymbal mode + OcQ = OcA * OcA; + OcF = (1.8f - 0.7f * OcQ) * 0.92f; // multiply by env 2 + OcA *= 1.0f + 4.0f * OBal1; // level is a compromise! + Ocf1 = TwoPi / OF1; + Ocf2 = TwoPi / OF2; + for (i = 0; i < 6; i++) + { + Oc[i][0] = Oc[i][1] = Ocf1 + (Ocf2 - Ocf1) * 0.2f * static_cast(i); + } - Tphi = GetPrivateProfileFloat(sec,"Phase",90.f,dsfile) / 57.29578f; //degrees>radians + // read noise band parameters + strcpy(sec, "NoiseBand"); + chkOn[3] = GetPrivateProfileInt(sec, "On", 0, dsfile); + BON = chkOn[3]; + sliLev[3] = GetPrivateProfileInt(sec, "Level", 128, dsfile); + BL = static_cast(sliLev[3] * sliLev[3]) * mem_b; + BF = MasterTune * TwoPi * GetPrivateProfileFloat(sec, "F", 1000.0, dsfile) / Fs; + BPhi = TwoPi / 8.f; + GetEnv(5, sec, "Envelope", dsfile); + BFStep = GetPrivateProfileInt(sec, "dF", 50, dsfile); + BQ = static_cast(BFStep); + BQ = BQ * BQ / (10000.f - 6600.f * (static_cast(sqrt(BF)) - 0.19f)); + BFStep = 1 + static_cast((40.f - (BFStep / 2.5f)) / (BQ + 1.f + (1.f * BF))); - //read overtone parameters - strcpy(sec, "Overtones"); - chkOn[2] = GetPrivateProfileInt(sec,"On",0,dsfile); OON = chkOn[2]; - sliLev[2] = GetPrivateProfileInt(sec,"Level",128,dsfile); - OL = (float)(sliLev[2] * sliLev[2]) * mem_o; - GetEnv(3, sec, "Envelope1", dsfile); - GetEnv(4, sec, "Envelope2", dsfile); - OMode = GetPrivateProfileInt(sec,"Method",2,dsfile); - OF1 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F1",200.0,dsfile) / Fs; - OF2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F2",120.0,dsfile) / Fs; - OW1 = GetPrivateProfileInt(sec,"Wave1",0,dsfile); - OW2 = GetPrivateProfileInt(sec,"Wave2",0,dsfile); - OBal2 = (float)GetPrivateProfileInt(sec,"Param",50,dsfile); - ODrive = static_cast(std::pow(OBal2, 3.0f)) / std::pow(50.0f, 3.0f); - OBal2 *= 0.01f; - OBal1 = 1.f - OBal2; - Ophi1 = Tphi; - Ophi2 = Tphi; - if(MainFilter==0) - MainFilter = GetPrivateProfileInt(sec,"Filter",0,dsfile); - if((GetPrivateProfileInt(sec,"Track1",0,dsfile)==1) && (TON==1)) - { OF1Sync = 1; OF1 = OF1 / F1; } - if((GetPrivateProfileInt(sec,"Track2",0,dsfile)==1) && (TON==1)) - { OF2Sync = 1; OF2 = OF2 / F1; } + strcpy(sec, "NoiseBand2"); + chkOn[4] = GetPrivateProfileInt(sec, "On", 0, dsfile); + BON2 = chkOn[4]; + sliLev[4] = GetPrivateProfileInt(sec, "Level", 128, dsfile); + BL2 = static_cast(sliLev[4] * sliLev[4]) * mem_b; + BF2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec, "F", 1000.0, dsfile) / Fs; + BPhi2 = TwoPi / 8.f; + GetEnv(6, sec, "Envelope", dsfile); + BFStep2 = GetPrivateProfileInt(sec, "dF", 50, dsfile); + BQ2 = static_cast(BFStep2); + BQ2 = BQ2 * BQ2 / (10000.f - 6600.f * (static_cast(sqrt(BF2)) - 0.19f)); + BFStep2 = 1 + static_cast((40 - (BFStep2 / 2.5)) / (BQ2 + 1 + (1 * BF2))); - OcA = 0.28f + OBal1 * OBal1; //overtone cymbal mode - OcQ = OcA * OcA; - OcF = (1.8f - 0.7f * OcQ) * 0.92f; //multiply by env 2 - OcA *= 1.0f + 4.0f * OBal1; //level is a compromise! - Ocf1 = TwoPi / OF1; - Ocf2 = TwoPi / OF2; - for(i=0; i<6; i++) Oc[i][0] = Oc[i][1] = Ocf1 + (Ocf2 - Ocf1) * 0.2f * (float)i; + // read distortion parameters + strcpy(sec, "Distortion"); + chkOn[5] = GetPrivateProfileInt(sec, "On", 0, dsfile); + DiON = chkOn[5]; + DStep = 1 + GetPrivateProfileInt(sec, "Rate", 0, dsfile); + if (DStep == 7) { DStep = 20; } + if (DStep == 6) { DStep = 10; } + if (DStep == 5) { DStep = 8; } - //read noise band parameters - strcpy(sec, "NoiseBand"); - chkOn[3] = GetPrivateProfileInt(sec,"On",0,dsfile); BON = chkOn[3]; - sliLev[3] = GetPrivateProfileInt(sec,"Level",128,dsfile); - BL = (float)(sliLev[3] * sliLev[3]) * mem_b; - BF = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F",1000.0,dsfile) / Fs; - BPhi = TwoPi / 8.f; - GetEnv(5, sec, "Envelope", dsfile); - BFStep = GetPrivateProfileInt(sec,"dF",50,dsfile); - BQ = (float)BFStep; - BQ = BQ * BQ / (10000.f-6600.f*((float)sqrt(BF)-0.19f)); - BFStep = 1 + (int)((40.f - (BFStep / 2.5f)) / (BQ + 1.f + (1.f * BF))); + clippoint = 32700; + DAtten = 1.0f; - strcpy(sec, "NoiseBand2"); - chkOn[4] = GetPrivateProfileInt(sec,"On",0,dsfile); BON2 = chkOn[4]; - sliLev[4] = GetPrivateProfileInt(sec,"Level",128,dsfile); - BL2 = (float)(sliLev[4] * sliLev[4]) * mem_b; - BF2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F",1000.0,dsfile) / Fs; - BPhi2 = TwoPi / 8.f; - GetEnv(6, sec, "Envelope", dsfile); - BFStep2 = GetPrivateProfileInt(sec,"dF",50,dsfile); - BQ2 = (float)BFStep2; - BQ2 = BQ2 * BQ2 / (10000.f-6600.f*((float)sqrt(BF2)-0.19f)); - BFStep2 = 1 + (int)((40 - (BFStep2 / 2.5)) / (BQ2 + 1 + (1 * BF2))); + if (DiON == 1) + { + DAtten = DGain * static_cast(LoudestEnv()); + clippoint = DAtten > 32700 ? 32700 : static_cast(DAtten); + DAtten = static_cast(std::pow(2.0, 2.0 * GetPrivateProfileInt(sec, "Bits", 0, dsfile))); + DGain = DAtten * DGain + * static_cast(std::pow(10.0, 0.05 * GetPrivateProfileInt(sec, "Clipping", 0, dsfile))); + } - //read distortion parameters - strcpy(sec, "Distortion"); - chkOn[5] = GetPrivateProfileInt(sec,"On",0,dsfile); DiON = chkOn[5]; - DStep = 1 + GetPrivateProfileInt(sec,"Rate",0,dsfile); - if(DStep==7) DStep=20; - if(DStep==6) DStep=10; - if(DStep==5) DStep=8; + // prepare envelopes + for (i = 1; i < 8; i++) + { + envData[i][NEXTT] = 0; + envData[i][PNT] = 0; + } + Length = LongestEnv(); - clippoint = 32700; - DAtten = 1.0f; + // allocate the buffer + // if(wave!=NULL) free(wave); + // wave = new int16_t[channels * (Length + 1280)]; //wave memory buffer + wave = new int16_t[channels * Length]; // wave memory buffer + if (wave == nullptr) + { + return 0; + } + wavewords = 0; - if(DiON==1) - { - DAtten = DGain * (short)LoudestEnv(); - if(DAtten>32700) clippoint=32700; else clippoint=(short)DAtten; - DAtten = static_cast(std::pow(2.0, 2.0 * GetPrivateProfileInt(sec,"Bits",0,dsfile))); - DGain = DAtten * DGain * static_cast(std::pow(10.0, 0.05 * GetPrivateProfileInt(sec,"Clipping",0,dsfile))); - } + /* + if(wavemode==0) + { + //open output file + fp = fopen(wavfile, "wb"); + if(!fp) {return 3;} //output fail - //prepare envelopes - for (i=1;i<8;i++) { envData[i][NEXTT]=0; envData[i][PNT]=0; } - Length = LongestEnv(); + //set up INFO chunk + WI.list = 0x5453494C; + WI.listLength = 36 + commentLen; + WI.info = 0x4F464E49; + WI.isft = 0x54465349; + WI.isftLength = 16; + strcpy(WI.software, "DrumSynth v2.0 "); WI.software[15]=0; + WI.icmt = 0x544D4349; + WI.icmtLength = commentLen; - //allocate the buffer - //if(wave!=NULL) free(wave); - //wave = new int16_t[channels * (Length + 1280)]; //wave memory buffer - wave = new int16_t[channels * Length]; //wave memory buffer - if(wave==nullptr) {return 0;} - wavewords = 0; + //write WAV header + WH.riff = 0x46464952; + WH.riffLength = 36 + (2 * Length) + 44 + commentLen; + WH.wave = 0x45564157; + WH.fmt = 0x20746D66; + WH.waveLength = 16; + WH.wFormatTag = WAVE_FORMAT_PCM; + WH.nChannels = 1; + WH.nSamplesPerSec = Fs; + WH.nAvgBytesPerSec = 2 * Fs; + WH.nBlockAlign = 2; + WH.wBitsPerSample = 16; + WH.data = 0x61746164; + WH.dataLength = 2 * Length; + fwrite(&WH, 1, 44, fp); + } + */ - /* - if(wavemode==0) - { - //open output file - fp = fopen(wavfile, "wb"); - if(!fp) {return 3;} //output fail + // generate + tpos = 0; + while (tpos < Length) + { + tplus = tpos + 1199; - //set up INFO chunk - WI.list = 0x5453494C; - WI.listLength = 36 + commentLen; - WI.info = 0x4F464E49; - WI.isft = 0x54465349; - WI.isftLength = 16; - strcpy(WI.software, "DrumSynth v2.0 "); WI.software[15]=0; - WI.icmt = 0x544D4349; - WI.icmtLength = commentLen; + if (NON == 1) // noise + { + for (t = tpos; t <= tplus; t++) + { + if (t < envData[2][NEXTT]) + { + envData[2][ENV] = envData[2][ENV] + envData[2][dENV]; + } + else + { + UpdateEnv(2, t); + } + x[2] = x[1]; + x[1] = x[0]; + x[0] = (randmax2 * static_cast(rand())) - 1.f; + TT = a * x[0] + b * x[1] + c * x[2] + d * TT; + DF[t - tpos] = TT * g * envData[2][ENV]; + } + if (t >= envData[2][MAX]) + { + NON = 0; + } + } + else + { + for (j = 0; j < 1200; j++) + { + DF[j] = 0.f; + } + } - //write WAV header - WH.riff = 0x46464952; - WH.riffLength = 36 + (2 * Length) + 44 + commentLen; - WH.wave = 0x45564157; - WH.fmt = 0x20746D66; - WH.waveLength = 16; - WH.wFormatTag = WAVE_FORMAT_PCM; - WH.nChannels = 1; - WH.nSamplesPerSec = Fs; - WH.nAvgBytesPerSec = 2 * Fs; - WH.nBlockAlign = 2; - WH.wBitsPerSample = 16; - WH.data = 0x61746164; - WH.dataLength = 2 * Length; - fwrite(&WH, 1, 44, fp); - } - */ + if (TON == 1) // tone + { + TphiStart = Tphi; + if (TDroop == 1) + { + for (t = tpos; t <= tplus; t++) + { + phi[t - tpos] = F2 + (ddF * static_cast(exp(t * TDroopRate))); + } + } + else + { + for (t = tpos; t <= tplus; t++) + { + phi[t - tpos] = F1 + (t / envData[1][MAX]) * ddF; + } + } + for (t = tpos; t <= tplus; t++) + { + totmp = t - tpos; + if (t < envData[1][NEXTT]) + { + envData[1][ENV] = envData[1][ENV] + envData[1][dENV]; + } + else + { + UpdateEnv(1, t); + } + Tphi = Tphi + phi[totmp]; + DF[totmp] += TL * envData[1][ENV] * static_cast(sin(fmod(Tphi, TwoPi))); // overflow? + } + if (t >= envData[1][MAX]) + { + TON = 0; + } + } + else + { + for (j = 0; j < 1200; j++) + { + phi[j] = F2; // for overtone sync + } + } - //generate - tpos = 0; - while(tpos(rand()) - 0.5f; + } + BPhi = BPhi + BF + BQ * BdF; + botmp = t - tpos; + DF[botmp] = DF[botmp] + static_cast(cos(fmod(BPhi, TwoPi))) * envData[5][ENV] * BL; + } + if (t >= envData[5][MAX]) + { + BON = 0; + } + } - if(NON==1) //noise - { - for(t=tpos; t<=tplus; t++) - { - if(t < envData[2][NEXTT]) envData[2][ENV] = envData[2][ENV] + envData[2][dENV]; - else UpdateEnv(2, t); - x[2] = x[1]; - x[1] = x[0]; - x[0] = (randmax2 * (float)rand()) - 1.f; - TT = a * x[0] + b * x[1] + c * x[2] + d * TT; - DF[t - tpos] = TT * g * envData[2][ENV]; - } - if(t>=envData[2][MAX]) NON=0; - } - else { - for(j=0; j<1200; j++) DF[j]=0.f; - } + if (BON2 == 1) // noise band 2 + { + for (t = tpos; t <= tplus; t++) + { + if (t < envData[6][NEXTT]) + { + envData[6][ENV] = envData[6][ENV] + envData[6][dENV]; + } + else + { + UpdateEnv(6, t); + } + if ((t % BFStep2) == 0) + { + BdF2 = randmax * static_cast(rand()) - 0.5f; + } + BPhi2 = BPhi2 + BF2 + BQ2 * BdF2; + botmp = t - tpos; + DF[botmp] = DF[botmp] + static_cast(cos(fmod(BPhi2, TwoPi))) * envData[6][ENV] * BL2; + } + if (t >= envData[6][MAX]) + { + BON2 = 0; + } + } - if(TON==1) //tone - { - TphiStart = Tphi; - if(TDroop==1) - { - for(t=tpos; t<=tplus; t++) - phi[t - tpos] = F2 + (ddF * (float)exp(t * TDroopRate)); - } - else - { - for(t=tpos; t<=tplus; t++) - phi[t - tpos] = F1 + (t / envData[1][MAX]) * ddF; - } - for(t=tpos; t<=tplus; t++) - { - totmp = t - tpos; - if(t < envData[1][NEXTT]) - envData[1][ENV] = envData[1][ENV] + envData[1][dENV]; - else UpdateEnv(1, t); - Tphi = Tphi + phi[totmp]; - DF[totmp] += TL * envData[1][ENV] * (float)sin(fmod(Tphi,TwoPi));//overflow? - } - if(t>=envData[1][MAX]) TON=0; - } - else for(j=0; j<1200; j++) phi[j]=F2; //for overtone sync + for (t = tpos; t <= tplus; t++) + { + if (OON == 1) // overtones + { + if (t < envData[3][NEXTT]) + { + envData[3][ENV] = envData[3][ENV] + envData[3][dENV]; + } + else + { + if (t >= envData[3][MAX]) // wait for OT2 + { + envData[3][ENV] = 0; + envData[3][dENV] = 0; + envData[3][NEXTT] = 999999; + } + else + { + UpdateEnv(3, t); + } + } + // + if (t < envData[4][NEXTT]) + { + envData[4][ENV] = envData[4][ENV] + envData[4][dENV]; + } + else + { + if (t >= envData[4][MAX]) // wait for OT1 + { + envData[4][ENV] = 0; + envData[4][dENV] = 0; + envData[4][NEXTT] = 999999; + } + else + { + UpdateEnv(4, t); + } + } + // + TphiStart = TphiStart + phi[t - tpos]; + if (OF1Sync == 1) + { + Ophi1 = TphiStart * OF1; + } + else + { + Ophi1 = Ophi1 + OF1; + } + if (OF2Sync == 1) + { + Ophi2 = TphiStart * OF2; + } + else + { + Ophi2 = Ophi2 + OF2; + } + Ot = 0.0f; + switch (OMode) + { + case 0: // add + Ot = OBal1 * envData[3][ENV] * waveform(Ophi1, OW1); + Ot = OL * (Ot + OBal2 * envData[4][ENV] * waveform(Ophi2, OW2)); + break; - if(BON==1) //noise band 1 - { - for(t=tpos; t<=tplus; t++) - { - if(t < envData[5][NEXTT]) - envData[5][ENV] = envData[5][ENV] + envData[5][dENV]; - else UpdateEnv(5, t); - if((t % BFStep) == 0) BdF = randmax * (float)rand() - 0.5f; - BPhi = BPhi + BF + BQ * BdF; - botmp = t - tpos; - DF[botmp] = DF[botmp] + (float)cos(fmod(BPhi,TwoPi)) * envData[5][ENV] * BL; - } - if(t>=envData[5][MAX]) BON=0; - } + case 1: // FM + Ot = ODrive * envData[4][ENV] * waveform(Ophi2, OW2); + Ot = OL * envData[3][ENV] * waveform(Ophi1 + Ot, OW1); + break; - if(BON2==1) //noise band 2 - { - for(t=tpos; t<=tplus; t++) - { - if(t < envData[6][NEXTT]) - envData[6][ENV] = envData[6][ENV] + envData[6][dENV]; - else UpdateEnv(6, t); - if((t % BFStep2) == 0) BdF2 = randmax * (float)rand() - 0.5f; - BPhi2 = BPhi2 + BF2 + BQ2 * BdF2; - botmp = t - tpos; - DF[botmp] = DF[botmp] + (float)cos(fmod(BPhi2,TwoPi)) * envData[6][ENV] * BL2; - } - if(t>=envData[6][MAX]) BON2=0; - } + case 2: // RM + Ot = (1 - ODrive / 8) + (((ODrive / 8) * envData[4][ENV]) * waveform(Ophi2, OW2)); + Ot = OL * envData[3][ENV] * waveform(Ophi1, OW1) * Ot; + break; + case 3: // 808 Cymbal + for (j = 0; j < 6; j++) + { + Oc[j][0] += 1.0f; - for (t=tpos; t<=tplus; t++) - { - if(OON==1) //overtones - { - if(t=envData[3][MAX]) //wait for OT2 - { - envData[3][ENV] = 0; - envData[3][dENV] = 0; - envData[3][NEXTT] = 999999; - } - else UpdateEnv(3, t); - } - // - if(t=envData[4][MAX]) //wait for OT1 - { - envData[4][ENV] = 0; - envData[4][dENV] = 0; - envData[4][NEXTT] = 999999; - } - else UpdateEnv(4, t); - } - // - TphiStart = TphiStart + phi[t - tpos]; - if(OF1Sync==1) Ophi1 = TphiStart * OF1; else Ophi1 = Ophi1 + OF1; - if(OF2Sync==1) Ophi2 = TphiStart * OF2; else Ophi2 = Ophi2 + OF2; - Ot=0.0f; - switch (OMode) - { - case 0: //add - Ot = OBal1 * envData[3][ENV] * waveform(Ophi1, OW1); - Ot = OL * (Ot + OBal2 * envData[4][ENV] * waveform(Ophi2, OW2)); - break; + if (Oc[j][0] > Oc[j][1]) + { + Oc[j][0] -= Oc[j][1]; + Ot = OL * envData[3][ENV]; + } + } + Ocf1 = envData[4][ENV] * OcF; // filter freq + Oc0 += Ocf1 * Oc1; + Oc1 += Ocf1 * (Ot + Oc2 - OcQ * Oc1 - Oc0); // bpf + Oc2 = Ot; + Ot = Oc1; + break; + } + } - case 1: //FM - Ot = ODrive * envData[4][ENV] * waveform(Ophi2, OW2); - Ot = OL * envData[3][ENV] * waveform(Ophi1 + Ot, OW1); - break; + if (MainFilter == 1) // filter overtones + { + if (t < envData[7][NEXTT]) + { + envData[7][ENV] = envData[7][ENV] + envData[7][dENV]; + } + else + { + UpdateEnv(7, t); + } - case 2: //RM - Ot = (1 - ODrive / 8) + (((ODrive / 8) * envData[4][ENV]) * waveform(Ophi2, OW2)); - Ot = OL * envData[3][ENV] * waveform(Ophi1, OW1) * Ot; - break; + MFtmp = envData[7][ENV]; + if (MFtmp > 0.2f) + { + MFfb = 1.001f - static_cast(std::pow(10.0f, MFtmp - 1)); + } + else + { + MFfb = 0.999f - 0.7824f * MFtmp; + } - case 3: //808 Cymbal - for(j=0; j<6; j++) - { - Oc[j][0] += 1.0f; + MFtmp = Ot + MFres * (1.f + (1.f / MFfb)) * (MFin - MFout); + MFin = MFfb * (MFin - MFtmp) + MFtmp; + MFout = MFfb * (MFout - MFin) + MFin; - if(Oc[j][0]>Oc[j][1]) - { - Oc[j][0] -= Oc[j][1]; - Ot = OL * envData[3][ENV]; - } - } - Ocf1 = envData[4][ENV] * OcF; //filter freq - Oc0 += Ocf1 * Oc1; - Oc1 += Ocf1 * (Ot + Oc2 - OcQ * Oc1 - Oc0); //bpf - Oc2 = Ot; - Ot = Oc1; - break; - } - } + DF[t - tpos] = DF[t - tpos] + (MFout - (HighPass * Ot)); + } + else if (MainFilter == 2) // filter all + { + if (t < envData[7][NEXTT]) + { + envData[7][ENV] = envData[7][ENV] + envData[7][dENV]; + } + else + { + UpdateEnv(7, t); + } - if(MainFilter==1) //filter overtones - { - if(t 0.2f) + { + MFfb = 1.001f - static_cast(std::pow(10.0f, MFtmp - 1)); + } + else + { + MFfb = 0.999f - 0.7824f * MFtmp; + } - MFtmp = envData[7][ENV]; - if(MFtmp >0.2f) - MFfb = 1.001f - static_cast(std::pow(10.0f, MFtmp - 1)); - else - MFfb = 0.999f - 0.7824f * MFtmp; + MFtmp = DF[t - tpos] + Ot + MFres * (1.f + (1.f / MFfb)) * (MFin - MFout); + MFin = MFfb * (MFin - MFtmp) + MFtmp; + MFout = MFfb * (MFout - MFin) + MFin; - MFtmp = Ot + MFres * (1.f + (1.f/MFfb)) * (MFin - MFout); - MFin = MFfb * (MFin - MFtmp) + MFtmp; - MFout = MFfb * (MFout - MFin) + MFin; + DF[t - tpos] = MFout - (HighPass * (DF[t - tpos] + Ot)); + } + // PG: Ot is uninitialized + else + { + DF[t - tpos] = DF[t - tpos] + Ot; // no filter + } + } - DF[t - tpos] = DF[t - tpos] + (MFout - (HighPass * Ot)); - } - else if(MainFilter==2) //filter all - { - if(t(DF[j] / DAtten); + } - MFtmp = envData[7][ENV]; - if(MFtmp >0.2f) - MFfb = 1.001f - static_cast(std::pow(10.0f, MFtmp - 1)); - else - MFfb = 0.999f - 0.7824f * MFtmp; + for (j = 0; j < 1200; j += DStep) // downsampling + { + DownAve = 0; + DownStart = j; + DownEnd = j + DStep - 1; + for (jj = DownStart; jj <= DownEnd; jj++) + { + DownAve = DownAve + DF[jj]; + } + DownAve = DownAve / DStep; + for (jj = DownStart; jj <= DownEnd; jj++) + { + DF[jj] = DownAve; + } + } + } + else + { + for (j = 0; j < 1200; j++) + { + DF[j] *= DGain; + } + } - MFtmp = DF[t - tpos] + Ot + MFres * (1.f + (1.f/MFfb)) * (MFin - MFout); - MFin = MFfb * (MFin - MFtmp) + MFtmp; - MFout = MFfb * (MFout - MFin) + MFin; + for (j = 0; j < 1200; j++) // clipping + output + { + if (DF[j] > clippoint) + { + wave[wavewords++] = clippoint; + } + else if (DF[j] < -clippoint) + { + wave[wavewords++] = -clippoint; + } + else + { + wave[wavewords++] = static_cast(DF[j]); + } - DF[t - tpos] = MFout - (HighPass * (DF[t - tpos] + Ot)); - } - // PG: Ot is uninitialized - else DF[t - tpos] = DF[t - tpos] + Ot; //no filter - } + for (int c = 1; c < channels; c++) + { + wave[wavewords] = wave[wavewords - 1]; + wavewords++; + } + } - if(DiON==1) //bit resolution - { - for(j=0; j<1200; j++) - DF[j] = DGain * (int)(DF[j] / DAtten); + tpos = tpos + 1200; + } - for(j=0; j<1200; j+=DStep) //downsampling - { - DownAve = 0; - DownStart = j; - DownEnd = j + DStep - 1; - for(jj = DownStart; jj<=DownEnd; jj++) - DownAve = DownAve + DF[jj]; - DownAve = DownAve / DStep; - for(jj = DownStart; jj<=DownEnd; jj++) - DF[jj] = DownAve; - } - } - else for(j=0; j<1200; j++) DF[j] *= DGain; + /* + if(wavemode==0) + { + fwrite(wave, 2, Length, fp); //write data + fwrite(&WI, 1, 44, fp); //write INFO chunk + fwrite(&comment, 1, commentLen, fp); + fclose(fp); + } + wavemode = 0; //force compatibility!! + */ - for(j = 0; j<1200; j++) //clipping + output - { - if(DF[j] > clippoint) - wave[wavewords++] = clippoint; - else if(DF[j] < -clippoint) - wave[wavewords++] = -clippoint; - else - wave[wavewords++] = (short)DF[j]; - - for (int c = 1; c < channels; c++) { - wave[wavewords] = wave[wavewords-1]; - wavewords++; - } - } - - tpos = tpos + 1200; - } - - /* - if(wavemode==0) - { - fwrite(wave, 2, Length, fp); //write data - fwrite(&WI, 1, 44, fp); //write INFO chunk - fwrite(&comment, 1, commentLen, fp); - fclose(fp); - } - wavemode = 0; //force compatibility!! - */ - - - return Length; + return Length; } - } // namespace lmms From a1f7753a9490cf21b13227636d2275fa076162e9 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sat, 22 Jun 2024 07:05:14 +0100 Subject: [PATCH 14/31] Fix MSVC warnings up to level 2 (#7329) * Fix MSVC warnings up to /W2 * Fix large shift UB warning --- .github/workflows/build.yml | 1 + CMakeLists.txt | 5 ++ plugins/CarlaBase/Carla.h | 2 +- plugins/Compressor/Compressor.h | 2 +- plugins/Compressor/CompressorControlDialog.h | 2 +- plugins/Delay/DelayControls.cpp | 12 +-- plugins/Delay/StereoDelay.cpp | 6 +- plugins/Dispersion/DispersionControls.cpp | 6 +- plugins/DualFilter/DualFilterControls.cpp | 4 +- plugins/Eq/EqControls.cpp | 48 ++++++------ plugins/Eq/EqCurve.cpp | 11 +-- plugins/Eq/EqFader.h | 2 +- plugins/Eq/EqSpectrumView.cpp | 12 +-- plugins/Flanger/FlangerControls.cpp | 12 +-- plugins/Flanger/MonoDelay.cpp | 6 +- plugins/LOMM/LOMM.cpp | 6 +- plugins/LOMM/LOMM.h | 2 +- plugins/LOMM/LOMMControls.cpp | 78 +++++++++---------- plugins/Lb302/Lb302.cpp | 4 +- plugins/Monstro/Monstro.cpp | 30 +++---- plugins/Nes/Nes.h | 10 +-- plugins/OpulenZ/OpulenZ.cpp | 12 +-- .../PeakControllerEffectControls.cpp | 12 +-- plugins/ReverbSC/dcblock.c | 2 +- plugins/ReverbSC/revsc.c | 32 ++++---- plugins/Sf2Player/Sf2Player.cpp | 8 +- plugins/Sfxr/Sfxr.h | 4 +- plugins/SlicerT/SlicerT.cpp | 4 +- plugins/SpectrumAnalyzer/SaSpectrumView.cpp | 2 +- plugins/SpectrumAnalyzer/SaWaterfallView.cpp | 3 +- plugins/Stk/Mallets/Mallets.cpp | 2 +- src/common/SharedMemory.cpp | 5 +- src/core/AutomationClip.cpp | 2 +- src/core/EnvelopeAndLfoParameters.cpp | 26 +++---- src/core/InstrumentSoundShaping.cpp | 2 +- src/core/LfoController.cpp | 6 +- src/core/Mixer.cpp | 6 +- src/core/fft_helpers.cpp | 14 ++-- src/core/lv2/Lv2UridMap.cpp | 4 +- src/gui/editors/AutomationEditor.cpp | 4 +- src/gui/editors/PianoRoll.cpp | 4 +- src/gui/modals/ControllerConnectionDialog.cpp | 5 +- src/gui/widgets/Fader.cpp | 4 +- tests/src/core/ArrayVectorTest.cpp | 8 +- 44 files changed, 215 insertions(+), 217 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eee7ae803..11094720a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -284,6 +284,7 @@ jobs: --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake ` -DCMAKE_BUILD_TYPE=RelWithDebInfo ` -DUSE_COMPILE_CACHE=ON ` + -DUSE_WERROR=ON ` -DVCPKG_TARGET_TRIPLET="${{ matrix.arch }}-windows" ` -DVCPKG_HOST_TRIPLET="${{ matrix.arch }}-windows" ` -DVCPKG_MANIFEST_INSTALL="${{ env.should_install_manifest }}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 9da4fc243..a9dbda4cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -675,6 +675,11 @@ elseif(MSVC) "/external:W0" # Don't emit warnings for third-party code "/external:anglebrackets" # Consider headers included with angle brackets to be third-party "/external:templates-" # Still emit warnings from first-party instantiations of third-party templates + # Silence "class X needs to have DLL-interface to be used by clients of + # class Y" warnings. These aren't trivial to address, and don't pose a + # problem for us since we build all modules with the same compiler and + # options, and dynamically link the CRT. + "/wd4251" ) set(THIRD_PARTY_COMPILE_ERROR_FLAGS "/W0" # Disable all warnings diff --git a/plugins/CarlaBase/Carla.h b/plugins/CarlaBase/Carla.h index c1190e5e7..da0ae67cc 100644 --- a/plugins/CarlaBase/Carla.h +++ b/plugins/CarlaBase/Carla.h @@ -81,7 +81,7 @@ class CarlaParamFloatModel : public FloatModel { public: CarlaParamFloatModel(Model * parent): - FloatModel(0.0, 0.0, 1.0, 0.001, parent, "Unused"), + FloatModel(0.f, 0.f, 1.f, 0.001f, parent, "Unused"), m_isOutput(false), m_isEnabled(false) { diff --git a/plugins/Compressor/Compressor.h b/plugins/Compressor/Compressor.h index 3fc90b752..4d6c05d7e 100755 --- a/plugins/Compressor/Compressor.h +++ b/plugins/Compressor/Compressor.h @@ -35,7 +35,7 @@ namespace lmms { -constexpr float COMP_LOG = -2.2; +constexpr float COMP_LOG = -2.2f; class CompressorEffect : public Effect { diff --git a/plugins/Compressor/CompressorControlDialog.h b/plugins/Compressor/CompressorControlDialog.h index cedba4b04..108c421a0 100755 --- a/plugins/Compressor/CompressorControlDialog.h +++ b/plugins/Compressor/CompressorControlDialog.h @@ -36,7 +36,7 @@ class QLabel; namespace lmms { -constexpr float COMP_NOISE_FLOOR = 0.000001;// -120 dbFs +constexpr float COMP_NOISE_FLOOR = 0.000001f;// -120 dbFs class CompressorControls; diff --git a/plugins/Delay/DelayControls.cpp b/plugins/Delay/DelayControls.cpp index b31488f72..c1ad73153 100644 --- a/plugins/Delay/DelayControls.cpp +++ b/plugins/Delay/DelayControls.cpp @@ -34,11 +34,11 @@ namespace lmms DelayControls::DelayControls( DelayEffect* effect ): EffectControls( effect ), m_effect ( effect ), - m_delayTimeModel( 0.5, 0.01, 5.0, 0.0001, 5000.0, this, tr( "Delay samples" )) , - m_feedbackModel(0.0f,0.0f,1.0f,0.01f,this,tr( "Feedback" ) ), - m_lfoTimeModel(2.0, 0.01, 5.0, 0.0001, 20000.0, this, tr( "LFO frequency" ) ), - m_lfoAmountModel(0.0, 0.0, 0.5, 0.0001, 2000.0, this, tr ( "LFO amount" ) ), - m_outGainModel( 0.0, -60.0, 20.0, 0.01, this, tr( "Output gain" ) ) + m_delayTimeModel(0.5f, 0.01f, 5.f, 0.0001f, 5000.f, this, tr("Delay samples")) , + m_feedbackModel(0.0f, 0.0f, 1.0f, 0.01f, this, tr("Feedback")), + m_lfoTimeModel(2.f, 0.01f, 5.f, 0.0001f, 20000.f, this, tr("LFO frequency")), + m_lfoAmountModel(0.f, 0.f, 0.5f, 0.0001f, 2000.f, this, tr("LFO amount")), + m_outGainModel(0.f, -60.f, 20.f, 0.01f, this, tr("Output gain")) { connect( Engine::audioEngine(), SIGNAL( sampleRateChanged() ), this, SLOT( changeSampleRate() ) ); m_outPeakL = 0.0; @@ -77,4 +77,4 @@ void DelayControls::changeSampleRate() } -} // namespace lmms \ No newline at end of file +} // namespace lmms diff --git a/plugins/Delay/StereoDelay.cpp b/plugins/Delay/StereoDelay.cpp index e4b8b5641..c03cf68d0 100644 --- a/plugins/Delay/StereoDelay.cpp +++ b/plugins/Delay/StereoDelay.cpp @@ -32,9 +32,9 @@ namespace lmms StereoDelay::StereoDelay( int maxTime, int sampleRate ) { m_buffer = 0; - m_maxTime = maxTime; + m_maxTime = static_cast(maxTime); m_maxLength = maxTime * sampleRate; - m_length = m_maxLength; + m_length = static_cast(m_maxLength); m_writeIndex = 0; m_feedback = 0.0f; @@ -58,7 +58,7 @@ StereoDelay::~StereoDelay() void StereoDelay::tick( sampleFrame& frame ) { m_writeIndex = ( m_writeIndex + 1 ) % ( int )m_maxLength; - int readIndex = m_writeIndex - m_length; + int readIndex = m_writeIndex - static_cast(m_length); if (readIndex < 0 ) { readIndex += m_maxLength; } float lOut = m_buffer[ readIndex ][ 0 ]; float rOut = m_buffer[ readIndex ] [1 ]; diff --git a/plugins/Dispersion/DispersionControls.cpp b/plugins/Dispersion/DispersionControls.cpp index 771ffb89d..f97fc0e37 100644 --- a/plugins/Dispersion/DispersionControls.cpp +++ b/plugins/Dispersion/DispersionControls.cpp @@ -35,9 +35,9 @@ DispersionControls::DispersionControls(DispersionEffect* effect) : EffectControls(effect), m_effect(effect), m_amountModel(0, 0, MAX_DISPERSION_FILTERS, this, tr("Amount")), - m_freqModel(200, 20, 20000, 0.001, this, tr("Frequency")), - m_resoModel(0.707, 0.01, 8, 0.0001, this, tr("Resonance")), - m_feedbackModel(0.f, -1.f, 1.f, 0.0001, this, tr("Feedback")), + m_freqModel(200, 20, 20000, 0.001f, this, tr("Frequency")), + m_resoModel(0.707f, 0.01f, 8, 0.0001f, this, tr("Resonance")), + m_feedbackModel(0.f, -1.f, 1.f, 0.0001f, this, tr("Feedback")), m_dcModel(false, this, tr("DC Offset Removal")) { m_freqModel.setScaleLogarithmic(true); diff --git a/plugins/DualFilter/DualFilterControls.cpp b/plugins/DualFilter/DualFilterControls.cpp index 4a4091aa2..75478c9d7 100644 --- a/plugins/DualFilter/DualFilterControls.cpp +++ b/plugins/DualFilter/DualFilterControls.cpp @@ -43,7 +43,7 @@ DualFilterControls::DualFilterControls( DualFilterEffect* effect ) : m_enabled1Model( true, this, tr( "Filter 1 enabled" ) ), m_filter1Model( this, tr( "Filter 1 type" ) ), m_cut1Model( 7000.0f, 1.0f, 20000.0f, 1.0f, this, tr( "Cutoff frequency 1" ) ), - m_res1Model( 0.5, BasicFilters<>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance 1" ) ), + m_res1Model(0.5f, BasicFilters<>::minQ(), 10.f, 0.01f, this, tr("Q/Resonance 1")), m_gain1Model( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Gain 1" ) ), m_mixModel( 0.0f, -1.0f, 1.0f, 0.01f, this, tr( "Mix" ) ), @@ -51,7 +51,7 @@ DualFilterControls::DualFilterControls( DualFilterEffect* effect ) : m_enabled2Model( true, this, tr( "Filter 2 enabled" ) ), m_filter2Model( this, tr( "Filter 2 type" ) ), m_cut2Model( 7000.0f, 1.0f, 20000.0f, 1.0f, this, tr( "Cutoff frequency 2" ) ), - m_res2Model( 0.5, BasicFilters<>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance 2" ) ), + m_res2Model(0.5f, BasicFilters<>::minQ(), 10.f, 0.01f, this, tr("Q/Resonance 2")), m_gain2Model( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Gain 2" ) ) { m_filter1Model.addItem( tr( "Low-pass" ), std::make_unique( "filter_lp" ) ); diff --git a/plugins/Eq/EqControls.cpp b/plugins/Eq/EqControls.cpp index 04fb9bd3a..ea5b2947f 100644 --- a/plugins/Eq/EqControls.cpp +++ b/plugins/Eq/EqControls.cpp @@ -37,30 +37,30 @@ namespace lmms EqControls::EqControls( EqEffect *effect ) : EffectControls( effect ), m_effect( effect ), - m_inGainModel( 0.0, -60.0, 20.0, 0.01, this, tr( "Input gain") ), - m_outGainModel( -.0, -60.0, 20.0, 0.01, this, tr( "Output gain" ) ), - m_lowShelfGainModel( 0.0 , -18, 18, 0.001, this, tr( "Low-shelf gain" ) ), - m_para1GainModel( 0.0 , -18, 18, 0.001, this, tr( "Peak 1 gain" ) ), - m_para2GainModel( 0.0 , -18, 18, 0.001, this, tr( "Peak 2 gain" ) ), - m_para3GainModel( 0.0 , -18, 18, 0.001, this, tr( "Peak 3 gain" ) ), - m_para4GainModel( 0.0 , -18, 18, 0.001, this, tr( "Peak 4 gain" ) ), - m_highShelfGainModel( 0.0 , -18, 18, 0.001, this, tr( "High-shelf gain" ) ), - m_hpResModel( 0.707,0.003, 10.0 , 0.001, this, tr( "HP res" ) ), - m_lowShelfResModel( 0.707, 0.55, 10.0 , 0.001, this , tr( "Low-shelf res" ) ), - m_para1BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 1 BW" ) ), - m_para2BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 2 BW" ) ), - m_para3BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 3 BW" ) ), - m_para4BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 4 BW" ) ), - m_highShelfResModel( 0.707, 0.55, 10.0 , 0.001, this , tr( "High-shelf res" ) ), - m_lpResModel( 0.707,0.003, 10.0 , 0.001, this , tr( "LP res" ) ), - m_hpFeqModel( 31.0, 20.0, 20000, 0.001, this , tr( "HP freq" ) ), - m_lowShelfFreqModel( 80.0, 20.0, 20000, 0.001, this , tr( "Low-shelf freq" ) ), - m_para1FreqModel( 120.0, 20.0, 20000, 0.001, this , tr( "Peak 1 freq" ) ), - m_para2FreqModel( 250.0, 20.0, 20000, 0.001, this, tr( "Peak 2 freq" ) ), - m_para3FreqModel( 2000.0, 20.0, 20000, 0.001, this , tr( "Peak 3 freq" ) ), - m_para4FreqModel( 4000.0, 20.0, 20000, 0.001, this , tr( "Peak 4 freq" ) ), - m_highShelfFreqModel( 12000.0, 20.0, 20000, 0.001, this , tr( "High-shelf freq" ) ), - m_lpFreqModel( 18000.0, 20.0, 20000, 0.001, this , tr( "LP freq" ) ), + m_inGainModel(0.f, -60.f, 20.f, 0.01f, this, tr("Input gain")), + m_outGainModel(-0.f, -60.f, 20.f, 0.01f, this, tr("Output gain")), + m_lowShelfGainModel( 0.f, -18, 18, 0.001f, this, tr("Low-shelf gain")), + m_para1GainModel(0.f, -18, 18, 0.001f, this, tr("Peak 1 gain")), + m_para2GainModel(0.f, -18, 18, 0.001f, this, tr("Peak 2 gain")), + m_para3GainModel(0.f, -18, 18, 0.001f, this, tr("Peak 3 gain")), + m_para4GainModel(0.f, -18, 18, 0.001f, this, tr("Peak 4 gain")), + m_highShelfGainModel(0.f, -18, 18, 0.001f, this, tr("High-shelf gain")), + m_hpResModel(0.707f,0.003f, 10.f, 0.001f, this, tr("HP res")), + m_lowShelfResModel(0.707f, 0.55f, 10.f, 0.001f, this, tr("Low-shelf res")), + m_para1BwModel(0.3f, 0.1f, 4, 0.001f, this, tr("Peak 1 BW")), + m_para2BwModel(0.3f, 0.1f, 4, 0.001f, this, tr("Peak 2 BW")), + m_para3BwModel(0.3f, 0.1f, 4, 0.001f, this, tr("Peak 3 BW")), + m_para4BwModel(0.3f, 0.1f, 4, 0.001f, this, tr("Peak 4 BW")), + m_highShelfResModel(0.707f, 0.55f, 10.f, 0.001f, this, tr("High-shelf res")), + m_lpResModel(0.707f,0.003f, 10.f, 0.001f, this, tr("LP res")), + m_hpFeqModel(31.f, 20.f, 20000, 0.001f, this, tr("HP freq")), + m_lowShelfFreqModel(80.f, 20.f, 20000, 0.001f, this, tr("Low-shelf freq")), + m_para1FreqModel(120.f, 20.f, 20000, 0.001f, this, tr("Peak 1 freq")), + m_para2FreqModel(250.f, 20.f, 20000, 0.001f, this, tr("Peak 2 freq")), + m_para3FreqModel(2000.f, 20.f, 20000, 0.001f, this, tr("Peak 3 freq")), + m_para4FreqModel(4000.f, 20.f, 20000, 0.001f, this, tr("Peak 4 freq")), + m_highShelfFreqModel(12000.f, 20.f, 20000, 0.001f, this, tr("High-shelf freq")), + m_lpFreqModel(18000.f, 20.f, 20000, 0.001f, this, tr("LP freq")), m_hpActiveModel( false, this , tr( "HP active" ) ), m_lowShelfActiveModel( false, this , tr( "Low-shelf active" ) ), m_para1ActiveModel( false, this , tr( "Peak 1 active" ) ), diff --git a/plugins/Eq/EqCurve.cpp b/plugins/Eq/EqCurve.cpp index e1d28ca0a..fcf78609b 100644 --- a/plugins/Eq/EqCurve.cpp +++ b/plugins/Eq/EqCurve.cpp @@ -581,17 +581,8 @@ void EqHandle::wheelEvent( QGraphicsSceneWheelEvent *wevent ) if( wevent->orientation() == Qt::Vertical ) { - m_resonance = m_resonance + ( numSteps ); + m_resonance = std::clamp(m_resonance + numSteps, 0.1f, highestBandwich); - if( m_resonance < 0.1 ) - { - m_resonance = 0.1; - } - - if( m_resonance > highestBandwich ) - { - m_resonance = highestBandwich; - } emit positionChanged(); } wevent->accept(); diff --git a/plugins/Eq/EqFader.h b/plugins/Eq/EqFader.h index d8897af5c..3185d0879 100644 --- a/plugins/Eq/EqFader.h +++ b/plugins/Eq/EqFader.h @@ -67,7 +67,7 @@ private slots: { const float opl = getPeak_L(); const float opr = getPeak_R(); - const float fallOff = 1.07; + const float fallOff = 1.07f; if( *m_lPeak > opl ) { setPeak_L( *m_lPeak ); diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index f91b3ebc3..427fff796 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -49,10 +49,10 @@ EqAnalyser::EqAnalyser() : //initialize Blackman-Harris window, constants taken from //https://en.wikipedia.org/wiki/Window_function#A_list_of_window_functions - const float a0 = 0.35875; - const float a1 = 0.48829; - const float a2 = 0.14128; - const float a3 = 0.01168; + const float a0 = 0.35875f; + const float a1 = 0.48829f; + const float a2 = 0.14128f; + const float a3 = 0.01168f; for (int i = 0; i < FFT_BUFFER_SIZE; i++) { @@ -230,7 +230,7 @@ void EqSpectrumView::paintEvent(QPaintEvent *event) float *bands = m_analyser->m_bands; m_path.moveTo( 0, height() ); m_peakSum = 0; - const float fallOff = 1.07; + const float fallOff = 1.07f; for( int x = 0; x < MAX_BANDS; ++x, ++bands ) { float peak = *bands != 0. ? (fh * 2.0 / 3.0 * (20. * log10(*bands / energy) - LOWER_Y) / (-LOWER_Y)) : 0.; @@ -305,4 +305,4 @@ void EqSpectrumView::periodicalUpdate() } // namespace gui -} // namespace lmms \ No newline at end of file +} // namespace lmms diff --git a/plugins/Flanger/FlangerControls.cpp b/plugins/Flanger/FlangerControls.cpp index 5550cdfb7..c5606380c 100644 --- a/plugins/Flanger/FlangerControls.cpp +++ b/plugins/Flanger/FlangerControls.cpp @@ -36,12 +36,12 @@ namespace lmms FlangerControls::FlangerControls( FlangerEffect *effect ) : EffectControls ( effect ), m_effect ( effect ), - m_delayTimeModel(0.001, 0.0001, 0.050, 0.0001, this, tr( "Delay samples" ) ), - m_lfoFrequencyModel( 0.25, 0.01, 60, 0.0001, 60000.0, this, tr( "LFO frequency" ) ), - m_lfoAmountModel( 0.0, 0.0, 0.0025, 0.0001, this, tr( "Amount" ) ), - m_lfoPhaseModel( 90.0, 0.0, 360.0, 0.0001, this, tr( "Stereo phase" ) ), - m_feedbackModel( 0.0, -1.0, 1.0, 0.0001, this, tr( "Feedback" ) ), - m_whiteNoiseAmountModel( 0.0, 0.0, 0.05, 0.0001, this, tr( "Noise" ) ), + m_delayTimeModel(0.001f, 0.0001f, 0.050f, 0.0001f, this, tr("Delay samples")), + m_lfoFrequencyModel(0.25f, 0.01f, 60, 0.0001f, 60000.f, this, tr("LFO frequency")), + m_lfoAmountModel(0.f, 0.f, 0.0025f, 0.0001f, this, tr("Amount")), + m_lfoPhaseModel(90.f, 0.f, 360.f, 0.0001f, this, tr("Stereo phase")), + m_feedbackModel(0.f, -1.f, 1.f, 0.0001f, this, tr("Feedback")), + m_whiteNoiseAmountModel(0.f, 0.f, 0.05f, 0.0001f, this, tr("Noise")), m_invertFeedbackModel ( false, this, tr( "Invert" ) ) { diff --git a/plugins/Flanger/MonoDelay.cpp b/plugins/Flanger/MonoDelay.cpp index 3ec028968..269b77323 100644 --- a/plugins/Flanger/MonoDelay.cpp +++ b/plugins/Flanger/MonoDelay.cpp @@ -32,9 +32,9 @@ namespace lmms MonoDelay::MonoDelay( int maxTime , int sampleRate ) { m_buffer = 0; - m_maxTime = maxTime; + m_maxTime = static_cast(maxTime); m_maxLength = maxTime * sampleRate; - m_length = m_maxLength; + m_length = static_cast(m_maxLength); m_writeIndex = 0; m_feedback = 0.0f; @@ -57,7 +57,7 @@ MonoDelay::~MonoDelay() void MonoDelay::tick( sample_t* sample ) { m_writeIndex = ( m_writeIndex + 1 ) % ( int )m_maxLength; - int readIndex = m_writeIndex - m_length; + int readIndex = m_writeIndex - static_cast(m_length); if (readIndex < 0 ) { readIndex += m_maxLength; } float out = m_buffer[ readIndex ]; m_buffer[ m_writeIndex ] = *sample + ( out * m_feedback ); diff --git a/plugins/LOMM/LOMM.cpp b/plugins/LOMM/LOMM.cpp index bffcfb9cb..e24171cea 100644 --- a/plugins/LOMM/LOMM.cpp +++ b/plugins/LOMM/LOMM.cpp @@ -57,8 +57,8 @@ LOMMEffect::LOMMEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* m_hp2(m_sampleRate), m_ap(m_sampleRate), m_needsUpdate(true), - m_coeffPrecalc(-0.05), - m_crestTimeConst(0.999), + m_coeffPrecalc(-0.05f), + m_crestTimeConst(0.999f), m_lookWrite(0), m_lookBufLength(2) { @@ -111,7 +111,7 @@ bool LOMMEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) { m_lp1.setLowpass(m_lommControls.m_split1Model.value()); m_hp1.setHighpass(m_lommControls.m_split1Model.value()); - m_ap.calcFilterCoeffs(m_lommControls.m_split1Model.value(), 0.70710678118); + m_ap.calcFilterCoeffs(m_lommControls.m_split1Model.value(), 0.70710678118f); } if (m_needsUpdate || m_lommControls.m_split2Model.isValueChanged()) { diff --git a/plugins/LOMM/LOMM.h b/plugins/LOMM/LOMM.h index 196d0a09d..9e03dc343 100644 --- a/plugins/LOMM/LOMM.h +++ b/plugins/LOMM/LOMM.h @@ -35,7 +35,7 @@ namespace lmms { -constexpr inline float LOMM_MIN_FLOOR = 0.00012589;// -72 dBFS +constexpr inline float LOMM_MIN_FLOOR = 0.00012589f;// -72 dBFS constexpr inline float LOMM_MAX_LOOKAHEAD = 20.f; constexpr inline float LOMM_AUTO_TIME_ADJUST = 5.f; diff --git a/plugins/LOMM/LOMMControls.cpp b/plugins/LOMM/LOMMControls.cpp index d695cf483..3ede0ddf2 100644 --- a/plugins/LOMM/LOMMControls.cpp +++ b/plugins/LOMM/LOMMControls.cpp @@ -35,55 +35,55 @@ namespace lmms LOMMControls::LOMMControls(LOMMEffect* effect) : EffectControls(effect), m_effect(effect), - m_depthModel(0.4, 0, 1, 0.00001, this, tr("Depth")), - m_timeModel(1, 0, 10, 0.00001, this, tr("Time")), - m_inVolModel(0, -48, 48, 0.00001, this, tr("Input Volume")), - m_outVolModel(8, -48, 48, 0.00001, this, tr("Output Volume")), - m_upwardModel(1, 0, 2, 0.00001, this, tr("Upward Depth")), - m_downwardModel(1, 0, 2, 0.00001, this, tr("Downward Depth")), - m_split1Model(2500, 20, 20000, 0.01, this, tr("High/Mid Split")), - m_split2Model(88.3, 20, 20000, 0.01, this, tr("Mid/Low Split")), + m_depthModel(0.4f, 0, 1, 0.00001f, this, tr("Depth")), + m_timeModel(1, 0, 10, 0.00001f, this, tr("Time")), + m_inVolModel(0, -48, 48, 0.00001f, this, tr("Input Volume")), + m_outVolModel(8, -48, 48, 0.00001f, this, tr("Output Volume")), + m_upwardModel(1, 0, 2, 0.00001f, this, tr("Upward Depth")), + m_downwardModel(1, 0, 2, 0.00001f, this, tr("Downward Depth")), + m_split1Model(2500, 20, 20000, 0.01f, this, tr("High/Mid Split")), + m_split2Model(88.3f, 20, 20000, 0.01f, this, tr("Mid/Low Split")), m_split1EnabledModel(true, this, tr("Enable High/Mid Split")), m_split2EnabledModel(true, this, tr("Enable Mid/Low Split")), m_band1EnabledModel(true, this, tr("Enable High Band")), m_band2EnabledModel(true, this, tr("Enable Mid Band")), m_band3EnabledModel(true, this, tr("Enable Low Band")), - m_inHighModel(0, -48, 48, 0.00001, this, tr("High Input Volume")), - m_inMidModel(0, -48, 48, 0.00001, this, tr("Mid Input Volume")), - m_inLowModel(0, -48, 48, 0.00001, this, tr("Low Input Volume")), - m_outHighModel(4.6, -48, 48, 0.00001, this, tr("High Output Volume")), - m_outMidModel(0.0, -48, 48, 0.00001, this, tr("Mid Output Volume")), - m_outLowModel(4.6, -48, 48, 0.00001, this, tr("Low Output Volume")), - m_aThreshHModel(-30.3, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001, this, tr("Above Threshold High")), - m_aThreshMModel(-25.0, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001, this, tr("Above Threshold Mid")), - m_aThreshLModel(-28.6, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001, this, tr("Above Threshold Low")), - m_aRatioHModel(99.99, 1, 99.99, 0.01, this, tr("Above Ratio High")), - m_aRatioMModel(66.7, 1, 99.99, 0.01, this, tr("Above Ratio Mid")), - m_aRatioLModel(66.7, 1, 99.99, 0.01, this, tr("Above Ratio Low")), - m_bThreshHModel(-35.6, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001, this, tr("Below Threshold High")), - m_bThreshMModel(-36.6, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001, this, tr("Below Threshold Mid")), - m_bThreshLModel(-35.6, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001, this, tr("Below Threshold Low")), - m_bRatioHModel(4.17, 1, 99.99, 0.01, this, tr("Below Ratio High")), - m_bRatioMModel(4.17, 1, 99.99, 0.01, this, tr("Below Ratio Mid")), - m_bRatioLModel(4.17, 1, 99.99, 0.01, this, tr("Below Ratio Low")), - m_atkHModel(13.5, 0, 1000, 0.001, this, tr("Attack High")), - m_atkMModel(22.4, 0, 1000, 0.001, this, tr("Attack Mid")), - m_atkLModel(47.8, 0, 1000, 0.001, this, tr("Attack Low")), - m_relHModel(132, 0, 1000, 0.001, this, tr("Release High")), - m_relMModel(282, 0, 1000, 0.001, this, tr("Release Mid")), - m_relLModel(282, 0, 1000, 0.001, this, tr("Release Low")), - m_rmsTimeModel(10, 0, 500, 0.001, this, tr("RMS Time")), - m_kneeModel(6, 0, 36, 0.00001, this, tr("Knee")), - m_rangeModel(36, 0, 96, 0.00001, this, tr("Range")), - m_balanceModel(0, -18, 18, 0.00001, this, tr("Balance")), + m_inHighModel(0, -48, 48, 0.00001f, this, tr("High Input Volume")), + m_inMidModel(0, -48, 48, 0.00001f, this, tr("Mid Input Volume")), + m_inLowModel(0, -48, 48, 0.00001f, this, tr("Low Input Volume")), + m_outHighModel(4.6f, -48, 48, 0.00001f, this, tr("High Output Volume")), + m_outMidModel(0.f, -48, 48, 0.00001f, this, tr("Mid Output Volume")), + m_outLowModel(4.6f, -48, 48, 0.00001f, this, tr("Low Output Volume")), + m_aThreshHModel(-30.3f, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001f, this, tr("Above Threshold High")), + m_aThreshMModel(-25.f, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001f, this, tr("Above Threshold Mid")), + m_aThreshLModel(-28.6f, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001f, this, tr("Above Threshold Low")), + m_aRatioHModel(99.99f, 1, 99.99f, 0.01f, this, tr("Above Ratio High")), + m_aRatioMModel(66.7f, 1, 99.99f, 0.01f, this, tr("Above Ratio Mid")), + m_aRatioLModel(66.7f, 1, 99.99f, 0.01f, this, tr("Above Ratio Low")), + m_bThreshHModel(-35.6f, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001f, this, tr("Below Threshold High")), + m_bThreshMModel(-36.6f, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001f, this, tr("Below Threshold Mid")), + m_bThreshLModel(-35.6f, LOMM_DISPLAY_MIN, LOMM_DISPLAY_MAX, 0.001f, this, tr("Below Threshold Low")), + m_bRatioHModel(4.17f, 1, 99.99f, 0.01f, this, tr("Below Ratio High")), + m_bRatioMModel(4.17f, 1, 99.99f, 0.01f, this, tr("Below Ratio Mid")), + m_bRatioLModel(4.17f, 1, 99.99f, 0.01f, this, tr("Below Ratio Low")), + m_atkHModel(13.5f, 0, 1000, 0.001f, this, tr("Attack High")), + m_atkMModel(22.4f, 0, 1000, 0.001f, this, tr("Attack Mid")), + m_atkLModel(47.8f, 0, 1000, 0.001f, this, tr("Attack Low")), + m_relHModel(132, 0, 1000, 0.001f, this, tr("Release High")), + m_relMModel(282, 0, 1000, 0.001f, this, tr("Release Mid")), + m_relLModel(282, 0, 1000, 0.001f, this, tr("Release Low")), + m_rmsTimeModel(10, 0, 500, 0.001f, this, tr("RMS Time")), + m_kneeModel(6, 0, 36, 0.00001f, this, tr("Knee")), + m_rangeModel(36, 0, 96, 0.00001f, this, tr("Range")), + m_balanceModel(0, -18, 18, 0.00001f, this, tr("Balance")), m_depthScalingModel(true, this, tr("Scale output volume with Depth")), m_stereoLinkModel(false, this, tr("Stereo Link")), - m_autoTimeModel(0, 0, 1, 0.00001, this, tr("Auto Time")), - m_mixModel(1, 0, 1, 0.00001, this, tr("Mix")), + m_autoTimeModel(0, 0, 1, 0.00001f, this, tr("Auto Time")), + m_mixModel(1, 0, 1, 0.00001f, this, tr("Mix")), m_feedbackModel(false, this, tr("Feedback")), m_midsideModel(false, this, tr("Mid/Side")), m_lookaheadEnableModel(false, this, tr("Lookahead")), - m_lookaheadModel(0.f, 0.f, LOMM_MAX_LOOKAHEAD, 0.01, this, tr("Lookahead Length")), + m_lookaheadModel(0.f, 0.f, LOMM_MAX_LOOKAHEAD, 0.01f, this, tr("Lookahead Length")), m_lowSideUpwardSuppressModel(false, this, tr("Suppress upward compression for side band")) { auto models = {&m_timeModel, &m_inVolModel, &m_outVolModel, &m_inHighModel, &m_inMidModel, diff --git a/plugins/Lb302/Lb302.cpp b/plugins/Lb302/Lb302.cpp index 5dfbd5992..17c9b7424 100644 --- a/plugins/Lb302/Lb302.cpp +++ b/plugins/Lb302/Lb302.cpp @@ -209,7 +209,7 @@ Lb302Filter3Pole::Lb302Filter3Pole(Lb302FilterKnobState *p_fs) : void Lb302Filter3Pole::recalc() { // DO NOT CALL BASE CLASS - vcf_e0 = 0.000001; + vcf_e0 = 0.000001f; vcf_e1 = 1.0; } @@ -291,7 +291,7 @@ Lb302Synth::Lb302Synth( InstrumentTrack * _instrumentTrack ) : accentToggle( false, this, tr( "Accent" ) ), deadToggle( false, this, tr( "Dead" ) ), db24Toggle( false, this, tr( "24dB/oct Filter" ) ), - vca_attack(1.0 - 0.96406088), + vca_attack(1.f - 0.96406088f), vca_a0(0.5), vca_a(0.), vca_mode(VcaMode::NeverPlayed) diff --git a/plugins/Monstro/Monstro.cpp b/plugins/Monstro/Monstro.cpp index 469b2da21..4278b7cdb 100644 --- a/plugins/Monstro/Monstro.cpp +++ b/plugins/Monstro/Monstro.cpp @@ -865,31 +865,31 @@ inline sample_t MonstroSynth::calcSlope( int slope, sample_t s ) MonstroInstrument::MonstroInstrument( InstrumentTrack * _instrument_track ) : Instrument( _instrument_track, &monstro_plugin_descriptor ), - m_osc1Vol( 33.0, 0.0, 200.0, 0.1, this, tr( "Osc 1 volume" ) ), - m_osc1Pan( 0.0, -100.0, 100.0, 0.1, this, tr( "Osc 1 panning" ) ), + m_osc1Vol(33.f, 0.f, 200.f, 0.1f, this, tr("Osc 1 volume")), + m_osc1Pan(0.f, -100.f, 100.f, 0.1f, this, tr("Osc 1 panning")), m_osc1Crs( 0.0, -24.0, 24.0, 1.0, this, tr( "Osc 1 coarse detune" ) ), m_osc1Ftl( 0.0, -100.0, 100.0, 1.0, this, tr( "Osc 1 fine detune left" ) ), m_osc1Ftr( 0.0, -100.0, 100.0, 1.0, this, tr( "Osc 1 fine detune right" ) ), - m_osc1Spo( 0.0, -180.0, 180.0, 0.1, this, tr( "Osc 1 stereo phase offset" ) ), - m_osc1Pw( 50.0, PW_MIN, PW_MAX, 0.01, this, tr( "Osc 1 pulse width" ) ), + m_osc1Spo(0.f, -180.f, 180.f, 0.1f, this, tr("Osc 1 stereo phase offset")), + m_osc1Pw(50.f, PW_MIN, PW_MAX, 0.01f, this, tr("Osc 1 pulse width")), m_osc1SSR( false, this, tr( "Osc 1 sync send on rise" ) ), m_osc1SSF( false, this, tr( "Osc 1 sync send on fall" ) ), - m_osc2Vol( 33.0, 0.0, 200.0, 0.1, this, tr( "Osc 2 volume" ) ), - m_osc2Pan( 0.0, -100.0, 100.0, 0.1, this, tr( "Osc 2 panning" ) ), + m_osc2Vol(33.f, 0.f, 200.f, 0.1f, this, tr("Osc 2 volume")), + m_osc2Pan(0.f, -100.f, 100.f, 0.1f, this, tr("Osc 2 panning")), m_osc2Crs( 0.0, -24.0, 24.0, 1.0, this, tr( "Osc 2 coarse detune" ) ), m_osc2Ftl( 0.0, -100.0, 100.0, 1.0, this, tr( "Osc 2 fine detune left" ) ), m_osc2Ftr( 0.0, -100.0, 100.0, 1.0, this, tr( "Osc 2 fine detune right" ) ), - m_osc2Spo( 0.0, -180.0, 180.0, 0.1, this, tr( "Osc 2 stereo phase offset" ) ), + m_osc2Spo(0.f, -180.f, 180.f, 0.1f, this, tr("Osc 2 stereo phase offset")), m_osc2Wave( this, tr( "Osc 2 waveform" ) ), m_osc2SyncH( false, this, tr( "Osc 2 sync hard" ) ), m_osc2SyncR( false, this, tr( "Osc 2 sync reverse" ) ), - m_osc3Vol( 33.0, 0.0, 200.0, 0.1, this, tr( "Osc 3 volume" ) ), - m_osc3Pan( 0.0, -100.0, 100.0, 0.1, this, tr( "Osc 3 panning" ) ), + m_osc3Vol(33.f, 0.f, 200.f, 0.1f, this, tr("Osc 3 volume")), + m_osc3Pan(0.f, -100.f, 100.f, 0.1f, this, tr("Osc 3 panning")), m_osc3Crs( 0.0, -24.0, 24.0, 1.0, this, tr( "Osc 3 coarse detune" ) ), - m_osc3Spo( 0.0, -180.0, 180.0, 0.1, this, tr( "Osc 3 Stereo phase offset" ) ), - m_osc3Sub( 0.0, -100.0, 100.0, 0.1, this, tr( "Osc 3 sub-oscillator mix" ) ), + m_osc3Spo(0.f, -180.f, 180.f, 0.1f, this, tr("Osc 3 Stereo phase offset")), + m_osc3Sub(0.f, -100.f, 100.f, 0.1f, this, tr("Osc 3 sub-oscillator mix")), m_osc3Wave1( this, tr( "Osc 3 waveform 1" ) ), m_osc3Wave2( this, tr( "Osc 3 waveform 2" ) ), m_osc3SyncH( false, this, tr( "Osc 3 sync hard" ) ), @@ -897,13 +897,13 @@ MonstroInstrument::MonstroInstrument( InstrumentTrack * _instrument_track ) : m_lfo1Wave( this, tr( "LFO 1 waveform" ) ), m_lfo1Att( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "LFO 1 attack" ) ), - m_lfo1Rate( 1.0f, 0.1, 10000.0, 0.1, 10000.0f, this, tr( "LFO 1 rate" ) ), - m_lfo1Phs( 0.0, -180.0, 180.0, 0.1, this, tr( "LFO 1 phase" ) ), + m_lfo1Rate(1.0f, 0.1f, 10000.f, 0.1f, 10000.0f, this, tr("LFO 1 rate")), + m_lfo1Phs(0.f, -180.f, 180.f, 0.1f, this, tr("LFO 1 phase")), m_lfo2Wave( this, tr( "LFO 2 waveform" ) ), m_lfo2Att( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "LFO 2 attack" ) ), - m_lfo2Rate( 1.0f, 0.1, 10000.0, 0.1, 10000.0f, this, tr( "LFO 2 rate" ) ), - m_lfo2Phs( 0.0, -180.0, 180.0, 0.1, this, tr( "LFO 2 phase" ) ), + m_lfo2Rate(1.0f, 0.1f, 10000.f, 0.1f, 10000.0f, this, tr("LFO 2 rate")), + m_lfo2Phs(0.0, -180.f, 180.f, 0.1f, this, tr("LFO 2 phase")), m_env1Pre( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "Env 1 pre-delay" ) ), m_env1Att( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "Env 1 attack" ) ), diff --git a/plugins/Nes/Nes.h b/plugins/Nes/Nes.h index 39e0a6719..e65cb3b13 100644 --- a/plugins/Nes/Nes.h +++ b/plugins/Nes/Nes.h @@ -60,22 +60,22 @@ namespace lmms { -const float NES_SIMPLE_FILTER = 1.0 / 20.0; // simulate nes analog audio output +const float NES_SIMPLE_FILTER = 1.f / 20.f; // simulate nes analog audio output const float NFB = 895000.0f; const float NOISE_FREQS[16] = { NFB/5, NFB/9, NFB/17, NFB/33, NFB/65, NFB/97, NFB/129, NFB/161, NFB/193, NFB/255, NFB/381, NFB/509, NFB/763, NFB/1017, NFB/2035, NFB/4069 }; const uint16_t LFSR_INIT = 1; const float DUTY_CYCLE[4] = { 0.125, 0.25, 0.5, 0.75 }; -const float DITHER_AMP = 1.0 / 60.0; +const float DITHER_AMP = 1.f / 60.f; const float MIN_FREQ = 10.0; const int TRIANGLE_WAVETABLE[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; const float NES_DIST = 0.9f; // simulate the slight nonlinear distortion in nes audio output -const float NES_MIXING_12 = 1.0 / 20.0; -const float NES_MIXING_34 = 1.0 / 12.0; -const float NES_MIXING_ALL = 1.0 / ( NES_MIXING_12 + NES_MIXING_34 ); // constants to simulate the hardwired mixing values for nes channels +const float NES_MIXING_12 = 1.f / 20.f; +const float NES_MIXING_34 = 1.f / 12.f; +const float NES_MIXING_ALL = 1.f / (NES_MIXING_12 + NES_MIXING_34); // constants to simulate the hardwired mixing values for nes channels const int MIN_WLEN = 4; diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index 607d40883..3c6004477 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -770,15 +770,15 @@ void OpulenzInstrumentView::updateKnobHints() // Envelope times in ms: t[0] = 0, t[n] = ( 1<{ - 0.0, 0.2, 0.4, 0.9, 1.8, 3.7, 7.4, - 15.0, 30.0, 60.0, 120.0, 240.0, 480.0, - 950.0, 1900.0, 3800.0 + 0.f, 0.2f, 0.4f, 0.9f, 1.8f, 3.7f, 7.4f, + 15.f, 30.f, 60.f, 120.f, 240.f, 480.f, + 950.f, 1900.f, 3800.f }; const auto dr_times = std::array{ - 0.0, 1.2, 2.5, 5.0, 10.0, 20.0, 40.0, - 80.0, 160.0, 320.0, 640.0, 1300.0, 2600.0, - 5200.0, 10000.0, 20000.0 + 0.f, 1.2f, 2.5f, 5.f, 10.f, 20.f, 40.f, + 80.f, 160.f, 320.f, 640.f, 1300.f, 2600.f, + 5200.f, 10000.f, 20000.f }; const auto fmultipliers = std::array{ diff --git a/plugins/PeakControllerEffect/PeakControllerEffectControls.cpp b/plugins/PeakControllerEffect/PeakControllerEffectControls.cpp index 070c9fbb8..0060b535b 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffectControls.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffectControls.cpp @@ -38,14 +38,14 @@ PeakControllerEffectControls:: PeakControllerEffectControls( PeakControllerEffect * _eff ) : EffectControls( _eff ), m_effect( _eff ), - m_baseModel( 0.5, 0.0, 1.0, 0.001, this, tr( "Base value" ) ), - m_amountModel( 1.0, -1.0, 1.0, 0.005, this, tr( "Modulation amount" ) ), - m_attackModel( 0, 0, 0.999, 0.001, this, tr( "Attack" ) ), - m_decayModel( 0, 0, 0.999, 0.001, this, tr( "Release" ) ), - m_tresholdModel( 0, 0, 1.0, 0.001, this, tr( "Treshold" ) ), + m_baseModel(0.5f, 0.f, 1.f, 0.001f, this, tr("Base value")), + m_amountModel(1.f, -1.f, 1.f, 0.005f, this, tr("Modulation amount")), + m_attackModel(0, 0, 0.999f, 0.001f, this, tr("Attack")), + m_decayModel(0, 0, 0.999f, 0.001f, this, tr("Release")), + m_tresholdModel(0, 0, 1.f, 0.001f, this, tr("Treshold")), m_muteModel( false, this, tr( "Mute output" ) ), m_absModel( true, this, tr("Absolute value") ), - m_amountMultModel( 1.0, 0, 32, 0.2, this, tr("Amount multiplicator") ) + m_amountMultModel(1.f, 0, 32, 0.2f, this, tr("Amount multiplicator")) { } diff --git a/plugins/ReverbSC/dcblock.c b/plugins/ReverbSC/dcblock.c index f38bb73dc..2c8d86950 100644 --- a/plugins/ReverbSC/dcblock.c +++ b/plugins/ReverbSC/dcblock.c @@ -33,7 +33,7 @@ int sp_dcblock_init(sp_data *sp, sp_dcblock *p, int oversampling ) p->inputs = 0.0; p->gain = pow( 0.99, 1.0f / oversampling ); if (p->gain == 0.0 || p->gain>=1.0 || p->gain<=-1.0) - p->gain = 0.99; + p->gain = 0.99f; return SP_OK; } diff --git a/plugins/ReverbSC/revsc.c b/plugins/ReverbSC/revsc.c index d9808963f..54db9a4db 100644 --- a/plugins/ReverbSC/revsc.c +++ b/plugins/ReverbSC/revsc.c @@ -16,7 +16,7 @@ #include "base.h" #include "revsc.h" -#define DEFAULT_SRATE 44100.0 +#define DEFAULT_SRATE 44100.f #define MIN_SRATE 5000.0 #define MAX_SRATE 1000000.0 #define MAX_PITCHMOD 20.0 @@ -34,20 +34,20 @@ /* reverbParams[n][3] = random seed (0 - 32767) */ static const SPFLOAT reverbParams[8][4] = { - { (2473.0 / DEFAULT_SRATE), 0.0010, 3.100, 1966.0 }, - { (2767.0 / DEFAULT_SRATE), 0.0011, 3.500, 29491.0 }, - { (3217.0 / DEFAULT_SRATE), 0.0017, 1.110, 22937.0 }, - { (3557.0 / DEFAULT_SRATE), 0.0006, 3.973, 9830.0 }, - { (3907.0 / DEFAULT_SRATE), 0.0010, 2.341, 20643.0 }, - { (4127.0 / DEFAULT_SRATE), 0.0011, 1.897, 22937.0 }, - { (2143.0 / DEFAULT_SRATE), 0.0017, 0.891, 29491.0 }, - { (1933.0 / DEFAULT_SRATE), 0.0006, 3.221, 14417.0 } + { (2473.f / DEFAULT_SRATE), 0.0010f, 3.100f, 1966.f }, + { (2767.f / DEFAULT_SRATE), 0.0011f, 3.500f, 29491.f }, + { (3217.f / DEFAULT_SRATE), 0.0017f, 1.110f, 22937.f }, + { (3557.f / DEFAULT_SRATE), 0.0006f, 3.973f, 9830.f }, + { (3907.f / DEFAULT_SRATE), 0.0010f, 2.341f, 20643.f }, + { (4127.f / DEFAULT_SRATE), 0.0011f, 1.897f, 22937.f }, + { (2143.f / DEFAULT_SRATE), 0.0017f, 0.891f, 29491.f }, + { (1933.f / DEFAULT_SRATE), 0.0006f, 3.221f, 14417.f } }; static int delay_line_max_samples(SPFLOAT sr, SPFLOAT iPitchMod, int n); static int init_delay_line(sp_revsc *p, sp_revsc_dl *lp, int n); static int delay_line_bytes_alloc(SPFLOAT sr, SPFLOAT iPitchMod, int n); -static const SPFLOAT outputGain = 0.35; +static const SPFLOAT outputGain = 0.35f; static const SPFLOAT jpScale = 0.25; int sp_revsc_create(sp_revsc **p){ *p = malloc(sizeof(sp_revsc)); @@ -56,9 +56,9 @@ int sp_revsc_create(sp_revsc **p){ int sp_revsc_init(sp_data *sp, sp_revsc *p) { - p->iSampleRate = sp->sr; - p->sampleRate = sp->sr; - p->feedback = 0.97; + p->iSampleRate = (float) sp->sr; + p->sampleRate = (float) sp->sr; + p->feedback = 0.97f; p->lpfreq = 10000; p->iPitchMod = 1; p->iSkipInit = 0; @@ -67,14 +67,14 @@ int sp_revsc_init(sp_data *sp, sp_revsc *p) p->initDone = 1; int i, nBytes = 0; for(i = 0; i < 8; i++){ - nBytes += delay_line_bytes_alloc(sp->sr, 1, i); + nBytes += delay_line_bytes_alloc((float) sp->sr, 1, i); } sp_auxdata_alloc(&p->aux, nBytes); nBytes = 0; for (i = 0; i < 8; i++) { p->delayLines[i].buf = (SPFLOAT*) (((char*) p->aux.ptr) + nBytes); init_delay_line(p, &p->delayLines[i], i); - nBytes += delay_line_bytes_alloc(sp->sr, 1, i); + nBytes += delay_line_bytes_alloc((float) sp->sr, 1, i); } return SP_OK; @@ -217,7 +217,7 @@ int sp_revsc_compute(sp_data *sp, sp_revsc *p, SPFLOAT *in1, SPFLOAT *in2, SPFLO /* calculate interpolation coefficients */ - a2 = frac * frac; a2 -= 1.0; a2 *= (1.0 / 6.0); + a2 = frac * frac; a2 -= 1.0; a2 *= (1.f / 6.f); a1 = frac; a1 += 1.0; a1 *= 0.5; am1 = a1 - 1.0; a0 = 3.0 * a2; a1 -= a0; am1 -= a2; a0 -= frac; diff --git a/plugins/Sf2Player/Sf2Player.cpp b/plugins/Sf2Player/Sf2Player.cpp index dd544dcf4..c2a9eca98 100644 --- a/plugins/Sf2Player/Sf2Player.cpp +++ b/plugins/Sf2Player/Sf2Player.cpp @@ -136,14 +136,14 @@ Sf2Instrument::Sf2Instrument( InstrumentTrack * _instrument_track ) : m_gain( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Gain" ) ), m_reverbOn( false, this, tr( "Reverb" ) ), m_reverbRoomSize( FLUID_REVERB_DEFAULT_ROOMSIZE, 0, 1.0, 0.01f, this, tr( "Reverb room size" ) ), - m_reverbDamping( FLUID_REVERB_DEFAULT_DAMP, 0, 1.0, 0.01, this, tr( "Reverb damping" ) ), + m_reverbDamping(FLUID_REVERB_DEFAULT_DAMP, 0, 1.f, 0.01f, this, tr("Reverb damping")), m_reverbWidth( FLUID_REVERB_DEFAULT_WIDTH, 0, 1.0, 0.01f, this, tr( "Reverb width" ) ), m_reverbLevel( FLUID_REVERB_DEFAULT_LEVEL, 0, 1.0, 0.01f, this, tr( "Reverb level" ) ), m_chorusOn( false, this, tr( "Chorus" ) ), m_chorusNum( FLUID_CHORUS_DEFAULT_N, 0, 10.0, 1.0, this, tr( "Chorus voices" ) ), - m_chorusLevel( FLUID_CHORUS_DEFAULT_LEVEL, 0, 10.0, 0.01, this, tr( "Chorus level" ) ), - m_chorusSpeed( FLUID_CHORUS_DEFAULT_SPEED, 0.29, 5.0, 0.01, this, tr( "Chorus speed" ) ), - m_chorusDepth( FLUID_CHORUS_DEFAULT_DEPTH, 0, 46.0, 0.05, this, tr( "Chorus depth" ) ) + m_chorusLevel(FLUID_CHORUS_DEFAULT_LEVEL, 0, 10.f, 0.01f, this, tr("Chorus level")), + m_chorusSpeed(FLUID_CHORUS_DEFAULT_SPEED, 0.29f, 5.f, 0.01f, this, tr("Chorus speed")), + m_chorusDepth(FLUID_CHORUS_DEFAULT_DEPTH, 0, 46.f, 0.05f, this, tr("Chorus depth")) { diff --git a/plugins/Sfxr/Sfxr.h b/plugins/Sfxr/Sfxr.h index 8af8984c9..1340cee5e 100644 --- a/plugins/Sfxr/Sfxr.h +++ b/plugins/Sfxr/Sfxr.h @@ -135,7 +135,7 @@ class SfxrZeroToOneFloatModel : public FloatModel { public: SfxrZeroToOneFloatModel( float val, Model * parent, const QString& displayName ): - FloatModel( val, 0.0, 1.0, 0.001, parent, displayName ) + FloatModel(val, 0.f, 1.f, 0.001f, parent, displayName) { } /* purpose: prevent the initial value of the model from being changed */ @@ -156,7 +156,7 @@ class SfxrNegPosOneFloatModel : public FloatModel { public: SfxrNegPosOneFloatModel(float val, Model * parent, const QString& displayName ): - FloatModel( val, -1.0, 1.0, 0.001, parent, displayName ) + FloatModel(val, -1.f, 1.f, 0.001f, parent, displayName) { } /* purpose: prevent the initial value of the model from being changed */ diff --git a/plugins/SlicerT/SlicerT.cpp b/plugins/SlicerT/SlicerT.cpp index 493dde6c3..d01cdfc36 100644 --- a/plugins/SlicerT/SlicerT.cpp +++ b/plugins/SlicerT/SlicerT.cpp @@ -197,7 +197,7 @@ void SlicerT::findSlices() int lastPoint = -minDist - 1; // to always store 0 first float spectralFlux = 0; - float prevFlux = 1E-10; // small value, no divison by zero + float prevFlux = 1E-10f; // small value, no divison by zero for (int i = 0; i < singleChannel.size() - windowSize; i += windowSize) { @@ -227,7 +227,7 @@ void SlicerT::findSlices() } prevFlux = spectralFlux; - spectralFlux = 1E-10; // again for no divison by zero + spectralFlux = 1E-10f; // again for no divison by zero } m_slicePoints.push_back(m_originalSample.sampleSize()); diff --git a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp index 7f73ed7cc..452e1e90f 100644 --- a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp +++ b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp @@ -742,7 +742,7 @@ std::vector> SaSpectrumView::makeLogAmpTics(int lo // Generate n dB increments, start checking at -90 dB. Limits are tweaked // just a little bit to make sure float comparisons do not miss edges. - for (float i = 0.000000001; 10 * log10(i) <= (high + 0.001); i *= increment) + for (float i = 0.000000001f; 10 * log10(i) <= (high + 0.001); i *= increment) { if (10 * log10(i) >= (low - 0.001)) { diff --git a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp index 024c3aea4..5169a4b49 100644 --- a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp +++ b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp @@ -218,8 +218,7 @@ std::vector> SaWaterfallView::makeTimeTics() float limit = yPixelToTime(m_displayBottom, m_displayHeight); // set increment to about 30 pixels (but min. 0.1 s) - float increment = std::round(10 * limit / (m_displayHeight / 30)) / 10; - if (increment < 0.1) {increment = 0.1;} + const float increment = std::max(std::round(10 * limit / (m_displayHeight / 30)) / 10, 0.1f); // NOTE: labels positions are rounded to match the (rounded) label value for (float i = 0; i <= limit; i += increment) diff --git a/plugins/Stk/Mallets/Mallets.cpp b/plugins/Stk/Mallets/Mallets.cpp index 7f4548ba4..4a3068d1c 100644 --- a/plugins/Stk/Mallets/Mallets.cpp +++ b/plugins/Stk/Mallets/Mallets.cpp @@ -114,7 +114,7 @@ MalletsInstrument::MalletsInstrument( InstrumentTrack * _instrument_track ): // TubeBell m_presetsModel.addItem( tr( "Tubular bells" ) ); - m_scalers.append( 1.8 ); + m_scalers.append(1.8f); // BandedWG m_presetsModel.addItem( tr( "Uniform bar" ) ); diff --git a/src/common/SharedMemory.cpp b/src/common/SharedMemory.cpp index 470016530..19d3dba1b 100644 --- a/src/common/SharedMemory.cpp +++ b/src/common/SharedMemory.cpp @@ -132,9 +132,10 @@ private: namespace { -auto sizeToHighAndLow(std::size_t size) -> std::pair +template +auto sizeToHighAndLow(T size) -> std::pair { - if constexpr(sizeof(std::size_t) <= sizeof(DWORD)) { + if constexpr (sizeof(T) <= sizeof(DWORD)) { return {0, size}; } else { return {static_cast(size >> 32), static_cast(size)}; diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index 0e4271822..dc496fa04 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -189,7 +189,7 @@ const AutomatableModel * AutomationClip::firstObject() const return model; } - static FloatModel fm(0, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, 0.001); + static FloatModel fm(0, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, 0.001f); return &fm; } diff --git a/src/core/EnvelopeAndLfoParameters.cpp b/src/core/EnvelopeAndLfoParameters.cpp index 861a62b51..9c0a4596a 100644 --- a/src/core/EnvelopeAndLfoParameters.cpp +++ b/src/core/EnvelopeAndLfoParameters.cpp @@ -97,13 +97,13 @@ EnvelopeAndLfoParameters::EnvelopeAndLfoParameters( Model * _parent ) : Model( _parent ), m_used( false ), - m_predelayModel( 0.0, 0.0, 2.0, 0.001, this, tr( "Env pre-delay" ) ), - m_attackModel( 0.0, 0.0, 2.0, 0.001, this, tr( "Env attack" ) ), - m_holdModel( 0.5, 0.0, 2.0, 0.001, this, tr( "Env hold" ) ), - m_decayModel( 0.5, 0.0, 2.0, 0.001, this, tr( "Env decay" ) ), - m_sustainModel( 0.5, 0.0, 1.0, 0.001, this, tr( "Env sustain" ) ), - m_releaseModel( 0.1, 0.0, 2.0, 0.001, this, tr( "Env release" ) ), - m_amountModel( 0.0, -1.0, 1.0, 0.005, this, tr( "Env mod amount" ) ), + m_predelayModel(0.f, 0.f, 2.f, 0.001f, this, tr("Env pre-delay")), + m_attackModel(0.f, 0.f, 2.f, 0.001f, this, tr("Env attack")), + m_holdModel(0.5f, 0.f, 2.f, 0.001f, this, tr("Env hold")), + m_decayModel(0.5f, 0.f, 2.f, 0.001f, this, tr("Env decay")), + m_sustainModel(0.5f, 0.f, 1.f, 0.001f, this, tr("Env sustain")), + m_releaseModel(0.1f, 0.f, 2.f, 0.001f, this, tr("Env release")), + m_amountModel(0.f, -1.f, 1.f, 0.005f, this, tr("Env mod amount")), m_valueForZeroAmount( _value_for_zero_amount ), m_pahdFrames( 0 ), m_rFrames( 0 ), @@ -111,12 +111,12 @@ EnvelopeAndLfoParameters::EnvelopeAndLfoParameters( m_rEnv( nullptr ), m_pahdBufSize( 0 ), m_rBufSize( 0 ), - m_lfoPredelayModel( 0.0, 0.0, 1.0, 0.001, this, tr( "LFO pre-delay" ) ), - m_lfoAttackModel( 0.0, 0.0, 1.0, 0.001, this, tr( "LFO attack" ) ), - m_lfoSpeedModel( 0.1, 0.001, 1.0, 0.0001, - SECS_PER_LFO_OSCILLATION * 1000.0, this, - tr( "LFO frequency" ) ), - m_lfoAmountModel( 0.0, -1.0, 1.0, 0.005, this, tr( "LFO mod amount" ) ), + m_lfoPredelayModel(0.f, 0.f, 1.f, 0.001f, this, tr("LFO pre-delay")), + m_lfoAttackModel(0.f, 0.f, 1.f, 0.001f, this, tr("LFO attack")), + m_lfoSpeedModel(0.1f, 0.001f, 1.f, 0.0001f, + SECS_PER_LFO_OSCILLATION * 1000.f, this, + tr("LFO frequency")), + m_lfoAmountModel(0.f, -1.f, 1.f, 0.005f, this, tr("LFO mod amount")), m_lfoWaveModel( static_cast(LfoShape::SineWave), 0, NumLfoShapes, this, tr( "LFO wave shape" ) ), m_x100Model( false, this, tr( "LFO frequency x 100" ) ), m_controlEnvAmountModel( false, this, tr( "Modulate env amount" ) ), diff --git a/src/core/InstrumentSoundShaping.cpp b/src/core/InstrumentSoundShaping.cpp index 9a2185da1..a7e344a7a 100644 --- a/src/core/InstrumentSoundShaping.cpp +++ b/src/core/InstrumentSoundShaping.cpp @@ -64,7 +64,7 @@ InstrumentSoundShaping::InstrumentSoundShaping( m_filterEnabledModel( false, this ), m_filterModel( this, tr( "Filter type" ) ), m_filterCutModel( 14000.0, 1.0, 14000.0, 1.0, this, tr( "Cutoff frequency" ) ), - m_filterResModel( 0.5, BasicFilters<>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance" ) ) + m_filterResModel(0.5f, BasicFilters<>::minQ(), 10.f, 0.01f, this, tr("Q/Resonance")) { for( int i = 0; i < NumTargets; ++i ) { diff --git a/src/core/LfoController.cpp b/src/core/LfoController.cpp index 0c6d3d1ae..96ea71f7b 100644 --- a/src/core/LfoController.cpp +++ b/src/core/LfoController.cpp @@ -39,9 +39,9 @@ namespace lmms LfoController::LfoController( Model * _parent ) : Controller( ControllerType::Lfo, _parent, tr( "LFO Controller" ) ), - m_baseModel( 0.5, 0.0, 1.0, 0.001, this, tr( "Base value" ) ), - m_speedModel( 2.0, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Oscillator speed" ) ), - m_amountModel( 1.0, -1.0, 1.0, 0.005, this, tr( "Oscillator amount" ) ), + m_baseModel(0.5f, 0.f, 1.f, 0.001f, this, tr("Base value")), + m_speedModel(2.f, 0.01f, 20.f, 0.0001f, 20000.f, this, tr("Oscillator speed")), + m_amountModel(1.f, -1.f, 1.f, 0.005f, this, tr("Oscillator amount")), m_phaseModel( 0.0, 0.0, 360.0, 4.0, this, tr( "Oscillator phase" ) ), m_waveModel( static_cast(Oscillator::WaveShape::Sine), 0, Oscillator::NumWaveShapes, this, tr( "Oscillator waveform" ) ), diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 6dd2e3451..dd68b55d3 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -43,8 +43,8 @@ namespace lmms MixerRoute::MixerRoute( MixerChannel * from, MixerChannel * to, float amount ) : m_from( from ), m_to( to ), - m_amount( amount, 0, 1, 0.001, nullptr, - tr( "Amount to send from channel %1 to channel %2" ).arg( m_from->m_channelIndex ).arg( m_to->m_channelIndex ) ) + m_amount(amount, 0, 1, 0.001f, nullptr, + tr("Amount to send from channel %1 to channel %2").arg(m_from->m_channelIndex).arg(m_to->m_channelIndex)) { //qDebug( "created: %d to %d", m_from->m_channelIndex, m_to->m_channelIndex ); // create send amount model @@ -67,7 +67,7 @@ MixerChannel::MixerChannel( int idx, Model * _parent ) : m_buffer( new sampleFrame[Engine::audioEngine()->framesPerPeriod()] ), m_muteModel( false, _parent ), m_soloModel( false, _parent ), - m_volumeModel( 1.0, 0.0, 2.0, 0.001, _parent ), + m_volumeModel(1.f, 0.f, 2.f, 0.001f, _parent), m_name(), m_lock(), m_channelIndex( idx ), diff --git a/src/core/fft_helpers.cpp b/src/core/fft_helpers.cpp index 35906e8d3..c24310341 100644 --- a/src/core/fft_helpers.cpp +++ b/src/core/fft_helpers.cpp @@ -122,13 +122,13 @@ int precomputeWindow(float *window, unsigned int length, FFTWindow type, bool no gain = 1; return 0; case FFTWindow::BlackmanHarris: - a0 = 0.35875; - a1 = 0.48829; - a2 = 0.14128; - a3 = 0.01168; + a0 = 0.35875f; + a1 = 0.48829f; + a2 = 0.14128f; + a3 = 0.01168f; break; case FFTWindow::Hamming: - a0 = 0.54; + a0 = 0.54f; a1 = 1.0 - a0; a2 = 0; a3 = 0; @@ -204,11 +204,11 @@ int compressbands(const float *absspec_buffer, float *compressedband, int num_ol float j_min = (i * ratio) + bottom; - if (j_min < 0) {j_min = bottom;} + if (j_min < 0) { j_min = static_cast(bottom); } float j_max = j_min + ratio; - for (float j = (int)j_min; j <= j_max; j++) + for (float j = std::floor(j_min); j <= j_max; j++) { compressedband[i] += absspec_buffer[(int)j]; } diff --git a/src/core/lv2/Lv2UridMap.cpp b/src/core/lv2/Lv2UridMap.cpp index ecc28693f..4aa9d11b4 100644 --- a/src/core/lv2/Lv2UridMap.cpp +++ b/src/core/lv2/Lv2UridMap.cpp @@ -76,12 +76,12 @@ LV2_URID UridMap::map(const char *uri) if (itr == m_map.end()) { // 1 is the first free URID - std::size_t index = 1u + m_unMap.size(); + const auto index = static_cast(1u + m_unMap.size()); auto pr = m_map.emplace(std::move(uriStr), index); if (pr.second) { m_unMap.emplace_back(pr.first->first.c_str()); - result = static_cast(index); + result = index; } } else { result = itr->second; } diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 41042f524..a7ca07279 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -120,7 +120,7 @@ AutomationEditor::AutomationEditor() : //keeps the direction of the widget, undepended on the locale setLayoutDirection( Qt::LeftToRight ); - m_tensionModel = new FloatModel(1.0, 0.0, 1.0, 0.01); + m_tensionModel = new FloatModel(1.f, 0.f, 1.f, 0.01f); connect( m_tensionModel, SIGNAL(dataChanged()), this, SLOT(setTension())); @@ -2107,7 +2107,7 @@ AutomationEditorWindow::AutomationEditorWindow() : for( float const & zoomLevel : m_editor->m_zoomXLevels ) { - m_editor->m_zoomingXModel.addItem( QString( "%1\%" ).arg( zoomLevel * 100 ) ); + m_editor->m_zoomingXModel.addItem(QString("%1%").arg(zoomLevel * 100)); } m_editor->m_zoomingXModel.setValue( m_editor->m_zoomingXModel.findText( "100%" ) ); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 4723004e8..5811f956c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -314,7 +314,7 @@ PianoRoll::PianoRoll() : // setup zooming-stuff for( float const & zoomLevel : m_zoomLevels ) { - m_zoomingModel.addItem( QString( "%1\%" ).arg( zoomLevel * 100 ) ); + m_zoomingModel.addItem(QString("%1%").arg(zoomLevel * 100)); } m_zoomingModel.setValue( m_zoomingModel.findText( "100%" ) ); connect( &m_zoomingModel, SIGNAL(dataChanged()), @@ -323,7 +323,7 @@ PianoRoll::PianoRoll() : // zoom y for (float const & zoomLevel : m_zoomYLevels) { - m_zoomingYModel.addItem(QString( "%1\%" ).arg(zoomLevel * 100)); + m_zoomingYModel.addItem(QString("%1%").arg(zoomLevel * 100)); } m_zoomingYModel.setValue(m_zoomingYModel.findText("100%")); connect(&m_zoomingYModel, SIGNAL(dataChanged()), diff --git a/src/gui/modals/ControllerConnectionDialog.cpp b/src/gui/modals/ControllerConnectionDialog.cpp index 12e26d03c..c7bdd28b4 100644 --- a/src/gui/modals/ControllerConnectionDialog.cpp +++ b/src/gui/modals/ControllerConnectionDialog.cpp @@ -295,7 +295,7 @@ ControllerConnectionDialog::~ControllerConnectionDialog() void ControllerConnectionDialog::selectController() { // Midi - if( m_midiGroupBox->model()->value() > 0 ) + if (m_midiGroupBox->model()->value()) { if( m_midiControllerSpinBox->model()->value() > 0 ) { @@ -321,8 +321,7 @@ void ControllerConnectionDialog::selectController() // User else { - if( m_userGroupBox->model()->value() > 0 && - Engine::getSong()->controllers().size() ) + if (m_userGroupBox->model()->value() && Engine::getSong()->controllers().size()) { m_controller = Engine::getSong()->controllers().at( m_userController->model()->value() ); diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index 24b16bfe4..9a0da4db4 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -282,7 +282,7 @@ void Fader::paintEvent(QPaintEvent* ev) void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) { - std::function mapper = [this](float value) { return ampToDbfs(qMax(0.0001, value)); }; + std::function mapper = [this](float value) { return ampToDbfs(qMax(0.0001f, value)); }; if (linear) { @@ -376,7 +376,7 @@ void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) // is the minimum value and that all other values lie inbetween. Otherwise // there will be warnings when the gradient is defined. const float mappedClipStarts(mapper(dbfsToAmp(0.f))); - const float mappedWarnEnd(mapper(dbfsToAmp(-0.01))); + const float mappedWarnEnd(mapper(dbfsToAmp(-0.01f))); const float mappedWarnStart(mapper(dbfsToAmp(-6.f))); const float mappedOkEnd(mapper(dbfsToAmp(-12.f))); diff --git a/tests/src/core/ArrayVectorTest.cpp b/tests/src/core/ArrayVectorTest.cpp index 9e6ed40b8..40ce4d001 100644 --- a/tests/src/core/ArrayVectorTest.cpp +++ b/tests/src/core/ArrayVectorTest.cpp @@ -231,12 +231,14 @@ private slots: //// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81159 auto v = ArrayVector{1, 2, 3}; const auto oldValue = v; -#pragma GCC diagnostic push #if __GNUC__ >= 13 -# pragma GCC diagnostic ignored "-Wself-move" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wself-move" #endif v = std::move(v); -#pragma GCC diagnostic pop +#if __GNUC__ >= 13 +# pragma GCC diagnostic pop +#endif QCOMPARE(v, oldValue); } { From aaca5fbd0e6dd4b4457dd5996abd88b9ceedb9df Mon Sep 17 00:00:00 2001 From: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Date: Mon, 24 Jun 2024 21:22:19 +0530 Subject: [PATCH 15/31] Remove `MemoryHelper` (#7335) * remove memory helper and replace alignedMalloc with stl version * it's aligned_alloc * forgot about destructor * switch to unique pointers Co-authored-by: saker * compile fix --------- Co-authored-by: saker --- include/AudioEngine.h | 5 +-- include/MemoryHelper.h | 49 --------------------------- include/lmms_basics.h | 1 - src/core/AudioEngine.cpp | 22 +++++------- src/core/CMakeLists.txt | 1 - src/core/MemoryHelper.cpp | 70 --------------------------------------- 6 files changed, 11 insertions(+), 137 deletions(-) delete mode 100644 include/MemoryHelper.h delete mode 100644 src/core/MemoryHelper.cpp diff --git a/include/AudioEngine.h b/include/AudioEngine.h index e434b7f15..6aeb293c7 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -34,6 +34,7 @@ #include #include +#include #include #include "lmms_basics.h" @@ -380,8 +381,8 @@ private: int m_inputBufferRead; int m_inputBufferWrite; - surroundSampleFrame * m_outputBufferRead; - surroundSampleFrame * m_outputBufferWrite; + std::unique_ptr m_outputBufferRead; + std::unique_ptr m_outputBufferWrite; // worker thread stuff std::vector m_workers; diff --git a/include/MemoryHelper.h b/include/MemoryHelper.h deleted file mode 100644 index e709ffc8a..000000000 --- a/include/MemoryHelper.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2014 Simon Symeonidis - * Copyright (c) 2004-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program 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. - * - * This program 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 this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#ifndef LMMS_MEMORY_HELPER_H -#define LMMS_MEMORY_HELPER_H - -#include - -namespace lmms -{ - - -/** - * Helper class to alocate aligned memory and free it. - */ -class MemoryHelper { -public: - - static void* alignedMalloc( size_t ); - - static void alignedFree( void* ); - -private: -}; - - -} // namespace lmms - -#endif // LMMS_MEMORY_HELPER_H diff --git a/include/lmms_basics.h b/include/lmms_basics.h index b566fa781..5c7292ab0 100644 --- a/include/lmms_basics.h +++ b/include/lmms_basics.h @@ -128,7 +128,6 @@ constexpr char LADSPA_PATH_SEPERATOR = using sampleFrame = std::array; using surroundSampleFrame = std::array; -constexpr std::size_t LMMS_ALIGN_SIZE = 16; #define LMMS_STRINGIFY(s) LMMS_STR(s) diff --git a/src/core/AudioEngine.cpp b/src/core/AudioEngine.cpp index 31c4a3e5c..d4fd643ac 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -37,7 +37,6 @@ #include "NotePlayHandle.h" #include "ConfigManager.h" #include "SamplePlayHandle.h" -#include "MemoryHelper.h" // platform-specific audio-interface-classes #include "AudioAlsa.h" @@ -137,12 +136,9 @@ AudioEngine::AudioEngine( bool renderOnly ) : // now that framesPerPeriod is fixed initialize global BufferManager BufferManager::init( m_framesPerPeriod ); - int outputBufferSize = m_framesPerPeriod * sizeof(surroundSampleFrame); - m_outputBufferRead = static_cast(MemoryHelper::alignedMalloc(outputBufferSize)); - m_outputBufferWrite = static_cast(MemoryHelper::alignedMalloc(outputBufferSize)); + m_outputBufferRead = std::make_unique(m_framesPerPeriod); + m_outputBufferWrite = std::make_unique(m_framesPerPeriod); - BufferManager::clear(m_outputBufferRead, m_framesPerPeriod); - BufferManager::clear(m_outputBufferWrite, m_framesPerPeriod); for( int i = 0; i < m_numWorkers+1; ++i ) { @@ -181,8 +177,6 @@ AudioEngine::~AudioEngine() delete m_midiClient; delete m_audioDev; - MemoryHelper::alignedFree(m_outputBufferRead); - MemoryHelper::alignedFree(m_outputBufferWrite); for (const auto& input : m_inputBuffer) { @@ -421,11 +415,11 @@ void AudioEngine::renderStageMix() AudioEngineProfiler::Probe profilerProbe(m_profiler, AudioEngineProfiler::DetailType::Mixing); Mixer *mixer = Engine::mixer(); - mixer->masterMix(m_outputBufferWrite); + mixer->masterMix(m_outputBufferWrite.get()); - MixHelpers::multiply(m_outputBufferWrite, m_masterGain, m_framesPerPeriod); + MixHelpers::multiply(m_outputBufferWrite.get(), m_masterGain, m_framesPerPeriod); - emit nextAudioBuffer(m_outputBufferRead); + emit nextAudioBuffer(m_outputBufferRead.get()); // and trigger LFOs EnvelopeAndLfoParameters::instances()->trigger(); @@ -435,7 +429,7 @@ void AudioEngine::renderStageMix() -const surroundSampleFrame *AudioEngine::renderNextBuffer() +const surroundSampleFrame* AudioEngine::renderNextBuffer() { const auto lock = std::lock_guard{m_changeMutex}; @@ -450,7 +444,7 @@ const surroundSampleFrame *AudioEngine::renderNextBuffer() s_renderingThread = false; m_profiler.finishPeriod(outputSampleRate(), m_framesPerPeriod); - return m_outputBufferRead; + return m_outputBufferRead.get(); } @@ -463,7 +457,7 @@ void AudioEngine::swapBuffers() m_inputBufferFrames[m_inputBufferWrite] = 0; std::swap(m_outputBufferRead, m_outputBufferWrite); - BufferManager::clear(m_outputBufferWrite, m_framesPerPeriod); + std::fill_n(m_outputBufferWrite.get(), m_framesPerPeriod, surroundSampleFrame{}); } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9ebe2c355..3608d2848 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -39,7 +39,6 @@ set(LMMS_SRCS core/LfoController.cpp core/LinkedModelGroups.cpp core/LocklessAllocator.cpp - core/MemoryHelper.cpp core/MeterModel.cpp core/MicroTimer.cpp core/Microtuner.cpp diff --git a/src/core/MemoryHelper.cpp b/src/core/MemoryHelper.cpp deleted file mode 100644 index 8f990d57e..000000000 --- a/src/core/MemoryHelper.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2014 Simon Symeonidis - * Copyright (c) 2008-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program 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. - * - * This program 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 this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#include - -#include "lmms_basics.h" -#include "MemoryHelper.h" - -namespace lmms -{ - - -/** - * Allocate a number of bytes and return them. - * @param byteNum is the number of bytes - */ -void* MemoryHelper::alignedMalloc( size_t byteNum ) -{ - int align_mask = LMMS_ALIGN_SIZE - 1; - - char* ptr = static_cast(malloc(byteNum + LMMS_ALIGN_SIZE + sizeof(int))); - - if( ptr == nullptr ) return nullptr; - - char* ptr2 = ptr + sizeof(int); - char* aligned_ptr = ptr2 + (LMMS_ALIGN_SIZE - ((size_t)ptr2 & align_mask)); - - ptr2 = aligned_ptr - sizeof( int ); - *( ( int* ) ptr2 ) = ( int )( aligned_ptr - ptr ); - - return aligned_ptr; -} - - -/** - * Free an aligned buffer - * @param _buffer is the buffer to free - */ -void MemoryHelper::alignedFree( void* _buffer ) -{ - if( _buffer ) - { - int *ptr2 = static_cast( _buffer ) - 1; - _buffer = static_cast( _buffer ) - *ptr2; - free( _buffer ); - } -} - - -} // namespace lmms From 103614473864a8fcc0347c1aec7657fd3568780d Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:17:48 -0500 Subject: [PATCH 16/31] Fix uninitialized compressor values (#7343) --- plugins/Compressor/Compressor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/Compressor/Compressor.cpp b/plugins/Compressor/Compressor.cpp index 91cc61029..1c51d6ddc 100755 --- a/plugins/Compressor/Compressor.cpp +++ b/plugins/Compressor/Compressor.cpp @@ -590,6 +590,9 @@ void CompressorEffect::changeSampleRate() calcInGain(); calcTiltCoeffs(); calcMix(); + + calcAutoAttack(); + calcAutoRelease(); } From 6634cec127a2ad8365148269c542cecb90255148 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Wed, 26 Jun 2024 00:30:27 -0500 Subject: [PATCH 17/31] Add Granular Pitch Shifter effect (#7328) --- cmake/modules/PluginList.cmake | 1 + include/lmms_constants.h | 3 + plugins/GranularPitchShifter/CMakeLists.txt | 9 + .../GranularPitchShifterControlDialog.cpp | 158 ++++++++++ .../GranularPitchShifterControlDialog.h | 75 +++++ .../GranularPitchShifterControls.cpp | 149 +++++++++ .../GranularPitchShifterControls.h | 87 ++++++ .../GranularPitchShifterEffect.cpp | 289 ++++++++++++++++++ .../GranularPitchShifterEffect.h | 185 +++++++++++ plugins/GranularPitchShifter/artwork.png | Bin 0 -> 55110 bytes plugins/GranularPitchShifter/help_active.png | Bin 0 -> 5486 bytes .../GranularPitchShifter/help_inactive.png | Bin 0 -> 5448 bytes plugins/GranularPitchShifter/logo.png | Bin 0 -> 774 bytes .../GranularPitchShifter/prefilter_active.png | Bin 0 -> 805 bytes .../prefilter_inactive.png | Bin 0 -> 890 bytes 15 files changed, 956 insertions(+) create mode 100755 plugins/GranularPitchShifter/CMakeLists.txt create mode 100755 plugins/GranularPitchShifter/GranularPitchShifterControlDialog.cpp create mode 100755 plugins/GranularPitchShifter/GranularPitchShifterControlDialog.h create mode 100755 plugins/GranularPitchShifter/GranularPitchShifterControls.cpp create mode 100755 plugins/GranularPitchShifter/GranularPitchShifterControls.h create mode 100755 plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp create mode 100755 plugins/GranularPitchShifter/GranularPitchShifterEffect.h create mode 100755 plugins/GranularPitchShifter/artwork.png create mode 100755 plugins/GranularPitchShifter/help_active.png create mode 100644 plugins/GranularPitchShifter/help_inactive.png create mode 100755 plugins/GranularPitchShifter/logo.png create mode 100755 plugins/GranularPitchShifter/prefilter_active.png create mode 100755 plugins/GranularPitchShifter/prefilter_inactive.png diff --git a/cmake/modules/PluginList.cmake b/cmake/modules/PluginList.cmake index 8b26d4ed5..009679533 100644 --- a/cmake/modules/PluginList.cmake +++ b/cmake/modules/PluginList.cmake @@ -38,6 +38,7 @@ SET(LMMS_PLUGIN_LIST DynamicsProcessor Eq Flanger + GranularPitchShifter HydrogenImport LadspaBrowser LadspaEffect diff --git a/include/lmms_constants.h b/include/lmms_constants.h index c6452d6c6..0c2ee1753 100644 --- a/include/lmms_constants.h +++ b/include/lmms_constants.h @@ -36,6 +36,7 @@ constexpr long double LD_PI_R = 1.0 / LD_PI; constexpr long double LD_PI_SQR = LD_PI * LD_PI; constexpr long double LD_E = 2.71828182845904523536028747135266249775724709369995; constexpr long double LD_E_R = 1.0 / LD_E; +constexpr long double LD_SQRT_2 = 1.41421356237309504880168872420969807856967187537695; constexpr double D_PI = (double) LD_PI; constexpr double D_2PI = (double) LD_2PI; @@ -44,6 +45,7 @@ constexpr double D_PI_R = (double) LD_PI_R; constexpr double D_PI_SQR = (double) LD_PI_SQR; constexpr double D_E = (double) LD_E; constexpr double D_E_R = (double) LD_E_R; +constexpr double D_SQRT_2 = (double) LD_SQRT_2; constexpr float F_PI = (float) LD_PI; constexpr float F_2PI = (float) LD_2PI; @@ -52,6 +54,7 @@ constexpr float F_PI_R = (float) LD_PI_R; constexpr float F_PI_SQR = (float) LD_PI_SQR; constexpr float F_E = (float) LD_E; constexpr float F_E_R = (float) LD_E_R; +constexpr float F_SQRT_2 = (float) LD_SQRT_2; // Microtuner constexpr unsigned int MaxScaleCount = 10; //!< number of scales per project diff --git a/plugins/GranularPitchShifter/CMakeLists.txt b/plugins/GranularPitchShifter/CMakeLists.txt new file mode 100755 index 000000000..c8f70fc78 --- /dev/null +++ b/plugins/GranularPitchShifter/CMakeLists.txt @@ -0,0 +1,9 @@ +include(BuildPlugin) +build_plugin(granularpitchshifter + GranularPitchShifterEffect.cpp + GranularPitchShifterControls.cpp + GranularPitchShifterControlDialog.cpp + MOCFILES + GranularPitchShifterControls.h + GranularPitchShifterControlDialog.h + EMBEDDED_RESOURCES *.png) diff --git a/plugins/GranularPitchShifter/GranularPitchShifterControlDialog.cpp b/plugins/GranularPitchShifter/GranularPitchShifterControlDialog.cpp new file mode 100755 index 000000000..71a8d15f7 --- /dev/null +++ b/plugins/GranularPitchShifter/GranularPitchShifterControlDialog.cpp @@ -0,0 +1,158 @@ +/* + * GranularPitchShifterControlDialog.cpp + * + * Copyright (c) 2024 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "GranularPitchShifterControlDialog.h" +#include "GranularPitchShifterControls.h" +#include "embed.h" +#include "LcdFloatSpinBox.h" +#include "Knob.h" +#include "GuiApplication.h" +#include "gui_templates.h" +#include "PixmapButton.h" + + +namespace lmms::gui +{ + +GranularPitchShifterControlDialog::GranularPitchShifterControlDialog(GranularPitchShifterControls* controls) : + EffectControlDialog(controls) +{ + setAutoFillBackground(true); + QPalette pal; + pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); + setPalette(pal); + setFixedSize(305, 180); + + auto makeKnob = [this](KnobType style, int x, int y, const QString& hintText, const QString& unit, FloatModel* model) + { + Knob* newKnob = new Knob(style, this); + newKnob->move(x, y); + newKnob->setModel(model); + newKnob->setHintText(hintText, unit); + return newKnob; + }; + + makeKnob(KnobType::Bright26, 19, 78, tr("Grain Size:"), " Hz", &controls->m_sizeModel); + makeKnob(KnobType::Bright26, 116, 10, tr("Spray:"), " seconds", &controls->m_sprayModel); + makeKnob(KnobType::Bright26, 158, 10, tr("Jitter:"), " octaves", &controls->m_jitterModel); + makeKnob(KnobType::Bright26, 200, 10, tr("Twitch:"), " octaves", &controls->m_twitchModel); + makeKnob(KnobType::Bright26, 188, 60, tr("Spray Stereo Spread:"), "", &controls->m_spraySpreadModel); + makeKnob(KnobType::Bright26, 135, 110, tr("Grain Shape:"), "", &controls->m_shapeModel); + makeKnob(KnobType::Bright26, 188, 110, tr("Fade Length:"), "", &controls->m_fadeLengthModel); + makeKnob(KnobType::Bright26, 258, 45, tr("Feedback:"), "", &controls->m_feedbackModel); + makeKnob(KnobType::Bright26, 258, 92, tr("Minimum Allowed Latency:"), " seconds", &controls->m_minLatencyModel); + makeKnob(KnobType::Small17, 66, 157, tr("Density:"), "x", &controls->m_densityModel); + makeKnob(KnobType::Small17, 8, 157, tr("Glide:"), " seconds", &controls->m_glideModel); + + LcdFloatSpinBox* pitchBox = new LcdFloatSpinBox(3, 2, "11green", tr("Pitch"), this); + pitchBox->move(15, 41); + pitchBox->setModel(&controls->m_pitchModel); + pitchBox->setToolTip(tr("Pitch")); + pitchBox->setSeamless(true, true); + + LcdFloatSpinBox* pitchSpreadBox = new LcdFloatSpinBox(3, 2, "11green", tr("Pitch Stereo Spread"), this); + pitchSpreadBox->move(133, 66); + pitchSpreadBox->setModel(&controls->m_pitchSpreadModel); + pitchSpreadBox->setToolTip(tr("Pitch Stereo Spread")); + pitchSpreadBox->setSeamless(true, true); + + QPushButton button("Show Help", this); + connect(&button, &QPushButton::clicked, this, &GranularPitchShifterControlDialog::showHelpWindow); + + PixmapButton* m_helpBtn = new PixmapButton(this, nullptr); + m_helpBtn->move(278, 159); + m_helpBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("help_active")); + m_helpBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("help_inactive")); + m_helpBtn->setToolTip(tr("Open help window")); + connect(m_helpBtn, SIGNAL(clicked()), this, SLOT(showHelpWindow())); + + PixmapButton* prefilterButton = new PixmapButton(this, tr("Prefilter")); + prefilterButton->move(8, 133); + prefilterButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("prefilter_active")); + prefilterButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("prefilter_inactive")); + prefilterButton->setCheckable(true); + prefilterButton->setModel(&controls->m_prefilterModel); + prefilterButton->setToolTip(tr("Prefilter")); + + ComboBox* rangeBox = new ComboBox(this); + rangeBox->setGeometry(189, 155, 80, 22); + rangeBox->setModel(&controls->m_rangeModel); + controls->updateRange(); +} + +void GranularPitchShifterControlDialog::showHelpWindow() { + GranularPitchShifterHelpView::getInstance()->close(); + GranularPitchShifterHelpView::getInstance()->show(); +} + + +QString GranularPitchShifterHelpView::s_helpText= +"
" +"Granular Pitch Shifter

" +"Plugin by Lost Robot
" +"GUI by thismoon
" +"
" +"

Grain:

" +"Pitch - The amount of pitch shifting to perform, in 12EDO semitones.
" +"Size - The length of each grain, in Hz. By default, new grains will be created at double this rate.
In most cases, you'll want this to be set to higher frequencies when shifting the pitch upward, and vice-versa.
" +"

Random:

" +"Spray - The amount of randomization for the playback position of each grain, in seconds.
This does not change when the grain plays, but rather what audio the grain is pulling from.
For example, a value of 0.5 seconds will allow each grain to play back audio from up to half of a second ago.
It's oftentimes recommended to use at least a small amount of Spray, as this will break up the periodicity in the grains, which is usually the main artifact caused by a granular pitch shifter.
This will also make the grains uncorrelated with each other, guaranteeing that a grain Shape value of 2 will always be optimal.
" +"Jitter - The amount of randomization for the pitch of each grain, in octaves.
This does not impact how often grains are created.
" +"Twitch - The amount of randomization for how often new grains are created, in octaves.
Jitter and Twitch both use the same random numbers, so if they're at the same value, then the grain creation timings will be changed exactly proportionally to their change in pitch.
" +"

Stereo:

" +"Pitch - The total distance in pitch between both stereo channels, in 12EDO semitones.
Half of the amount of pitch shifting shown will be applied to the right channel, and the opposite to the left channel.
" +"Spray - The allowed distance between each channel's randomized position with the Spray feature in the Random category.
A value of 1 makes the Spray values in each channel entirely unlinked." +"

Shape:

" +"Shape - The shape of each grain's fades. In most cases, 2 is the optimal value, providing equal-power fades.
However, when the plugin is performing minimal pitch shifting and has most of its parameters at default, a value of 1 may be more optimal, providing equal-gain fades.
All fades are designed for 50% grain overlap.
" +"Fade - The length of the grain fades. A value of 1 provides the cleanest fades, causing those fades to reach across the entire grain.
Values below 1 make the fade artifacts more audible, but those fades will only apply to the outer edges of each grain.
A value of 0 will result in clicking sounds due to the fades no longer being present.
" +"

Delay:

" +"Feedback - The amount of feedback for the pitch shifter.
This feeds a portion of the pitch shifter output back into the input buffer. Large values can be dangerous.
" +"Latency - The minimum amount of latency the pitch shifter will have.
This granular pitch shifter dynamically changes its latency to be at the minimum possible amount depending on your settings.
If you'd like for this latency to be more predictable, you may increase the value of this parameter until the latency no longer changes.
This parameter may also be used to be set the minimum amount of delay for the feedback.
A larger latency amount can remove subtle fluttering artifacts that may result from automating the pitch shifting amount at high speeds." +"

Miscellaneous:

" +"Prefilter - Enables a 12 dB lowpass filter prior to the pitch shifting which automatically adjusts its cutoff to drastically reduce any resulting aliasing.
" +"Density - The multiplier for how often grains are spawned.
This will increase the grain overlap above 50%.
It will create painful piercing sounds if you don't make use of any of the knobs in the Random category.
Otherwise, you can get some interesting effects similar to unison or a stationary Paulstretch.
Note that this knob uses by far the most CPU out of any parameter in this plugin when increased.
" +"Glide - The length of interpolation for the amount of pitch shifting.
A small amount of glide is very effective for cleaning up many of the artifacts that may result from changing the pitch shift amount over time.
" +"Range - The length of the pitch shifter's internal ring buffer.
Changing this will change the minimum and maximum values for some of the other parameters, which are listed in each of the options.
Increase it if you need parameter values that aren't supported with the minimum buffer length. Otherwise, it's best to leave it at its minimum value.
" +; + +GranularPitchShifterHelpView::GranularPitchShifterHelpView():QTextEdit(s_helpText) +{ +#if (QT_VERSION < QT_VERSION_CHECK(5,12,0)) + // Bug workaround: https://codereview.qt-project.org/c/qt/qtbase/+/225348 + using ::operator|; +#endif + setWindowTitle("Granular Pitch Shifter Help"); + setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse); + getGUI()->mainWindow()->addWindowedWidget(this); + parentWidget()->setAttribute(Qt::WA_DeleteOnClose, false); + parentWidget()->setWindowIcon(PLUGIN_NAME::getIconPixmap("logo")); + + // No maximize button + Qt::WindowFlags flags = parentWidget()->windowFlags(); + flags &= ~Qt::WindowMaximizeButtonHint; + parentWidget()->setWindowFlags(flags); +} + + +} // namespace lmms::gui diff --git a/plugins/GranularPitchShifter/GranularPitchShifterControlDialog.h b/plugins/GranularPitchShifter/GranularPitchShifterControlDialog.h new file mode 100755 index 000000000..751106b2c --- /dev/null +++ b/plugins/GranularPitchShifter/GranularPitchShifterControlDialog.h @@ -0,0 +1,75 @@ +/* + * GranularPitchShifterControlDialog.h + * + * Copyright (c) 2024 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_GRANULAR_PITCH_SHIFTER_CONTROLS_H +#define LMMS_GRANULAR_PITCH_SHIFTER_CONTROLS_H + +#include "EffectControlDialog.h" + +#include +#include "ComboBox.h" +#include "GuiApplication.h" +#include "MainWindow.h" + +namespace lmms +{ + +class GranularPitchShifterControls; +class FloatModel; + +namespace gui +{ + +class Knob; + +class GranularPitchShifterControlDialog : public EffectControlDialog +{ + Q_OBJECT +public: + GranularPitchShifterControlDialog(GranularPitchShifterControls* controls); + ~GranularPitchShifterControlDialog() override = default; +public slots: + void showHelpWindow(); +}; + +class GranularPitchShifterHelpView : public QTextEdit +{ + Q_OBJECT +public: + static GranularPitchShifterHelpView* getInstance() + { + static GranularPitchShifterHelpView instance; + return &instance; + } + +private: + GranularPitchShifterHelpView(); + static QString s_helpText; +}; + +} // namespace gui + +} // namespace lmms + +#endif // LMMS_GRANULAR_PITCH_SHIFTER_CONTROLS_H diff --git a/plugins/GranularPitchShifter/GranularPitchShifterControls.cpp b/plugins/GranularPitchShifter/GranularPitchShifterControls.cpp new file mode 100755 index 000000000..86e9a0cfd --- /dev/null +++ b/plugins/GranularPitchShifter/GranularPitchShifterControls.cpp @@ -0,0 +1,149 @@ +/* + * GranularPitchShifterControls.cpp + * + * Copyright (c) 2024 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "GranularPitchShifterControls.h" +#include "GranularPitchShifterEffect.h" + +namespace lmms +{ + +GranularPitchShifterControls::GranularPitchShifterControls(GranularPitchShifterEffect* effect) : + EffectControls(effect), + m_effect(effect), + m_pitchModel(1.f, -48.f, 24.f, 0.01f, this, tr("Pitch")), + m_sizeModel(10.f, 2.f, 1000.f, 0.001f, this, tr("Grain Size")), + m_sprayModel(0.005f, 0.f, 0.5f, 0.0001f, this, tr("Spray")), + m_jitterModel(0.f, 0.f, 1.f, 0.0001f, this, tr("Jitter")), + m_twitchModel(0.f, 0.f, 1.f, 0.0001f, this, tr("Twitch")), + m_pitchSpreadModel(0.f, -24.f, 24.f, 0.01f, this, tr("Pitch Stereo Spread")), + m_spraySpreadModel(0.f, 0.f, 1.f, 0.0001f, this, tr("Spray Stereo")), + m_shapeModel(2.f, 1.f, 2.f, 0.0001f, this, tr("Shape")), + m_fadeLengthModel(1.f, 0.001f, 1.f, 0.00001f, this, tr("Fade Length")), + m_feedbackModel(0.f, 0.f, 1.f, 0.00001f, this, tr("Feedback")), + m_minLatencyModel(0.01f, 0.f, 1.f, 0.00001f, this, tr("Minimum Allowed Latency")), + m_prefilterModel(true, this, tr("Prefilter")), + m_densityModel(1.f, 1.f, 16.f, 0.0001f, this, tr("Density")), + m_glideModel(0.01f, 0.f, 1.f, 0.0001f, this, tr("Glide")), + m_rangeModel(this, tr("Ring Buffer Length")) +{ + m_sizeModel.setScaleLogarithmic(true); + m_sprayModel.setScaleLogarithmic(true); + m_spraySpreadModel.setScaleLogarithmic(true); + m_minLatencyModel.setScaleLogarithmic(true); + m_densityModel.setScaleLogarithmic(true); + m_glideModel.setScaleLogarithmic(true); + + m_rangeModel.addItem(tr("5 Seconds")); + m_rangeModel.addItem(tr("10 Seconds (Size)")); + m_rangeModel.addItem(tr("40 Seconds (Size and Pitch)")); + m_rangeModel.addItem(tr("40 Seconds (Size and Spray and Jitter)")); + m_rangeModel.addItem(tr("120 Seconds (All of the above)")); + + connect(&m_rangeModel, &ComboBoxModel::dataChanged, this, &GranularPitchShifterControls::updateRange); +} + +void GranularPitchShifterControls::updateRange() +{ + switch (m_rangeModel.value()) + { + case 0:// 5 seconds + m_sizeModel.setRange(4.f, 1000.f, 0.001f); + m_pitchModel.setRange(-48.f, 24.f, 0.01f); + m_sprayModel.setRange(0.f, 0.5f, 0.0001f); + m_jitterModel.setRange(0.f, 1.f, 0.0001f); + break; + case 1:// 10 seconds (size) + m_sizeModel.setRange(2.f, 1000.f, 0.001f); + m_pitchModel.setRange(-48.f, 24.f, 0.01f); + m_sprayModel.setRange(0.f, 0.5f, 0.0001f); + m_jitterModel.setRange(0.f, 1.f, 0.0001f); + break; + case 2:// 40 seconds (size and pitch) + m_sizeModel.setRange(2.f, 1000.f, 0.001f); + m_pitchModel.setRange(-48.f, 48.f, 0.01f); + m_sprayModel.setRange(0.f, 0.5f, 0.0001f); + m_jitterModel.setRange(0.f, 1.f, 0.0001f); + break; + case 3:// 40 seconds (size and spray and jitter) + m_sizeModel.setRange(2.f, 1000.f, 0.001f); + m_pitchModel.setRange(-48.f, 24.f, 0.01f); + m_sprayModel.setRange(0.f, 20.f, 0.0001f); + m_jitterModel.setRange(0.f, 2.f, 0.0001f); + break; + case 4:// 120 seconds (all of the above) + m_sizeModel.setRange(2.f, 1000.f, 0.001f); + m_pitchModel.setRange(-48.f, 48.f, 0.01f); + m_sprayModel.setRange(0.f, 40.f, 0.0001f); + m_jitterModel.setRange(0.f, 2.f, 0.0001f); + break; + default: + break; + } + m_effect->sampleRateNeedsUpdate(); +} + +void GranularPitchShifterControls::loadSettings(const QDomElement& parent) +{ + // must be loaded first so the ranges are set properly + m_rangeModel.loadSettings(parent, "range"); + + m_pitchModel.loadSettings(parent, "pitch"); + m_sizeModel.loadSettings(parent, "size"); + m_sprayModel.loadSettings(parent, "spray"); + m_jitterModel.loadSettings(parent, "jitter"); + m_twitchModel.loadSettings(parent, "twitch"); + m_pitchSpreadModel.loadSettings(parent, "pitchSpread"); + m_spraySpreadModel.loadSettings(parent, "spraySpread"); + m_shapeModel.loadSettings(parent, "shape"); + m_fadeLengthModel.loadSettings(parent, "fadeLength"); + m_feedbackModel.loadSettings(parent, "feedback"); + m_minLatencyModel.loadSettings(parent, "minLatency"); + m_prefilterModel.loadSettings(parent, "prefilter"); + m_densityModel.loadSettings(parent, "density"); + m_glideModel.loadSettings(parent, "glide"); +} + +void GranularPitchShifterControls::saveSettings(QDomDocument& doc, QDomElement& parent) +{ + m_rangeModel.saveSettings(doc, parent, "range"); + m_pitchModel.saveSettings(doc, parent, "pitch"); + m_sizeModel.saveSettings(doc, parent, "size"); + m_sprayModel.saveSettings(doc, parent, "spray"); + m_jitterModel.saveSettings(doc, parent, "jitter"); + m_twitchModel.saveSettings(doc, parent, "twitch"); + m_pitchSpreadModel.saveSettings(doc, parent, "pitchSpread"); + m_spraySpreadModel.saveSettings(doc, parent, "spraySpread"); + m_shapeModel.saveSettings(doc, parent, "shape"); + m_fadeLengthModel.saveSettings(doc, parent, "fadeLength"); + m_feedbackModel.saveSettings(doc, parent, "feedback"); + m_minLatencyModel.saveSettings(doc, parent, "minLatency"); + m_prefilterModel.saveSettings(doc, parent, "prefilter"); + m_densityModel.saveSettings(doc, parent, "density"); + m_glideModel.saveSettings(doc, parent, "glide"); +} + + +} // namespace lmms diff --git a/plugins/GranularPitchShifter/GranularPitchShifterControls.h b/plugins/GranularPitchShifter/GranularPitchShifterControls.h new file mode 100755 index 000000000..3ae8f8819 --- /dev/null +++ b/plugins/GranularPitchShifter/GranularPitchShifterControls.h @@ -0,0 +1,87 @@ +/* + * GranularPitchShifterControls.h + * + * Copyright (c) 2024 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_GRANULAR_PITCH_SHIFTER_CONTROL_DIALOG_H +#define LMMS_GRANULAR_PITCH_SHIFTER_CONTROL_DIALOG_H + +#include "EffectControls.h" +#include "GranularPitchShifterControlDialog.h" + +namespace lmms +{ + +class GranularPitchShifterEffect; + +namespace gui +{ +class GranularPitchShifterControlDialog; +} + +class GranularPitchShifterControls : public EffectControls +{ + Q_OBJECT +public: + GranularPitchShifterControls(GranularPitchShifterEffect* effect); + ~GranularPitchShifterControls() override = default; + + void saveSettings(QDomDocument& doc, QDomElement& parent) override; + void loadSettings(const QDomElement& parent) override; + inline QString nodeName() const override + { + return "GranularPitchShifterControls"; + } + gui::EffectControlDialog* createView() override + { + return new gui::GranularPitchShifterControlDialog(this); + } + int controlCount() override { return 4; } + +public slots: + void updateRange(); + +private: + GranularPitchShifterEffect* m_effect; + FloatModel m_pitchModel; + FloatModel m_sizeModel; + FloatModel m_sprayModel; + FloatModel m_jitterModel; + FloatModel m_twitchModel; + FloatModel m_pitchSpreadModel; + FloatModel m_spraySpreadModel; + FloatModel m_shapeModel; + FloatModel m_fadeLengthModel; + FloatModel m_feedbackModel; + FloatModel m_minLatencyModel; + BoolModel m_prefilterModel; + FloatModel m_densityModel; + FloatModel m_glideModel; + ComboBoxModel m_rangeModel; + + friend class gui::GranularPitchShifterControlDialog; + friend class GranularPitchShifterEffect; +}; + +} // namespace lmms + +#endif // LMMS_GRANULAR_PITCH_SHIFTER_CONTROL_DIALOG_H diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp new file mode 100755 index 000000000..ee796d8e3 --- /dev/null +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp @@ -0,0 +1,289 @@ +/* + * GranularPitchShifter.cpp + * + * Copyright (c) 2024 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "GranularPitchShifterEffect.h" + +#include +#include "embed.h" +#include "plugin_export.h" + + +namespace lmms +{ + +extern "C" +{ +Plugin::Descriptor PLUGIN_EXPORT granularpitchshifter_plugin_descriptor = +{ + LMMS_STRINGIFY(PLUGIN_NAME), + "Granular Pitch Shifter", + QT_TRANSLATE_NOOP("PluginBrowser", "Granular pitch shifter"), + "Lost Robot ", + 0x0100, + Plugin::Type::Effect, + new PluginPixmapLoader("logo"), + nullptr, + nullptr, +} ; +} + + +GranularPitchShifterEffect::GranularPitchShifterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : + Effect(&granularpitchshifter_plugin_descriptor, parent, key), + m_granularpitchshifterControls(this), + m_prefilter({PrefilterLowpass(), PrefilterLowpass()}) +{ + autoQuitModel()->setValue(autoQuitModel()->maxValue()); + + changeSampleRate(); +} + + +bool GranularPitchShifterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +{ + if (!isEnabled() || !isRunning()) { return false; } + + const float d = dryLevel(); + const float w = wetLevel(); + + const ValueBuffer* pitchBuf = m_granularpitchshifterControls.m_pitchModel.valueBuffer(); + const ValueBuffer* pitchSpreadBuf = m_granularpitchshifterControls.m_pitchSpreadModel.valueBuffer(); + + const float size = m_granularpitchshifterControls.m_sizeModel.value(); + const float shape = m_granularpitchshifterControls.m_shapeModel.value(); + const float jitter = m_granularpitchshifterControls.m_jitterModel.value(); + const float twitch = m_granularpitchshifterControls.m_twitchModel.value(); + const float spray = m_granularpitchshifterControls.m_sprayModel.value(); + const float spraySpread = m_granularpitchshifterControls.m_spraySpreadModel.value(); + const float density = m_granularpitchshifterControls.m_densityModel.value(); + const float glide = m_granularpitchshifterControls.m_glideModel.value(); + const int minLatency = m_granularpitchshifterControls.m_minLatencyModel.value() * m_sampleRate; + const float densityInvRoot = std::sqrt(1.f / density); + const float feedback = m_granularpitchshifterControls.m_feedbackModel.value(); + const float fadeLength = 1.f / m_granularpitchshifterControls.m_fadeLengthModel.value(); + const bool prefilter = m_granularpitchshifterControls.m_prefilterModel.value(); + + if (glide != m_oldGlide) + { + m_oldGlide = glide; + m_glideCoef = std::exp(-1 / (glide * m_sampleRate)); + } + + const float shapeK = cosWindowApproxK(shape); + const int sizeSamples = m_sampleRate / size; + const float waitMult = sizeSamples / (density * 2); + + for (fpp_t f = 0; f < frames; ++f) + { + const double pitch = pitchBuf ? pitchBuf->value(f) : m_granularpitchshifterControls.m_pitchModel.value(); + const double pitchSpread = (pitchSpreadBuf ? pitchSpreadBuf->value(f) : m_granularpitchshifterControls.m_pitchSpreadModel.value()) * 0.5f; + + // interpolate pitch depending on glide + for (int i = 0; i < 2; ++i) + { + double targetVal = pitch + pitchSpread * (i ? 1. : -1.); + + if (targetVal == m_truePitch[i]) { continue; } + m_updatePitches = true; + + m_truePitch[i] = m_glideCoef * m_truePitch[i] + (1. - m_glideCoef) * targetVal; + // we crudely lock the pitch to the target value once it gets close enough, so we can save on CPU + if (std::abs(targetVal - m_truePitch[i]) < GlideSnagRadius) { m_truePitch[i] = targetVal; } + } + + // this stuff is computationally expensive, so we should only do it when necessary + if (m_updatePitches) + { + m_updatePitches = false; + + std::array speed = { + std::exp2(m_truePitch[0] * (1. / 12.)), + std::exp2(m_truePitch[1] * (1. / 12.)) + }; + std::array ratio = { + speed[0] / m_speed[0], + speed[1] / m_speed[1] + }; + + for (int i = 0; i < m_grainCount; ++i) + { + for (int j = 0; j < 2; ++j) + { + m_grains[i].grainSpeed[j] *= ratio[j]; + + // we unfortunately need to do extra stuff to ensure these don't shoot past the write index... + if (m_grains[i].grainSpeed[j] > 1) + { + double distance = m_writePoint - m_grains[i].readPoint[j] - SafetyLatency; + if (distance <= 0) { distance += m_ringBufLength; } + double grainSpeedRequired = ((m_grains[i].grainSpeed[j] - 1.) / distance) * (1. - m_grains[i].phase); + m_grains[i].phaseSpeed[j] = std::max(m_grains[i].phaseSpeed[j], grainSpeedRequired); + } + } + } + m_speed[0] = speed[0]; + m_speed[1] = speed[1]; + + // prevent aliasing by lowpassing frequencies that the pitch shifting would push above nyquist + m_prefilter[0].setCoefs(m_sampleRate, std::min(m_nyquist / static_cast(speed[0]), m_nyquist) * PrefilterBandwidth); + m_prefilter[1].setCoefs(m_sampleRate, std::min(m_nyquist / static_cast(speed[1]), m_nyquist) * PrefilterBandwidth); + } + + std::array s = {0, 0}; + std::array filtered = {buf[f][0], buf[f][1]}; + + // spawn a new grain if it's time + if (++m_timeSinceLastGrain >= m_nextWaitRandomization * waitMult) + { + m_timeSinceLastGrain = 0; + double randThing = (fast_rand()/static_cast(FAST_RAND_MAX) * 2. - 1.); + m_nextWaitRandomization = std::exp2(randThing * twitch); + double grainSpeed = 1. / std::exp2(randThing * jitter); + + std::array sprayResult = {0, 0}; + if (spray > 0) + { + sprayResult[0] = (fast_rand() / static_cast(FAST_RAND_MAX)) * spray * m_sampleRate; + sprayResult[1] = linearInterpolate( + sprayResult[0], + (fast_rand() / static_cast(FAST_RAND_MAX)) * spray * m_sampleRate, + spraySpread); + } + + std::array readPoint; + int latency = std::max(static_cast(std::max(sizeSamples * (std::max(m_speed[0], m_speed[1]) * grainSpeed - 1.), 0.) + SafetyLatency), minLatency); + for (int i = 0; i < 2; ++i) + { + readPoint[i] = m_writePoint - latency - sprayResult[i]; + if (readPoint[i] < 0) { readPoint[i] += m_ringBufLength; } + } + const double phaseInc = 1. / sizeSamples; + m_grains.push_back(Grain(grainSpeed * m_speed[0], grainSpeed * m_speed[1], phaseInc, phaseInc, readPoint[0], readPoint[1])); + ++m_grainCount; + } + + for (int i = 0; i < m_grainCount; ++i) + { + m_grains[i].phase += std::max(m_grains[i].phaseSpeed[0], m_grains[i].phaseSpeed[1]); + if (m_grains[i].phase >= 1) + { + // grain is done, delete it + std::swap(m_grains[i], m_grains[m_grainCount-1]); + m_grains.pop_back(); + --i; + --m_grainCount; + continue; + } + + m_grains[i].readPoint[0] += m_grains[i].grainSpeed[0]; + m_grains[i].readPoint[1] += m_grains[i].grainSpeed[1]; + if (m_grains[i].readPoint[0] >= m_ringBufLength) { m_grains[i].readPoint[0] -= m_ringBufLength; } + if (m_grains[i].readPoint[1] >= m_ringBufLength) { m_grains[i].readPoint[1] -= m_ringBufLength; } + + const float fadePos = std::clamp((-std::abs(-2.f * static_cast(m_grains[i].phase) + 1.f) + 0.5f) * fadeLength + 0.5f, 0.f, 1.f); + const float windowVal = cosHalfWindowApprox(fadePos, shapeK); + s[0] += getHermiteSample(m_grains[i].readPoint[0], 0) * windowVal; + s[1] += getHermiteSample(m_grains[i].readPoint[1], 1) * windowVal; + } + + // note that adding two signals together, when uncorrelated, results in a signal power multiplication of sqrt(2), not 2 + s[0] *= densityInvRoot; + s[1] *= densityInvRoot; + + // 1-pole highpass for DC offset removal, to make feedback safer + s[0] -= (m_dcVal[0] = (1.f - m_dcCoeff) * s[0] + m_dcCoeff * m_dcVal[0]); + s[1] -= (m_dcVal[1] = (1.f - m_dcCoeff) * s[1] + m_dcCoeff * m_dcVal[1]); + + // cheap safety saturator to protect against infinite feedback + if (feedback > 0) + { + s[0] = safetySaturate(s[0]); + s[1] = safetySaturate(s[1]); + } + + if (++m_writePoint >= m_ringBufLength) + { + m_writePoint = 0; + } + if (prefilter) + { + filtered[0] = m_prefilter[0].process(filtered[0]); + filtered[1] = m_prefilter[1].process(filtered[1]); + } + + m_ringBuf[m_writePoint][0] = filtered[0] + s[0] * feedback; + m_ringBuf[m_writePoint][1] = filtered[1] + s[1] * feedback; + + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + } + + if (m_sampleRateNeedsUpdate) + { + m_sampleRateNeedsUpdate = false; + changeSampleRate(); + } + + return isRunning(); +} + +void GranularPitchShifterEffect::changeSampleRate() +{ + const int range = m_granularpitchshifterControls.m_rangeModel.value(); + const float ringBufLength = RangeSeconds[range]; + + m_sampleRate = Engine::audioEngine()->outputSampleRate(); + m_nyquist = m_sampleRate / 2; + + m_ringBufLength = m_sampleRate * ringBufLength; + m_ringBuf.resize(m_ringBufLength); + for (size_t i = 0; i < m_ringBufLength; ++i) + { + m_ringBuf[i][0] = 0; + m_ringBuf[i][1] = 0; + } + m_writePoint = 0; + + m_oldGlide = -1; + + m_updatePitches = true; + + m_grains.clear(); + m_grainCount = 0; + m_grains.reserve(8);// arbitrary + + m_dcCoeff = std::exp(-2.0 * F_PI * DcRemovalHz / m_sampleRate); +} + + +extern "C" +{ +// necessary for getting instance out of shared lib +PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* parent, void* data) +{ + return new GranularPitchShifterEffect(parent, static_cast(data)); +} +} + +} // namespace lmms diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h new file mode 100755 index 000000000..111d0538d --- /dev/null +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h @@ -0,0 +1,185 @@ +/* + * GranularPitchShifter.h + * + * Copyright (c) 2024 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_GRANULAR_PITCH_SHIFTER_EFFECT_H +#define LMMS_GRANULAR_PITCH_SHIFTER_EFFECT_H + +#include "Effect.h" +#include "GranularPitchShifterControls.h" + +#include "BasicFilters.h" +#include "interpolation.h" + +namespace lmms +{ + +constexpr float PrefilterBandwidth = 0.96f;// 96% of nyquist +constexpr double GlideSnagRadius = 0.001; +constexpr int SafetyLatency = 3; +constexpr float RangeSeconds[5] = {5, 10, 40, 40, 120}; +constexpr float DcRemovalHz = 7.f; +constexpr float SatuSafeVol = 16.f; +constexpr float SatuStrength = 0.001f; + + +class GranularPitchShifterEffect : public Effect +{ +public: + GranularPitchShifterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); + ~GranularPitchShifterEffect() override = default; + bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + + EffectControls* controls() override + { + return &m_granularpitchshifterControls; + } + + // double index and fraction are required for good quality + float getHermiteSample(double index, int ch) + { + const int index_floor = static_cast(index); + const double fraction = index - index_floor; + + float v0, v1, v2, v3; + + if (index_floor == 0) { v0 = m_ringBuf[m_ringBuf.size() - 1][ch]; } + else { v0 = m_ringBuf[index_floor - 1][ch]; } + + v1 = m_ringBuf[index_floor][ch]; + + if(index_floor >= m_ringBuf.size() - 2) + { + v2 = m_ringBuf[(index_floor + 1) % m_ringBuf.size()][ch]; + v3 = m_ringBuf[(index_floor + 2) % m_ringBuf.size()][ch]; + } + else + { + v2 = m_ringBuf[index_floor + 1][ch]; + v3 = m_ringBuf[index_floor + 2][ch]; + } + + return hermiteInterpolate(v0, v1, v2, v3, static_cast(fraction)); + } + + // adapted from signalsmith's crossfade approximation: + // https://signalsmith-audio.co.uk/writing/2021/cheap-energy-crossfade + float cosHalfWindowApprox(float x, float k) + { + float A = x * (1 - x); + float B = A * (1 + k * A); + float C = (B + x); + return C * C; + } + // 1-2 fades between equal-gain and equal-power + float cosWindowApproxK(float p) + { + return -6.0026608f + p * (6.8773512f - 1.5838104f * p); + } + + // designed to use minimal CPU if the input isn't loud + float safetySaturate(float input) + { + float absInput = std::abs(input); + return absInput <= SatuSafeVol ? input : + std::copysign((absInput - SatuSafeVol) / (1 + (absInput - SatuSafeVol) * SatuStrength) + SatuSafeVol, input); + } + + void sampleRateNeedsUpdate() { m_sampleRateNeedsUpdate = true; } + + void changeSampleRate(); + +private: + struct PrefilterLowpass + { + float m_v0z = 0.f, m_v1 = 0.f, m_v2 = 0.f; + float m_g1, m_g2, m_g3, m_g4; + + void setCoefs(float sampleRate, float cutoff) + { + const float g = std::tan(F_PI * cutoff / sampleRate); + const float ginv = g / (1.f + g * (g + F_SQRT_2)); + m_g1 = ginv; + m_g2 = 2.f * (g + F_SQRT_2) * ginv; + m_g3 = g * ginv; + m_g4 = 2.f * ginv; + } + + float process(float input) + { + const float v1z = m_v1; + const float v3 = input + m_v0z - 2.f * m_v2; + m_v1 += m_g1 * v3 - m_g2 * v1z; + m_v2 += m_g3 * v3 + m_g4 * v1z; + m_v0z = input; + return m_v2; + } + }; + + struct Grain + { + Grain(double grainSpeedL, double grainSpeedR, double phaseSpeedL, double phaseSpeedR, double readPointL, double readPointR) : + readPoint{readPointL, readPointR}, + phaseSpeed{phaseSpeedL, phaseSpeedR}, + grainSpeed{grainSpeedL, grainSpeedR}, + phase{0} + {} + std::array readPoint; + std::array phaseSpeed; + std::array grainSpeed; + double phase; + }; + + GranularPitchShifterControls m_granularpitchshifterControls; + + std::vector> m_ringBuf; + std::vector m_grains; + + std::array m_prefilter; + std::array m_speed = {1, 1}; + std::array m_truePitch = {0, 0}; + std::array m_dcVal = {0, 0}; + + float m_sampleRate; + float m_nyquist; + float m_nextWaitRandomization = 1; + float m_dcCoeff; + + int m_ringBufLength = 0; + int m_writePoint = 0; + int m_grainCount = 0; + int m_timeSinceLastGrain = 0; + + double m_oldGlide = -1; + double m_glideCoef = 0; + + bool m_sampleRateNeedsUpdate = false; + bool m_updatePitches = true; + + friend class GranularPitchShifterControls; +}; + + +} // namespace lmms + +#endif // LMMS_GRANULAR_PITCH_SHIFTER_EFFECT_H diff --git a/plugins/GranularPitchShifter/artwork.png b/plugins/GranularPitchShifter/artwork.png new file mode 100755 index 0000000000000000000000000000000000000000..632750bcf5efb00daa936b4f7c495af21a4f359f GIT binary patch literal 55110 zcmeFZWpHG@k}X!8PLPRy2l|}fT*n7bt^|_$ zT!oB<6c z@5a3OY(%}f_BoK94$rLbrf(+gb=r@-J#BV3kGkpZeReo&=4!rs_{PLu4G%jC==$oA zdtubeYEGl&K!bip9b>$Bi6;G^*(zy1bUb>-uIT=V&413Sr;6X2T~l<}bADh&-ECu@ zVe)QAldSRcf$P}nmV1aAz1j{qaD|vA5Bw6pW4p^-3PHl*%l<^_RvKZuPElqA5nau} z;!#qe?;bi-i~1Ps=1WgGAT>SPr_*?Sdskq~RpUD?Nxm|^8`Yegrr7b+wElQ|zpzi; zMDy^4=Y4w8z0x|m8}sGkEgjbt((fvH%~F}pW^OoUK#F{mKIIvFjkpUbaO+NfpZ zqbmqarCedOi5b!BJG6Ugz1F$mv_NZ^x~F{Anzl#vc@z8c8);gBj-ymP!Q*MHM$MHG z>P)=*!wwU}{s_|I7m&~A+goV|7-O1E8WqyHOWG2Ns6%%I)w(datn{0=b0^hV8-QSU zF}!z1b9P1AwrwIT;%SiMn}&qE>9JEDo>5QnK3d>CLy)w?G2G>(YeakLpMBj>0hJ6@ zYfPv%^Zdl0=tvJr2E`#BP!uIe4wU63DIRbd*{P1B0Y^H5;UvjglI10hbCzXwB^j3G zP0g#Bwm{Fa(Y)48O^aM?7g}w17gLa(-}(B&h@!d2$_mqG$qtzIq?x7}&#W5gy88-x z)pU#(7F4%vlq9(>8}De_FPmTU=VjS%iW21*N^@NPkXg!Ue%{{M8cp(O+_5Qf)_K(r z%_?rD+65#QWyLe#;Xu+EMMo(tkEK`9iq=d}m|i1j$8!ftOHMhAp<_g?y*RCtxyl_z zU48PoGZk-kynI?7MkzjproUQl`lL3Iq@=MK*03teTj#yTNFh5z1U@duaI~Q?6>@s! zILNL!V$(9a!)9K5`Cm;2-+1zGwN=MrT*w7>BI>*b7$C%le)r1zYtD&-m!9>&KT&e1 z21YO0+LQSg%#vsMk8WTX_eR#)=!;;2YW&}xRb^?TOmebfI1ItHf95`8n}+-e>V7Kp zQFQeo<-5S(U1|z+OH6w>b}>(qB#SO7V8t|5Ah&ne8|B{!DpXs~;fLA1|8kT(IMUhxj|B` za&y3Hb8cUxFs|n0GMkY;3w{gG(*1KNw^}j-)U&3WV&zrewWsq%)qQybTLH2}QHhSS$?aAZ7x)JWs_cAEkKB6$GD=9(-g1)dd#K zO3zet8D((a-U^bm|;>DLRBkZQg1CzFWq85_cbv zI1@VG4v54Mrat_2^CY&GF+OjsN6xQcPf2k{wsD+02OaVCY;$vT%FEHb z*pJ{Qa^wnrwNWAgKxNQ*TC%`_&Ae&WFf1ts81so?wlUh!jFfMQ<#T%TUPMrIJytb{Tx5y)o{>@2We)jEHer=;IKfl_MJBzhGum4l zmbCkAkt8;e31NTxig|8AnHh+#Md>VgBZYBjZA7(7EYvmmCxfT94(Mf=_~yiSZTg*p z9JBIg;%N8b--yN>nHlZ5E70>zYDF)Z<@b?+9i+bkomlFrx?${kbdXncEMeKi4a_7> zBb(edB%P$ z8ciN1fO?&P(cXYYY73t{GeTRq>p&fCb+!tX0w+mTz|W>gDA`Mhw-qo7X#H&@s9wfr zWFeNFV)N=1zlU~?4eaj`OXEaIDd9i0y=Z5;4WAmkgwBvGQlb#lCfd|3{JZ(-|@SrPfd5f|;#r0ry8bvQAaFN8f4opY%~? zbbzdpEQeB5qDi3&TceWk9}vu1(B?GlTSD&U@|jXaVvP)9%g+gbnW zdI~m1pCk;5NncDzf@NGE(%134v>BBKN^$`3SW#1$GzOU-!v+75LOM!j8^D~Mp9Ss* z@mtp51IlSvRkn16w-Is*&BKS-vbi1pM()<)c)J!OenSEg%N^jZpC8Fbv>?&CpVyS- zX$r7IUQkE8F`zdroo~7euJ^~EZ;+7yj67ZQTLmK~Refpm2=^fB#xjgh#?4g-F#kfJ zYiZ~8-hc%*G8U4Ep}JY}iCB<$Tv@~fj)bV)l-~X`CV|B8p9EGp4KmH=fNU~}Dhzy> zGMU!R+I*^exR2AT1{QHpA8`GJU+BL{CYl6he^VkQU-+Y_!NmCZz6GQ#F$m-l)k#My)WYgwcADdp7?#>7VUoV8^Azqj%}SQua}a>XfFQ} zmtmrKmS@!By!7s`tRC8i@}xJgAugZ<+`P*9_=wdf3sagE?7SYH4iv(CUq zo^)db>>2|mNL8q&6?YC@56f^_#$xw08X|SOcbYuO&#mQbxGR42LD-^|+cZHPk zZ>=1k)HF@bmL@!4Y(Kg#FU_ZGcrlZCMJPEfEIn7lx z0uZgKs}l3dNLNQ;Psx*Vuq${D_yzEn*<<+$(i+n8^2%yW)C7CVs#;i>9+SavmW+N2 z4vVBU6NT+k741NY8Q^S|c5Er(rhRwvQ&*QGJ`D|n$-q;z;P*C=I;2LoX8%uIJV}u@}_uG{1=y{S0z~v8-wOY8K^fxcgnf5 zWwIILxTYn7XJ|LiO1gnm)rRY>GR*K*s(LU0LO)UAa1%o-O(> zvUZnVx)B5#*tx7)*J{lk2^~dFGJ0J7V7{Q3FxW2FmuV3IH+~@XWNn>|GJZbzXqfCU zB)m4Wyf|cq`Xoo_+-2|b@$UNkd&VvK(uAlNd{6jKVn-N)3NQj(^#?)n2YLl^m7XZC z0WF$32t|EdYJ!w5e>#G`95bhiqMZezC4t7y^` z8?wZA;sypP7{v4N73-Yr^;f$osO;f18RZt)8ot0t0>=a9=qUD93lH0j5nOo!*O>EK z{Lq%IfwzW~KnS#-FdqRiaVs$$rcP$=wY^T|=3-kr3N%Q5&bt!V+(uxFQq%n<^1-3= zJttFohoXwqkysjW9>RcqJ7}?QH zx>J6;8e0Gmfh9F{sv>vI>T_{v0_G{SD=U(SLejCVEd)K|Ls{`1&dk&#ext9%X>JI| zDK&|Oy9KD4yC6HHuozw|JR;A9$LkZldBh!fxmbouovI}^9Y%BZT`=q6?Cq)LgUEmm8QP8P0H5Jf6%F45n#mp<&d$Yl4*!@XpPqmbpZ?jp0spKx*2QwO;{S7{CaM$ zOGr3~auiFemykke(b#Sw>lhP$FG56F;11JL(uM_tZ}96~>e?U{!_nyhHc68)Hg$|`cJ6Z}3zibX#FBy`3QN@7jf3~TfE8)#ie z(VXPD0!{Xuw7e>Js{y~{SwJf+uw&D-v1m6eOmiiBh|2x?*;;D#xtM?ao6q&U$yK?*8l zIfOJzmU=|SlkHGY%WQpm&)@1bL-elOWDFv@V*o^k5o+osVdg_30&sZ@<&k@D)<0{f|0vk2vV!Kjtp4 zM=;+ef;6|nV@h!t1c3tK3sP^l8s!8-2!$~@o2R~sZ9D(zdL@L>fs3&-!zdnvBM|CV zfnl>+cWRYip1EMwNPU{nLxKTTFc%w$0Fqw{LUQOSZh~{9ZYw|-Gh4W_s_Rk-nk%$l z$$#{-TCe@Cvg%H1-5J1!>{MmU;Fl0^4AOJ4I`n`rH<%$ulTM#>kco@6`cWJLjvr5e z2|`0^1JFF?#f}EYwr8-L;BP-@qsf8s9!e(o@E(BKcs6d@2!l?~KB1EY4G<(ffJGT8 zr61u$7ker1?CxaiMmYMs|5zMeid6vGEBQ1zTC_H$>=Y!OA9KSIEDHTu3=>4nk;cK# z1Yzu}W=OrVwep(~eIMi#kLw-9fv85%cFG{ssIb(6tYlqQz-&7Q+4ZVa^=-`NntiU6 zw#v+%%4JYqX1^wf=8NeVvpksejQkBw zBLoNAcKLf4;h~%gqp?*&(=`R~u$0-tr4SsHn7kIxG0&;$1xzD6;8Ga+)M}=VJ!OJT zQj#|EWs{_FTz%Fa@@4%iOu+#uLerS%jVT8FXdz|b!Sv=IBPN>5P`)h)5~Fu@z}B=^pEA$=kT*N&x|7!w~ zwUiiSm7;uy6N95%@O^8Z)E^C(nC#|A85Us{RhslY68fl73%s1_p;no#_*4_~HsH09 zpZHi9F`%IZ`~s>M!UY%9yEc-C&6C=c1HH=*57|TgSaz(|R-)OOVl?o&wq~a6qFm*z zam%A=so1tKYZi*CSv{Bkk~&}dF`9`pxW8@>~Fw1As{cO6}n%QDx?qpF#_QX7+H-8(28 zPiuz30{*1HR1}SV-(#uYVU<|$)s2~RE)pT`ghSYOZ4Gqg%v`E5P8-112!hd$r4m(b z4@?`Yc{=LBI{uXw&+|IZAvvmikA|_9*gMQzSftbXVa7$%Vu71B*66_4F3;q_j|^Fv zd<|%ajh>PrF6hv?l0@`PMonrq_!cN1UB;gybcJg#P2i;p?0s%R8P&yq_O?Q1?d@VKS5p z`5=Lib3H!gZkYg{q&Vl#k^lS~XG}tr9E=CC!>J8`3d`Yq6CRt2veGz;vQY@yEz^+*JIBmB*Eywv$ zIs#E-HZF> z9Svcce;om-%Sdw?+FH}<8`&Bd)4EyPeH{@20Ni|TcKU{v#!mPK#-`>rJcL*6-Gun& zMm&USEHd;mc0$Hx=Hea>#!4Qt%7z}6h8#wOe7sQHZk%5L*2Yfy_-@u#HjbQbJcR$? za(-R^Ev6&H|3}2hl7~=TMjl_t*1;H`nUl7Yd)-!N`PDQCRff5MOsZ zgl0}ocARu{uCA`Mu1vJH4yJSr92^{U^o(?jj5J>oG>+~zPWo;%HjYGpA^wFSZ0u<0 zU~cDRZfk@87gOKB*4c@NknpP>|3CU?Z6_o1pYS%0|7PKf4>~t}J30nhdOB-sy8o)- z=p^Fu1@i9>{a-a4mA_8X=oF0|ZJiwqjYV9HZJdbyD}<5Zf9l&gJ6Qc=j*%gqv6Zp) zm#E`cs|^3GNihi-`Tx}TOM$7mwcS5jUu6F`NhfoY|3lV)>)YR&f6V!>9r;rKPu%|| z{U5gfBm5;LBf}|dYv}y9dlJGtgn!%TG_o}`H{$%~lHJIJ!^nVvmB!H6goB2efr*WV zgN5FZ#)OfH)xgNWkjdDP{=Yy;*f=`r+ZY=Eh57=gHUGllU}0i3X4Pk*F=A(Bq+vE> z=b$k#F<_%%F<@XeGB9RjWj1E~FA#DL=3ic^Z}ne$^%u(M3yRsmn1z9zje~}P-H4us znV!LbhMk>VpN5{Em7ax-jh>B}UjH8`BSTJ6TL)|Xui-Se);Be#v$HY%r{XW+oC5L^ zJcNw2|LXWZCGuAKP9|RpJcQEbHqLJUM^xF|+E~d+|1X;iYz!QX%q(myU!Uyk9PIx` zNY&WE@yiqcVlvRvGW`qp@33%w8S_P~{$D@+0{BPc%N9-{2V;FFTL)!ZTPq&Iza7B; ztND+6<8%LOP{hq0za-rMdi=kAUdh=0Uw8kS0#@e#RN>?Qt{SPyP>;6#re?)y()WPxOq;H1w=AjLgam z44e!soGffK^emk8^n`T(Hkj`3to{#+x#|92oN)gm@L$5fm)^h1zQW5_w4(dZaP@D_ z{?hpWG~fr@IMm%U+?-~y8cHD{EvkH*Sr2dqYLW) zYRtU^MN=z8=`S+RES(^A&0%<3%;RpcG68(JvxfS!dd=-K_ zNyvzRAA_O8e`n84=<50^!f+B%cM`I-{+l-g{z>PIjqqK~oy_q6rgLikaA*JkK0rcP zK-q2eywfsG+c=r_PfYz32Un%4NE~I^AOa!@3WO7$B8u1JrX=F8HJUcP7I6rt%8@3N zFs;TqP!JK2q{lhGbx>qyV1c5R_4bX@#0ZC}LS;}-U;-5ZU?)?Q@;<54zTDrAS$LLH zFVSmSDCfMT`MKJ>>gCSqskS~_&qD_|S5mg#KWs&X0sIpa!oq++jF;|S0K`e@TV`0# z1jMG&79_8!@BGnk=cFr?rOD~re)8hU#2vruF(hiuQ~Lmtz<#Pv+)}@sA!`w>qC+s&w7kpO(+sLd zfJ*Patsi2?Gw_RvfrAd!VyEtE-C|^n8pckeob~WP6FNMt*hmNY*JTPX43N}`%R76| znSnkDU1~58jWagiDe)$n(H=opZ7^k68WM2D+@|gFSh`hKhejAWoaq-<tgB5y#v$=#AevHsGeb0@W5jWK^0x0PCO{nqmzlv^t!R0OV)7R7fdy6%;pUR zBW^c2G2w#fxbNTOX`?cf90=dmKRtP?Id<0adlo%*AK9F!XH`m3RAXIC56@7DCS=e( z*FTkH%kgfd8V3va(^LI3n-uq8tK%0J=e3SIeXptR^pnoC{o^Bca_*XG_q$ZheoJ?T z8_(88=9x$5l5lsww_0|n&QVk6rl(uyw5x4Ryv`B(2d(41YkFplDYwp*SFvwzXVP7( z`b78p0?5Sy_KWuLHf-I;(~7O{H^-AACs91!^QRc7PLy~*QI&)$$}M^|MCahvm0TeN5qtmpY_NPZqErKWaXYa@{NJevge5C>BI?E~1dk_2LRvA0uaE=tvsz?J z>Z6_!my_-=*LV?Amq8{=L18*AG7~HlBncbMT`T@B2G$!{F!RV*h*OOLf>(`K&b~_j zQXyqzBv)$Fvx}_x(ASRJmOpTwznDRMI;X)6xMEZNe$~uWUU!<)o9Ao`^@nb(K-3)B zAop>YBk`Y|W09U6PnGZGZml$QVSRg`?h$&?j(TD09l7PED>i84zM1!^peV_U27xbZ z;LvQ{>`nNs9h*+JRnsGm1n7|w#A&>=D{>6CjajXw+)0#)zRP2 z&h%9cgKnpm*8_bAF~57#owynu|9)RN5(O|OZm~At`{HWoaZbMH(?5$GB(6>PD~Fj( z^}Kwpb3-16cF4J?boR(g0wbvVCZZvMMQxy;5het#1fAvTEd8OIlCkdGb$f4M2(W3k zE3JYm#>S;;;Y-%xSpSjTLO@zJA$0~_^XEg$#+x%`nMgpHo4T6WsGxoajE9PE+OImb z_!vy9tK?|C&6{go{8SR?f7a6RNhX0J37+BkD7z_PHS{>D!A9}aP|+|HUnCf z9sN>ezb4!89bZ7X!4iw}VIbf=O5Gh#7{>;UIX|6I?_&3AM12Jy$veV)1;y4$y%9nn zh@3tOzQ%ev6>{zJ&0V+4 z=HCcR@DV#kRE(3$kIN+Vs3DdhxuKE7I_lzQY( zjM4jOA3$VCSl2bHYa2>P^+2R$oU3`9%EC6i(Vk9=@fj*J@yxs**ymVWglfkWBn^rI(2r`xsv{ev9T>?y{r`U!E7(#YjM8&(8{>kLn zBwKLlIXB}DPGHiowhc^Cz}=~pLv4;z896Hwp=nyg8q8hz4(35mAyM6Ekz=c&0@a3q z$$7X}8C?`L5`T8vZ#ajPtnv$sgH4nKO~5`% zT@-)tQNq<*8v`M2lurt`m|z-|xISFvjqDy?G0;AHq;~4yn9;G}7(+ui!rn`{T|)5i z5u=_(q}sF&Mk3>$$cdNLo$oE?U|I^U&LP!!R&{rlNMB*{4s-8xZ)X)JX<*XHMvtnA zKR)by^ExRu2)dy-?~%n4pSj^_4V#PUKJEerF}RBO%51!g1o^r)yrh8Jk?@O++#k_s zDjO}pJ8pq6n7JWAyN4#MZi$6b>jg5gp%QJcjM*L|QxH%&c@c@4ARl8oQ3SNzYF=I2 z6x=Di4jh@GQM3i_w~TDgR#a7evUrJgw8*jbQ0qj)Hi7*%?^83LC)JUZSOS#D+$J;; z2RM*6FY|Rsl*oKSD`KXuq83?KkQi7jNMPM{vG^rJw0<=jHDB6*n=o-}&ksxtJxW%z z7)mc=S?W{tTXm(*!?C@zWsU=*N=>16`?>Ch2+O!Ol?vuoNBxlqu{i~5w}i#sZ5yY6 z%&JJETM{Enyks^)*R`G-mSn73rkE(xvg#G|*4uUB&f16y<1<%PE6_m}lV(OTRAMpq zZwk)-yj|}$_8(D94?K!n`i(S)>G~9RA-kJndy#v|k*Yk{15c*I<@ehO3I_D-K!VN3f*$!S$JWbhZp@Z|0LlW)Xlj^RG6DQxEPpu~0bKee1- z*rYHJyhlk?P9+@dGmtZ|dLQ&vwZ17G)fOgKy+SK$%c zEEV~c2@hWAJ>Rr~&gz~H1*w=wiHFiu*vVLhl-6ej{025O&@s*!l4M~`|6nk^iR#%1ew6uZ)*?Jv&*8KLTE`DMLF2voZ_OBsuiK>Spkr#i+gfU zlH#TCi2OUm#f*?Ip^Oc-3QZ)=FVCZ+D7V0W(2w)$w)VQ`n#U*wEc*wL7l@M|*?@xQ zjBAY!m#r2c-KAfwA&hE4PwL^(N(xP4dq6c?hpws!N^?b5D^tMd+ya)_Cr(zKR#ocUmoIZ!DQs)mtC?jgylCYx)LNZ> zwebVh;qYX?H!cH(M%HhoF7;1jAwix>QiAJs8N|aYF38FnC=9E$3ByHI5Bv$UQ^34p zoUOQp5~wi&WtGK%Q#jwoUnfG7jN^>4%w`x0kpKrK=?H{cmR990>^q~>98fH#quHGs z32VlT>5w_P2!ELoaEFnAO4B6G8Eool2Cu8GV047Adr+ zMmw5L=N+Zvd5$kb06v+h!VHr^F84Ey zOFwITdSoU5kw3xuPtWe;@}(N0S^?6S2Oj(p>GxY0D$iR=k*P2VUEsuO@%sBBak5(s z$V-GG)WinmR7Y;@sm{RumNnA7% z#H-T`NR;=sQ`HeQ%5;AvUMEC2-sg+r;ip}x&#>W-$8JLd148l7Fc$HiUhqyFs?=_9 zSKljMAmIE)3^jhqQFaO_u3;l?o`_Rp_jw5lvXXb^I(CU8k1@9l685I1LR{y00I$oT z`SZ%Ps+RkMTHV30+-}hKF1*TE?;3tXOKdpxK-S0>6H`;WaqF!y*fh{z;T=lHhP706 zYBN@Yn~^tBN;ZA_2g-2qDmfAP0ul9s>FL~9?Wby&y~_LUiYzeIibELfK^#O~q)UI4 z(C-N;Je53R=Oc+O;sh~^}*VA4})Ld5@N-q}}40p&(o3w(H zi$SuqjTXr*4>aU=Q@bF=7Eqzk_?X@=E7(*?442)BwY`RGL~ zHQVgw6*4T22coBbFZ)m`ypMfv(d!jR%TA|(RkyGGVrw`Zj|-29so}U{vLAA|8&3?D z*4i7cN9^OA_@~d7=gs_xYRB`gRO?}6YQAbE5I~mwBX*XhCSwo zp)a*FM3oe|TnDrao1=l2PmLPFlIZVF)H8zeRAMi8n^VBb(k8*RO>>}wM5bqJP(+^t zzs$qde24Z^GZ?!hdWW)a(DnBn;?qC?Nx#QgZwB=WEn%3bAIUs!RmqI1x9TB5Vt;s# z0CvR7pJ${`GE{1I2)#Vj%+Si34j4eK@pvM;#kF|WZT>^~uQaTMgYi!$UY|vCH=8w= zzZQ{sZL?$hEa#`Cd7+SDe|~srGkx@TxIaH@lord-Gz|KMJymB=6gCuzG^=wgLP{f! zUK$*c^EADQnwpr73(fzsV7FMAyS*w6$pr&GKCRd}T)U)ptpLaMg82S6DfBf4pup-) zr=71yvJdn`lh!dSZE=bJ#3WoB8j*l9sP-m~dM-#hv5Uf{txO(QEww>eR`I~I z@XeoHb;zeHEI^Y4^k<3rbmUKsblsE>338?$LOIH6PZt-kCQaDRP9AlKWdp0VW}NTb z&+veuDKy<7XWeeFue&&MJ;soboPq0+X$B@HV8846k?A_4(R{bdmy6|>-SIDm6s=Zn zeRs6SQ~s_Rf4OF09qKPLn6R;&;7q1Qa%|;FjU=Z+2Z%rPG5|9*)Z|yHDsjY;gyKK} zXr|BFQjS=dUNxaaddi$9`%ewGBERMXlu4dz_q%-Mq$9!Xz<$xU*U2u{$ZE|hZ2Bf< z7@~m69`i)8W+!S#<=pN!x@4gB#+TvcMt58+ZaFmO4J#RC^MBou~|%h+!`~K%V;yf3m4-<${1wc%DY4dJClHRp=@SO z%q2kfPu7b2YW_mB5^rKWt`A1!>}0NmHxLhL)wPljJ~s<*vuxSfaNrJoj-u*@|IW6}}=onkP# zo&wE`+!$FY%9bxPP#1U@7$EZSyymx*f+Hm+x>>uRwrskfd3bDwB#&=Jr!Sc(jN4`m ze(O9>=BMsrR$Am z+lmPfholD{uHrz2M#BxV^?voV7bnH^ZaS02%#kNG!T4G?It+WiC7*@6FO7sg4CpUo zEmms#uNrs)R>Z*j1qs{_sgY+Gqm%=l)n94ovw1(bW}S<&Lxe~*B3q!P*$OA!iaLyf zIK=?k^84N*TV=Ac;eFxvU`(?EoWHU)%W}GPc0n}7%}WFkW!y}A@+x)?>lM9sCz3{E zg8~oNDAZuTDoU>%&R=E!!y+&!DJSRaxV{4gSPhY&XJ{n;3u7a6ol- zti2RxsHqdrYNI3=7nD*BX{+8H%TQUmtWt4WM&-Boq&W&3kdV)u0<==rLxf7GZvVKV z<2aYky6%12yCM7Vr1EB}N1;mT2FKUCT~O=I+DZDJTht|HR-DvqjWxKxPyEY*<)`|` zB_j&U>ne3fGk19G`^(8!#F)*iNmGGUs8ON3TPWsACJ!QaH;@pFplpAm2mwa{UW`bG zT+(vqFwxBvsZ#B~zW)9E=z3MPoP_Zeh=jCUPD&XV7{XW5HO{?Gj9sgvnt)Ui*R@QC z(rfl5fJ;Yri+3H2cjXyXTox=2thh}MX4QRnZ2fn##UE`xUDnk;4o3Ihc6wJAY6TN&&WjYtUq(@|;W{PHZ*{zJ{<5 z{&42Du+kVT;mCuCA&N7cLr)TRbSDp(%A^LUdz^cFYj{bUZQ zRO>`*S$7F_FiI*EF6uZh=&Q^^NPjT_>vZ12O}SwB`vv!(RB9EKqUH!5`pK!6VGqy8 z{)uzTuSE<2ZHSVZdP<{mVTQ#PmsH2Q3F>ouY{u9=UmEI1g@-rRq*8pC=Sn_a{DJ=%cf9nTG)q@I{{+z2ECs z+0>T{zd0O9x!u>10RW}m_x)+<>Agc&d|_0)u8^#opTK{~_k;Mn(H7e&#CvDTYS>9k zHpHeRR6%bwQvesN@vQRsEqimKduK{3I~H4VuY8H=^c5NvJE&or6DRlO z9Oc49V4JG=41Mj9dGnWTtez;LQwj>xWUo~RI!%r7=oMi^L3p^D(h=F~fOhDzim9oI zbFu;^$9O1h+^e4xL*VGhuVvyri#0y<2EAq6EefX_y!%%Mp)1JdaQ@6ilWVps!{jQ%ePs}Ms zZ|DZLVK?$XK{lIIK4P-Ydv(*qwpt${26F@Lk!%FW@>iH>eQkf*X|tZ@8qx=!i6(cK z{*mD|f)o5hG=xWfR3^E+1u6p_l>A_BxeXO~aab8!WhPHln_{kw4V9eBVbDHOgb{#enx?oAvX-6k46jjRRmPooo5b9+jNp#QZL7n+!HyyuHA}(eJp$~8=ea9Zh5dscJwjX}rjg-yXRi4* z1>IsoFzKqOwME07=-6Df{vrU@S_5-d*4owH#Fb`>dbG~edezLvRluG~!_H8D{%iUI zVt%w^HdSL@wtoU;HC_g`-rnU7s&#p>__W;(&XiG6)0(5U<@w)MPzIq4Iw?A}oK#oe-kCoRF0t6$;cJujZYex?eKC@v6$@e81Zss59&DGWG zl!sSqg?4dYVI*866!&C=hzJdfBUze(kzsep&xEQV9zN3ic?(hnk;IX#_dwU(pc_Wn z=k-hi`z>a$jDH$^q#ab?8#wk%WO};Bg!J^Ymcg>$GN+?j6_`AgE~zIefwBqtJbu_R z@we5D)~ksFLwIXmR$C;kZb-`kE=}Lv|M)Gyw>cORs9iy1Ej+A~(29;^C5Y>32@>Y$ zmZ^e1b4S5T9fbP>i*-zqEQTrQu(bG573ekxQLIV1o3>ORj#Wze1JmWZGl^5(dgiSl zu3J&Jxj_!_o<}9#xy%K-jK)nS3SlA5Ws+Om<)T7(?-;7v-6X`<+Z(4tGY)Ye*)-2a zM861R*)V83{?9%EH+T;Lh2#-T`rv9SQ$YEjXA5s}e^7rTRIO9wyc&|B5J1Q6*kw?M z$+!xfOa~e6;r)a(qj*8@ujMktzDyiIa<&5;OrYpo9n1<3&VC==>b*EKxO#zeNS`r9 z1?maM;mAF^STZySkrHwG+)#-`Hc4Y=h5GO+0QsKKBtbv_8VV!;@8Ci4U`msO5xe~@ zo-oanYqpIP#IX!VwSkk3{5Rzd1!A4~lL^e%^kLqpkr2DN1WM#@%$pi92 zX3;sbG8@?B*ge^?_U)C$$jD&ZqV%d{6SI?zqGoA(2ijGJ1(}4qGVvh(gDyn!)wmUZ zBtF{moIYfAvR*xRUlkPG3*6NXVN_o#h;o^5k$YSR164bu?oNk#GCiaCGSbwMQj*36wrs5sed?z0BYrG_ zV$`N5RTX!opBV9ElR5^a#_lr9!~VrEk$9X>Fvr-LMnn=PRCTB;#|S;wYXtVq2h z*kVZ&91^e(juLeuJ0SiO!mgH%`*eJa16P*j9Wl{vKAv4L5o%j-fZhJa8gMR)&1 z-q>Rmv>w&270#_01pBF}v^HlNg2t|EImr>$$>lSp1^GE8^SWmnU;f^Yv)+m7GlDGV zw%lPaGmH$~Uu3Wv2C^(jkryJEEq6*GKyk0quJ}fS5qwYt_LKCKtl#1;5R93OAY8Wa+%ZdLA(b;?gRUq>zcZG_Sgr@Lkr5Ft+x)}dAu z$47!qq2x+fYIM+p!dgIUcB*|48s$ZFBdlIztRi*%Fpk?ik+x&r*j~9CFP79YS+>Sz z7$gqbQ9okRSY4wIBh2A#2WvZ@=vN%E&G#7&vSr8%gU`e&o$2P(()q&e^x$G{%wVSI zmVBnd*^Ji}r?uThR7W<@LU_!V^9?N0WAjEg6?ZH)v^u-N)RifqDTh(pZ(ah9ZeWI67Pr#g@YiC3U==dG za)TPRCL{#ZitU|=r5n8~QyxgDXyLbnVG&#W5UDOO$@J}w#8094@tuUnRsZsGGg#~1 z{K(hZik*p#4Nh#Y0Ftto9t2Zg7p|Wlq>-yDU8I>=WRA#*j#l^q5go2x)P6!u`mVlY zkAY;<`fy`V2?Ovpo&yLG+dG01?!odSo5YxVe%}w0tA|Hg(bCq+aP0}#J0_z|&uonT zj8n{?KUI_2Y>N+FmuI)P9y6y8MCk2FQtBsycf};{+q5c#tar~{K>gpllM=cN} zhzr$C7@EQqRD-b^!FS2)=jbXKxUEL7$r>W&`yv;3T4kkrhUFY)BZ|NCTk?^%#&DvG zd7h(Hc(FYi<;6zl({a@A(-;`K=`et!#;9HGCs-lPv`=CTa%ae;qo{@q8nvi!zj+)W za5%|5&ZLx9D9pCS9$#yua1`2y+W&sSYjs(mU+C+%KTm1yA0;V@jmEIfalzZJ)(-CV zt5oZE;k0cn7k+9l2S5pU?L)vJAQ%}rQrCVhs?!&x{?P?|TDQI*2yhJc>fNPfWsVQA zs|8&<>N`W*yS<>Qs;V}q3C6~$<}gvjZruz&S0g}y=u>}2H`vDt4Q>bb_JANDQxEQ^ z7zQTMZwL1FRF*H@9vOMS09}IXtr*qmKkPCSM@MRmm$urc4MxM*fuIsBJgumpAku}^ zGthZ&KchV$ef$Un%JH)wT& z%Q`6n*XA8B*c}yN2Np@(DP5qGwmo|E-GVrT=_(H&CE@&MQuksc5e>B(BORdwR#;N? z2(R|}Xm)-_C4Cxdy`weD4CCUsDkVsc_xZkdLd!fC0-(KpNrDk(TFvBLzt@B@=i8vW z6x%v#%>A=7gstxx-T@%@YG2?0@B7HtLCiW}*28x8D#s7b+u;eyyoec5T_$$+Sf88C zh^ARCe8Z2+OQ)^O70;uDv3a{V&C`d%%m!Kc=G5ioWwu{G7ST*DfEK*zc=2Z&Gn}Y% zfy?^cYIMD^0vHzk*Sp=a+>33;yG=^Tn|)rIUORnWj-T9hA6_7loBv7A3hj9u7w|okNI@4?@#S zUB;aX;AZRFV=^uZiCeV2bhw4j)lkARYm9JW0OX(LtK;3$Gz-P_5AmMgc+VWj; z7~6PPvTf07*7lFh{qnMT^2RJJwRD{0$90;T;WRp)Jl5)RM`w6{Bo{bJQKun!9p!)t zedQ{xXh?LYQ5KIIEg7F{7lA_Vyxitlq=EulcC(pfL#nraK#J4uz!MeKt#>|l_PxGb zJ*;L`9OHkn8;(MkJly|HxDp2RAJu#zlIz)lKi}iH=^ATG8D7XtRzQq=R$J&_xD?Q2 z9`H`UA$R)v1X*lTDLLl&Uq%@KvUFXI;R$TjI6Ok+zU{p8JW}>4h-Z;eHNhHG!nRa!8p1f0jG3Gy_ir(Fz=K z(jJmTml49CvQm$v<9DA}L4=1%;iUtI_6xiCUHgp;)#c9KV5^CWD0q*B6D#0*ykYyd z;7>LLQ+?ICSQFr<1Ksdz!_8dU@8h{aW88C*$8Mv!B&GROL#oAjWZ~5zz$JiIdk2s4 z_O4%U$&A)^;OS%-&O-R*`{U8i9Q z5}-vz^o9L@@_Gu`;9?~}^FFS~>!%SYCTi6R4ylL{5L1wkj6&cX3(+FG(j!7)`C&3l z<5b|08J4mUfju$@#*}|+eC+3MK<#QMhdRJ^Z3q0M)`8Zn2Y+Dsi$82d*bF?jSQk)1L$J*U1*c%14uMNr}JnLw^n`5|EvG zVk*w5KbLCt+rOT9ou(&`&DF2_B|rmSchp}G5vzv?e0+Ce{X zUYEm8L8q5C;YG^t&?G1URC86ZnJuo0KQ|!Axn;Gq5`6 zn*i~*fX8~tTC+72+-T{H=nb)HX5-qDw^6?7_?gG)a)-bFaaJ0$h8uInySO3 zzzLIKA{$RQEIVp~Tf#LQ_@v1~%8A-ack#+&3s@ow#>H%|(}nC*7N#>Sb1kR5z%8T9 zO;_?vUhJ)i?QZx*o01E7yJ5NxZxER?6cCUQjw6`0Fc@hAxu*ro4li>5hRng-91kcd zsV<-ss#Z&miXsX|nTLdU+ISY@$wtmb4!gDBQJl`hjn=enMMxMD_CBw!+FGDK_e#0VXP*vvm(>t?@3cVSz9OqGTRZq>+dzJdQzwD1nG+}KU7|IsP3?ANnSp0p4UwO?egi77um0>emy6q zAL)*(uqGMlv(^h=rmE5doGRhAi8yx;j}WL5N{PGo1!w2tAN-B1eAuY&ujgBBB1$Sf z{ix)4Him`CWAQ_Vp|Trqe6dh|k}@j(1uH#x2%MRK4ejZ}?z3l_e{Tck*Fb3_7Itm? z8Z(nVT9{wN3HnE2sxC)kY;1^$5)yLo-@)gA_?Ky*a@F=QvqGI?{?tMx-o zR$R}rWDnG9V`@YxbarF?b(4}rHSnwjS9w)0HwBzB5qlYp;r78lC;g4wXH8dzWcM^G zcurfkmnS%vBUlvVuaDg*l)ayc)&{cyl%TcPQcq2*Hc{`d)Dt!TF(xo0c~4g>FQK&q z!$n9vye6zqz&+3PN~jOCkksdg&T7isp@HhF`u|DihV)1{a;SI7^AkUZ|6Dq-c(;sR zmW7BlTF|E%P;DQ^wuPn_Gc`iVl$o1bO&IoI^8f~wP^VJivp_eYvgwIAoUrMwD@#Nl zlUEl+*_{aXVGusJ5x{1qjHOsIJM$_@+&6}0n3m@vWpvplVPWH`oLd37aG>o9qM}N;;`r z31QCxArCSh`<{yGXI#s$i)%+N{IgAcPfK@bTf;QufTLNhRPB`98x9@pW{ZJ-jVR_t z8@g2j-`3~;a)_mRI0M2c-nbEd(Cki}G`fmZAX6}L(#^h(Z~dQg7OiQGF%a-axyU-V z4i>8d9#j4r9tmot^420RIsp?jBCN_hXTCi#Xn}MAF*iCz1-taVr|kuSIyr*~F$*|M zkqh;PyLo|pJVoNyzh2MJJhotw_ zTCy(O%F*1z+?8imBrGWF?&Kp95rwIzT4l`7LfmY>3Y_3+s%)w^7vQ`U4v_>)&vTc0 zKAeaXoac=gDrWWBcfQ|XdmF38ndxt{Xq&lfG^fL1^upf^IG0{u!1Y~(mbDy<*1>u! zsZgjXbf;Xx-NOVLktOQ0qK4_EgTOgN`WQT<6E<{A5JAh6%m&4=`Mp&&C=;Bf5*v<> zS3+G<4V-*eWnc3Ie;!U}UPTAlr@^ifB-0s86Yy5GjI9cv6jSXI^io9l}j{rBw+bMou$*dHAPn40nUM8GWq6^z(MQb-N*oRo=v0uM`$Oy zJ6CIIV71v5oHd8>eUl3=idiOG(cljq2Bi)K7~JeYhuOP9EO?vsbdA&(lq2Quy@$Qs zeWyU~Cth`bS)^7Cr@k^ZOlu3xgp%uV>ITxVLZ$xVgN>-e@On(E4snojRW-U{vt+Mg zn{K;S)?eIjZQk2jEc6N>r~>4JVkoef?t^K*rf-%}Ovz{gq0W_GJ415ysCWoVqKo-x z^hQYV@5>9q<19?d))7)L6vd`iAv73CMi9!d;zvT`cGV-Z3Qh=#Qq9dsV&u`&CsHH@ z!_3EIN$_~iDxC)eQhZ`@F*a`GIc8l^mrH0>x-*#TyJ=;5AR#gee*E?d2|?0MRLD-L zDRWKP(ZEMCII11cR2Tu&npRS*&}L^jQQ0tE*$tDVq7T#J2=LelUBfDHCHVVAs=ySK zMZ8Ab)JUqjZWItYg-TGN?3`+2x;w#v2$E>;+79FXEjM|^I z>R_)^pvS7tL{lN8PtI04=v+jj_n5BYi`afqgl+7cn=XBm>86|ANwzLg?<3xeMNJNo z$XgQN=4fP&;gGX*+FU#o4{1dnr&(T*!LBt-FgHx@ytfkY{Y=l@)&4YttPB3Ie)q{` z&UmST=;&eTA%X1U!+zXdx%>paJ?!F8kZGsRz#>LN0ainHKJTnPLx;eww!DI<+l9;5 zt6S%t-KQPvxZ6*Lu^;{0l5LOY=j@-v533jccT5Ar47850t z9Qou0G=^~~Jld-CtK}TK1(?~xsPV<|vvX*zge^5)Zf4n;XejJl-Ju)5mx1TgTws^* zxVEG4;#U*EU|3FY@)?Etc)-XQwz>;T*yj*2PYDg0Rd98@1UZ?@LtHztp~42rz@hv7 zF;ALW;0FO(nOV+)iigCaaYRgX__p`Z%Y)OWK_SNK9vY7!0i?=Iet*N`f}TypRlD^_ z^@|9a9g_Zo^8CpLJ?G%=X!5bTL?^CxNHf{mfmP#DktDHOcwPYjbjsp$(}Bx{hqMG?s-q(z=^ zu~s@`ZNbT8=17ciG)q~AyFh#rvg%ZmdUG4@Y_{O8hz(?GR$D!6SYVhxUXvgp@xnB8 zPDjFMk28DyR89;w$cj5Qx56lXvK&SlR6gt2`LUQ;VMT-O=TlX1W;BDG$W(2DWv`A5Yw}(u43yPmMK@H zFG<%U%sM=IYRZF0{i_i;e)8rhcw(K!;E@1sRZFYcL%z5OrstbBwTmi1HMi^9>@YWl zbjqnO^BO*h*WS>O5Wx;liQzS&Mv$>5c?6J6a=pUTavkSYzOAiN_|l)zWD?jZ!h5@dud0%VzDVtbT!v;i4P507nCQdD6p%XI4$&)Du@SRgYIE;ZPkcW1tj za4mF&33nF5v1XY&g#z4)k3cvTk<+WHeB$dKD9vEkOQIkoRx7zk6%-UCYw3l-MNw1F zI`x>8MQvou8?7d(LetM(_H{Tb#43jBA^u47zh z`0>(Q;4Bx?7!P!a_WjH2ZhVX#{)`7w@3@okY3&N@%G?SZRF1<8KCjsSB&nO}4!>aN ziCa`rLjmizqE6fP%D5EvSfofSP&&n@XWqJPvX^o2l5xFa?EK*p;t~i zvG9F}e80^I`lI|2cm|{5l$inmzPggR41M0aqlAIw=II1}pU`&O?=C?77wTh$T?S*} z4+7c<(5NJe=>curdnVjSZxVYXxRK`45DX?`;4<BSQ!uLA*&&cg716+c22V@9hX zUa=u|TN=9#=r!=+2-+d<#->h&j%sMf2_H#w`@#U}fx00D7ByuSV1_JIaxobd8|?;b z4Lv)JFJ6A#PNaTEUCJM!& z=f7rT=1Mei$2FW=Z#kWA1Ii}U{M5FrM}nC%PLD5)Hs^3BV^_3&kXLJWARO5*6Zd?! z8g(K?4gr#FLvbf!k}(v+q*X+sg}K@F^c5*X?EQ%f?oBKP)p}my^IEyddyUgU8_uH{ zvWYx2I?dL-Zd!H!HAIc-^8W&VE1+|Alq(>yWOW@cgBMZo#@Zs~EtG^|Lbb+I(bpjw zv6t-=@zU*d=+R#H!rrgaqZx4z43sC?Tp~!Q$p~XR8qlNT2*yH?)wz~(AX_fYwa=Em zi&-yC$zg8X%Fo=Gurm=RmT!L!@10gZHu-PwKXD~mN(%4E7~P^RUiTh#r!RN2%O%gN zyS|4N{8NZau*+0J!N>n}h>A641A&~{gIZHsPJv96AD;t0v$_S-{CMHHOL@fY+veqlvzp4e z#>fBS9K{j(8vGqkReORR7bWvAQ`DGZt;zTnzJ9)rc5Ageb;@XT+si1pPe%G|5+r^m>l<|FZyM zdfV1~C@}r5=w6fvz*)v?1L#Kbcee>Oiif=)g#Cbt3@mW|>~d%{c6SU=d;`?<0AI+X zK1wxAB7XMhPL7C6B9X1^?*oPMT1-neok4O&`@w^r;$Eo%t<`)&sF|{skAt6qh`W=5 zPD)dE+1BU%1kV`NJ-4}2I)+iIIxwqBA{mcW3x02nmO&~WuhC!wfO&}X5y7F7`2utBz``reqWKEXg5*AoN<+lO8Kfl&XBSE0X{E?s;s-l3*aGstiWQ(r{Xb~wJWq|CSek4OTCB&?FDXSNIB_8J*L{yY453`~=4LTl3qEQb zXaxnHHVqdFMSuQ8{DD``j@R%-L)M_}HKy!P7vD9NtvU7!^Q*n4wx`)89jv1?@Op?K z@mLX+7gHTarI8DFWmdt1?gUmNz#}+?Xm-#MVe%-~=MsYWF;@d9_d{{lKYJ&4ycqbz zBGyE9GNBWwU2Wp*tT7dvj$vV^WO*^Lr5!gHcTJg4uOn+s7rDSnmdg?iZFEu^f87{J zQC=?0ah4^D;j~<<+vn)~9S|I<2Q%6n8fE-(;wpmg`aQv}2Ia7@xx=nnx4%GC)x04} ze#f^^2Yv_zxKF5Zc-Dj8rl!>7 z!WPIFEsq0aF)B59%ZSy(7Jrr*)jd7M!j^=x&1r12UgNbMyd~jh??+2i;vD)G?7%Av zbf}HS42)9l;h|05ZN8n{=}B9uvuJW{W0o*a5m~Fz3x_J5)4ZugU!(yisoSDoSQWu` zQE&C6gO7Eua=&m+DiTM<0L_V|%wu50&Pp(fs441xWoB60LO%kL@Zc!;wT1<^UsbfA z+jGF&mE29rscW7{&TM5pG-xv;6pg}r-Ul{MOtGgly3K}wPIvw(RaJwEL9ZgIfmWpq zv-f7~oyR^_1bfMRfzemY;1uA%Hh3(pK#GCF2s2A@#*_2}FNrGE2PP5dp%ON%cj%lz zC!U?49iz%O!%Ee3e24BtQxYdm$xkXp8;ia80=k=h_OS55-^G)t79W4>3m3;Uq}vaq zUij^+R$xgj+)bV=ibERhL~>T#RV@Z1N>e~spUnBUTj$wLTn!4FZ&0(koGQw-97;Ic zl^jEsI}V#nyXIHL6mY-!f(S?m>LCPc+UW|qi70PwUUYDL|MPSr#)Z1v6ux?-)9t<( zTUUalhVo2xB@y^}nfvFSvarxoL(7MM>N*p*9bkgHuxsxjP~ffQiw|~9;0+RhbUrj0 zQaprD=52k|(kRrE54=J(MPHV1K%mu#BB^rPzyI!#C(m)&@!(G#@tpxV&Hp?7*q3t5 zRA+7wq54!bIya2PPi${7P#U!&ZY!=7BQRd4e}tfput4qN(q0=_ZXd0;P;?w=6DcAa zBqjuIwEB$LL^Elna=2ACE-GztqCmPMq>Nu8)hlTmSWX^*emu}TAXURL?Sm_>iQ$L0 zB?>A>8+SunV9c-65>{W+jC*1kY|Y3_@Q1iQ(5B<>Xk-3eER1MkMyh#JjZ2yzyY!Pq zxby($vm%Q44cl9i>m0^m86UZY;p?8%-*nep8X1Y``?#0qYgZIxNsGXO1Juy$y~N@% z)A_H;_)<~YXpbZqNaL{Ne5=OhJ4FJVCVBYtT+J%1I#)4sf;lle@XIh5&dBcY5-Q*N zVoS{Py4l86{zdNQsDAUrCC=OTNyB0PU#L?AGq$=ebjw6G_X~;F%|oukMTwD^ zo4Pes;i#+le?0KnBLH~x=hr+2VCS=&`qB`f$mp&p=Z(3-2gP5V=&88MYK|whtbEW8 z#q*NyLWte%=^zAVO`F<(3m5zLBbXg}fE{v{woK31xkSu9JY`|k5pQR+6CVGzNqfpQ6a5l2j;+I{l!zw^}c;?^ki%9jQJl9*8?ruVNODH^pYD^8OOTNA|_e?2VXX*A>hXqLm+<1}14Hf1d@0nk4sp}}Zi04Pw$p5VV)e?pFI zKa79%Z+-oiPc8OpZ5O&Yu1}_HpJ#1A^BMsG6o)vMIRV(R+c1>9 zRB#y$8M*t}2y@s}Say>JTk`LA#fl=k6#U1SaG`4ZX~=?N)35k_J|iYvP9ZGD;xHYb z*jEo8mjo^NWJ^gj$^-4mhN@Itexza}a_Vn}@2rfB zk()^9?DiYatKB6~p!D2~0n$GL2tc0C>-NXDk&)6&thMc*C|A3i(Rtr?Sic#$;V}IG zl_u7cl@sGH=rPmdsAErxpPhHNvBPu#HBcsqJ34$s_V1qQEKWqBDWO_@KRW;SCgZEE z4%C0Q0v?4ss8bou94?c^KCxqfcDXBbM+P*hCa!{+BzE6uB1aMtTXL#V-HbL6K7X?1 zJWbDAMP3xzrJ$u1%Z60VmFq^{qN7e8!^af}KC$}0ya3lVTDH>$_1Uf9usYxa2h`r@ zx3|@M-2l0Ry{0r@oPVJb)@H*$1jz{E;)%ic{DQXr?winv4pFd*#{9Zg8G~A8y_1BJ z0-UwI5LizWD>|M10m@Ohbew{@NS6jFn7xFqQtd*T=oBHZG2}Xl44hCYsAJfP27cFL2#P5w*Z;4e8q86D8yeMb-q{nwC& zZ};k2?SGA?r>8-HesvzZGqHAd+GusXYi0NBi%ie9?py+tynuRVZVq_+fq$)g1&?V$ zGS~L>{Ae}FPzbZYcU1X{GM69LKedXv)f5sc z6cBH4ykp`AXJlXl!mUAk4?kSWnjfN8fiD;Fww5*t%z>|Qh1l7036183Gsr1pmYnrg zNi;gR4doUl7(@WwLrt!#z>~K>4(~U*QE2Rnp{FK)f2jN#{}8m<;{(FE|uon=|-f3_uV={1I0TBB3gNL-#x|io?qy1p;f1MG~eAFIEJ6la3Q_&1m zf?WX)h=5*&OsD0@lv+X2acwcM@dXZN;vxSPs0CR-jqAy{~NQGjpWFapGG z?T51tre;T{?T-hFrbAwNF&!{LNQ@9z!E(os%~wKYO7*F9q_wU#(%|fa1`kRN#Lq84 z(2MF)O>o5#5M94K?>DZKZ90+3)vdL7!FED7sZCoElmKeW=2A!w;|-XQ=Sha;-Bb>* z(*x%>k7D8_G#@K(bPliKp#E;JF7*(gOQm)+99UXdKmZhx*HQU48d*KxR*xS7bax~w zIhD=%z7)7w*K^rW)?EEG<$y~82P@?xkCVdjC+}@x95#rFE@++R&=>|0_5!Z3F-vue zJ*6*Nh)~ukB_`MsShtOlrSteosj3c1b%InjE%iL=btCfcX|MFq?{D!l!)7P|rd4n9 z=JPj0mVt3K0NLGr^^)tb`Oh9}nn5kqkYuYsEIRK_$dV#2xW|s$OE!J5`Y7kSFC{NE zj&?Z3jL9rUw^&2Hy;VEkl?d@8Ycx+9SRa9l>d_v(ykx{QXH3pDYVNsci`T>7usOph zMZfn%jak@!fWBk=asw?Dm8w${zP_&g`B)}6BuzM;1 zK|uj9K|^+O4fr0eT!?H^Dmm?OY=k+mxDNgf{k?M8RJyzvtRVbC`e*g9r)E@xO^uo? zx-P?j%Hlw(UpcqjyyNPibyQWsDgaB;P$Ivb*pQ8;nIP0Ft2XB1Owe@fdH!J|C-IE? z`?!>?;C8n ztCNYHKQ=-_w$|C!He@IIFyTdRuklHNcAiubZ#Ha|iZ0z)TBJT>#Q5rn}b0IZY;x19E)qaOi*J39ux`%$t^&mEY_ zsCGa9t{&1%UWUm4nj>J**>3-Q&KHl`6Ozveg*`bYy z^m}M*r%8Ml*7K-$nJ83^wVc=*(r~Y7+ zSA|mdZz~X(gd_wSlE()?di19dn!$S4BAZmGvH8px-XQ>2Z3VZJ?R=kwJZ z`ngk@{;sLw21~zIR@}(ahX(GHJ#D+&Fvf&a%h>#p8$_L})OXMx`0MH5xcQfc) z{C9qpfo4+II^I~V1*%x+z(9%B<5K~*KpY@>lyG+Lm zggnG1(Kti@Ox#Vmb+JF(KLIY!J_nf>7d)%X29gDqHB2@Vv{os<@oF4wuDzHx-kB8; zaP8R9zoHh+#Od8EPe5L=TPdAhk&vppmG=x#IV15_K`_lM4dGK5r?QYY8pgL==6KeT z<3m&S6GApBqJxfN6jaA3N{TnKWE7~>;v4h_rM#AV6rwSH;xbF=TZ1Hd5(;wQ@C_It&=>23|16+Pvw61Q!?9rN|>k z-G5~g0ir2nTzB+-iR?NW8#Q))sJ`CTxlmsG#87tFq4v&#gIX=DRR6J7rlLF>Y1yx> z0gqPA&DrmxFE`Gr=P~L~Mn*`r;-~zlXH6s_S3y^TqeZ^gLL`!`^+>~M=dr4SJ6~=~ z>t=Orqf@GEFMCKTVsvYD)Vihe##Jh~EsV&Zy>~Xn-p4y@AWPsxg-=I+FD*KY7HM(`RmJCFiv` zZlSj3NPip8U8PTmF)JM>=M#wo`}4wZF0I}n$I`522O}awC$%Ub&WCIkL!>_Fpe1#^ z?ouKJDP=PaM><r-0FW?kBl5B@QB@Gb5MAiGm6-Hz1_L0F3x&Qwn$23gCOgD}7w zY`BK?fN7Z@QhVa4oZM6-CweDBU2?~o&{qDN(rk(%9kDBq)lOtjlu;fB$H}Bk1RQSl z7n&ZbP}E^+O-?LDU8B`DnRJH{Oxl$y)9p`A36}#LOwtug1tL&RLEagdzI~~pOT=Z) zHdz*Js1mKI{ayTKL)FE{Bh7@*zJ|{P2aMJo>jYOpM^AFo1fKaub3~OjZ^AZ&%BG4t z&bah60a9`ktJc6uYLK%&a-%@q`*3Jb+O_5ztA58lfRFS$yQwt=Ams#JN6bIV!Ry;r zj|J;?Jar}MG=Lq)Ki43|!EN<&jqmZ$@kU#ktppCd*vY85X4VaWR|EDVO#G}N0B$*X z%z&f5xjP5|nNO*jjUI?%7V*x#$jd95y1L4NOaKCh*j@=j3CXd3?Qj4x%*@iLuKxvS zRx6G%7pJ-j_%gj;ctoJiJaiC3+R{kaZ`K&`RYUhAF``!KY8LSIPj?`Dx$&hp zsVt^=NoGCtdq{;RK3x;XxRP>F<=aXs#F?U0O++V2U6D?^6LgMIiD@G41QFs=Qr~|* zePY&F8wVj%yg<;vJkZe?X_iA5G~1fH3U_CS2Rr!wocJ}+X7;2rA?5*Y=cAr zK`I)p_dCR8)WWCdW{v{pM}RGJcjq!Y#IVj&ctdXwfz6uPr4u}k5ESYG?ejtj$1GCf|g}a*UP< z7Hw~a0gcPmK_#(yqJXrivD$~}5*;5BRJk=%PoAl`4=cA9zjC@im_#b2X(kB{k&D70 zFC(VHa8hniYfm!46zV4*5spX{X|@TPrXd{*lH<2^qBYa@w%Xa2-4UHQmK4^i9APwb zUZXgOp461BU#8kmo(NE};ivwT*@44mRN6WHJFdZZKW=)Gft@JS0;Ka`x-^gBdq1cM zu!|tw*|PvW^6&(=ZfyP3cMwu8#f35{E5I~67o15dq2f(ko+;-QU4}3&Rti00{k6RXjXOQlNu> zC@r7|0)+=AroL%1s7uSTrvR#ay5T7;eGVMZ>Hq}F4m-hR;cW+qaoTbF02DnVa}a>% z^D}hs@x{c&8b8dZZn>D(8S37jHcXAkv^ZkbThraZrBymch}1&RPvu%(ibFe5q_NL4 zp=78;swc`Ad{OZe1tY@*HiBSPrKuvM9tOu*T3m3t&IkLal{IdEi=kf=;^;tb(_#xZ zJy|LN2i0Sp(U|w&@1x>5cfHt4fr~iH* z{`W7d2ey?s!>MqgJ=3MWNW^lGP0ns{Do#_o@SkJVMPnRI8>FSd3qdXRXqC*UJXw z7v-{^^clr29R;orYL0r`-H`*Dv`;CadK9mX&1_O;v2t(NHRxxXLUgRcH<8-Cmqr)DOwdl3l-(_s19s+xGVpSmZvp%+rhji7G67 z+@a-VSMAW(we`IIEo{CMB`ab3nN4HyB8ntpV{c9?+AAh*{f#O#Q^ z*T<392iCdy6}A?RN_Ji2QTaG?wwvmv$Pi*e2BBj=fda)^po%gOir;IRW34N48E4a&c1PS8(IiuAni?a? zRP*oeZhnR~iIw)jISDT@Xn24cCO##$F{oaO@9bZez~1-t+}i5oDO(e!?@Rud{eLsB zVaKy9U(`ksoe<}Y*2C}(_HO|uq-wnmJb*a&PvJSN*iUHW5#;Me2S|bdRcqzR z;+_DkFDvCWWOH#dJ^a5tvz`hKX9rDf zphW_s6e${Hv;Hj>t2Y7MaD%+Uc#%c(&mS163F`()`5BS52rsX!Em|s!Obl6;f`yoop zbn^96;;OJXqqUQ(3l|chSog#`2M%&&)oHJ_ozeLtxy&C3JqoLQ2vg<+Uh$(hOEM2A zTz)I2hd_X$Q#a=`vN{7Tbsqoav3IB>3m$hd(K8wb%2%a#3qmIGC@K zEij%OGLxnwDZ|#gA67*b7|FuVttN8^I-LKgjL zY^ZC=sR&9-9^gcURgz|iK&t0fy7(kjZJx>Buel*czg?tvf-l(5#tH*XWdcRn+gUwl z-14*jDu$9}z)ThXr5rMWbCXBJ(}LBRvV-9`^p4e zS!tXtpHpoQgXX;c0EdR{No`z!u_9=sRwmbUM+;bn+g@n^i`tC{d9V^G-Bd3E z6|PiM(ABsYroO;NyK%2SD3La`ekVBSLLgNoRl%LQV*-a_Ujip0E8FZV z*_h0;O-ZOVVNdIRMQt{=#=yPfRTnKH3tn>VZ({Bsp!CMzD9a zrtc#a`iu286R-GL_ZlRXC+M~Q)p)Q)&RG~$XAV`qs^pEvdDatdqrh{1YShhj)WSIT zJq76>0$kC2EIYa+x+}1oI~z_VWoDMmnX*3)KD#*Pmf9t6S4-l_YB?s}WUe&o^p7|w zs!spKNE4-GkPjQ6*h^hmM?#&&=%EQ8lax0@#A^tXMX+HWqmb#r6)c3_w4!(?tdSY} zBe6-puoV*-YlQqqPA1pJT?V6j_H_N`)H~JNQwHOc%Ae7oCreY-`=Gyb>-W;dIOm@$ z1e-MTaU#v+MV)QHXBo=SxqTLql;Ul!Rh(vV9>T@>s|CxVc+Gw-;)$zK+8K-GI9@c+ zQ68nzvlW4AEg21ldcI3oR;=VRBYmrMvL7Ut9!#oyhAonUl{jIGogU6i(@;p$Zu{Y@ zNN~i#-~Yjd>$|=HMAeQAf-=3(e>EJhbZpV+KdJi%*$swJiTTOw4wA_Ca0EtbI!=N?PkW^qf-3)e<~yO%g(KHOCJeC`eN=@qIk6$SE>e5GLfc zx@Jm;rMeU=Nw@vHX71Kr-R8%16;1RH;YwwT(u(*t9X<``-!xBp+n~f2B?-I&Wf|>P zFDtCjSc-B)>=XQCzB`R9WjjePHe0sRTejFK&HGu0pMfwhdgQCB3zEZ~JQ-&}otQo| zHt>Lod`f{7L`VtgpFUeuoRRPl{a>^s<;f|w=Jhrk^T@7Uy2C>MN7FS%Nzz2i9^1BU zdv+hZSe)Ktgs;j!IZf4%hj*J_jS|6yGsQ&Y2*$%TL zrq;Bmw!10WCb9b$4auGa>RSo)RTv5Sr>Pw*6lZpgk^-WaWokQNeF$ur8D?5Z!U^KgE*3Ceff6$yS zI3%GKAGGF^aB)sCM$a76`-K5*!8S3*A zSzlKWqo;36Fv1>mnj_4kX(Wsk;@!a8JZg)AGupG2hI|5G4u9qe*QDTTX|Yrf_Cm$i{1KqFARJ%7SgOqE)L7SQ+&2D#v8fqr|Q$jrOhe+w|}x zaS+m4GH%No4Mv9t)23yFD{I{LOltqkjrf~%*cM$vO;&E8-)HLU5K>8|h~kk_ZIGSB z4p&t{W;;%jgb_2gG9Plk8L>}A8v8S@oqp9K8|^nmsZwoTDYc%_BrTA6HoPE%vdY0g z=?PAAIVfzGMw88uKwy+$dcBXKz#drOBJ}0>5gmv353WD=T~L0HpMA`>FWb4C>+Pjl z5bYoA0(1JonP%sL;ZwdUEs&UE2$KrEfjvdFUF(PSX7Goa7-(0ZD@2V@gUqvZQTVw7 z82KqnGF8q>pgm4dbBs3%>H#mKYnghCt|kJQ&1S>9$@*>5zS(8VH7Eq6hXc3Kmzr7V zvwj$6I)GgMZNqEz@nL4GWM&NTxZbSiiGjT}XerTzsE5c$8hb;{`M6Ppb_G!u{fRjg zjqBP+>c)5WevbV^w(h;vS+3W>Fv&LU;rftiiMp_uyUpp z(mKAHu#)Fw?}_5CaVGq85-Af@vxsNUM-+QY77i1C2ip8kaJRFV9=b^VKj2Z>G8P&O z%(ff^_{`k^7RiU)(8WK1Fp9Kt_`qr-0~4@iBP?;{dI2I>ie z*QrF)p^!Ih{LQeV%KVt483mvO)4Mx8&)e4N+1b#!@6E_C#Dna?@^3aYD*CL%AD_E8 zS{{F^v)C*-pRa9~K)7-b7|1L>r8)b;(W8{6pRt{2ou?p+iOw){#4|v>KwB(Q!?3)d zL&mhNeeHsi(}s7GMgBzF+&^?msIgXLJ_ZSKBX>1bEh1p6&Cxhq1*q|uA@LT)W9>PJhIuXo)(y7jT;n3 zu5+NEsjY1Dm3q?9t{#nROVJFWN{Trrw=A(A%FtV8B#C;)7h?Dw?MFJClBzf?`E}7n zObYMdhY!>)fb2fkPqMmNe%aRSZe0!Vrs%(4Zp=Iw@c&SKogs3lt3i+IYCjy+xPm2} zM^rmVS9jct`3Y^eye--kzDNF0ODZiUCZD;fZHrh*NhA9?oQ$D`6!kc_^s8sljVkFe zpE)G1hG4pb-TeI10De4k$WL5d=1(@L7)!Bqim1i>Z}$k6iNdy~k(_|hg!JbyT99}- zzXid{LMVulh9@uSBR^Hpp=PRx_KC29isF2g?fRl(g(D9h(+SatsO_o6r?iVgc(05D zm!I?LaCEb*1NA)nDkz$BY7UzU3;Tg7zoSGgAQ_z7T~{6au486&_%9~CvvUq^`NaqC z%_~iMc@pw_JR-|Cm5kRnGv^4Ask=&@i*QZEf7JdJ5&4oeqt$NXjrPJq?s9nc_l_VL zVWFNh9d$LssU>Y*$RE*6HV;^;Cy}AF%I^ngLeei2nx2`Fn1&SlL1z^un>7k5q|rA%g-X#Wyu}GZ z`e(LT(p15yHHLk@Q@GBo#gWC(NS zXs*`5>MqCD6SnYk^i8YpT@VOh)w>=YMFTr{+a=Y>tuRauOj(|b~k6GvHF zYI?1^NoKfJtQpGupsnM&{;g5fMzdaW1>@+}nX5swlH@02$xV?*KnG53(!Y%$JNZ?( z(Z;mlFRCBy^5<*D{+6P6tfpMb+vH3OLVE)j=0eO>`o8A75$fwHU)MZCI@dn}n^6>X z?Ts$H+)VfEw@i>1p`pz6pz6CgkLTRq$V?Cy1e1>RGkHPybhyg4!cVx|_av0NqsM_N z)(C1d&eE4<8^GiylvSFPk*3U->M)2i*-k1bGtNveHttF$CtaVERX&5>3(mk`q;s>o z^24-ayd2TWPOXkpx+7#ISixnc#M8h$Bbb>_av|^vL0Fi_-D}fozY*J!^d3+e=S<>Y zb5O-hB9#iQAC*koM+nt{X+s6@w@fNaJ+Su8N>H9|`=+_)Nq9rBy(C*VKp z)op5NX1Oz&Ra;L^v4BIbb^G)6cb($_p>h_>=R4p=gd~P1&tT_n$OFqZ{=}B&ma^cV za4daz0QW~7TeII=%l$i6z`Mx~9t7;`ajjc_DoN~bOALy5>%hslj`er?hhlcTg;131 z`C?+H^?_j}m*kAoYJGEr2+kaC`u@Ri3lOeA@JBXH*{9ud6D$R2S~^~nGieK_!8uso zL+QVra%-aAKUpg+cm}5P8gC(|H;6}`aakI1rCF<6joA1R-3!imV^k?#Sm*8O%4iTI zVH2WtTFn>{AbZS3apbGj>kx>4wI{y;7Bp1PkhC_l%b`+V95b2SSH9)L)yylR??khf zUwqa5?MG6Fi4%azbp}o>U!0p;QV0NJM@U=IcwQ zm;e0lQh^tJA5Y<+o#X}vW$JTe2EBacrHN|S=y>7yw(@1^`(E+rD8K_*aFmCR(<5RL zCxfQko>ZGO$FH|BBLUBsH~_l35Pt{hvipTTg7iG-kt;%x^B^4?-suL0IQY#TJ?4XXnUK5$}Fi;)6xoDn#u~H&0KQE z>J)DLHRXB@s`CqAwanj}8t2X|W_;&h?Hi;9R^7evka#()>LwpbhO?B^%~o)v=Pp%(FY3f&X1g(v1k2 zgi$ch!>qas;+BsWJWnUdt{vS>$tH+CYK{7-wbpyL-=>ghVw$bilxio|1tUM1U&+f9`5FgZ)TBk`>!;!tlLUtpo z8LwNY3tgeJY0)v4r#fX!Y?%5MMchjqTgCYvU1kL8O&N!_g#B?1=FN1?8=;$kws4ab zw6!nnCGhc8epf>Msl0j@5w zIS|nTBBG6SH95!c&9|8laN`YmlSjQ+7PLn=70ByyNaIGOiS6^3jMBw7L4=ca6~a2LvZTFaLC03$~m`AbdX0q7$aSLfs5l#8iGrg zU&h&41ieApEE6Tb+Rg`W9fvlu-|aVf0U!OOP=_2TV~YLtCPg5iq)~%2NCv-DVWF-R zEx5cPx8&tSIz<0qAxszp3KoyvlrHzgrQ*$Mb9YV95=liZ31|s#xbJ@ICdX+`!B|oj zq;wS&WaU7q4WV#15;tU7CrzsNh9;YgFxl=$ix($D>q|=cLdV!x*_d~%!gPy(O3gU% z`rECS(vo35QW;yJKae8{+ZtXOHKic@)6(k~M36KNZ;x?x03RZE66l@2winq@yx2Gx z3tiA(qZ|AL-F6Q#c2Uf&e4Am5PA44BIs`a4>OFFmu8Ob%XvZOnR-V6dawGjVR4u#G z_i^bNO21w7*Y)srM?F)$+BU&j3MHjIEAxjT;}=xJrd*Q@=}Kc~jc>7W9W%8ZXA!De zPt)QPphZR`8sl)%TFAyG?-8>YH|zhULrvER)mB~O(Vjj5WSV!o%9;|hXdU~i?5--q zDuZ4~T*8OeyU~5BR%I~6h^4rx8y)0P*(0ABH#UrYLJWoFaTRM?2&@81NIpK(shh)# zut$V~AB4?#)S$WQy9o_DUCO69FjnhV`J8{(;N6DP4FJi)+!;)K2s4@a=PQ@uh5g`` z{;%-8CjwOIg;yINqz?T@8hP$3k-`Arw&K!#jiz1z4sefMIW8fg*x+WAis_YGLGW!0 zn}}$l+kIzZcU=DTEIV2;VBgR0$kvc4eqP(MAo!o@N3;8f#~6pzBa4h@#mK8RrRI!% zl9rE)iV|PUQx_eJlGHL5%Jo`JuEMqYb$gA4#k((lm6qgrM9lFJc|LZIX*62BlpQmF z&=sPxlzirmayUvYJz}orpDZ?*y%aIe^t<0#iRkW0(i*~4KjOqq4ci!etXuWG+Eg|% zX*bQ6r5nv~u4i8Gj3c-?xLdxLe3a_wR+w-8w8pf^R8F3xMEp(Q!k)aphvDh!U^lK3 zKgaT$(b2E1!Ii+_)l4J1%I`OQzGMdO)Mn)Qv06Mm?$)&m#x2+0jO^}G!XMX%tQxeU z0{P1+_q8`(6Lu$acAn( z9WwYGv3KsGURd<(6MkAdc{fGrm<_Edho3E-m@DB%;4=6`gu1&%7gTc_QWUJm;u5uE zhSu#sZ;6G0P7-ft9n(W$vSdMknR*{ryOcNTwIRb+qNoZwK zuSs7I&do~|ENjsJspj_uXE=&)eTv@6L(7C)Y!3(xO+5I^)QCRb{?uwTikw9}jX)3r`OA==|?7$?-JX@rgEL0>WWzh*{wYB($A&+@rV z$Do||qv3A<0!?|Q>J^QDA1DF<$4>)bH+idxlB+)~`00)9CfPSzga%Kyoz$hxlcw*Q z$9U42NYTK|!~OI(OEQCv|12N*CK{@`XUEmg+pQ-Y3&`H#Bu|fNwZk4qS;I=K7+m`( zLFQChNMW*JxJf%^*kQ-Y1Yw7O8Y~sU-B#GGD_23!z&MJCR;=w&@M%&H(?-y6?Gu|+ z|LI$=c%LcM7GMJb_`dW-`SiiTVa+o2(F=?&>*@kyNw39Cw2KM%py<&yDdTy)9S=Oi zvcMY>I2@N;=q;XRM^8_yT;RuZ(Y#zXJdjbw$Dd6v+AEz_^E*s$wy|`{Q6v&%oM)G9 z)P#m%-(*8D^qJ?zCr3a@r8BaeZW!82QRf%A%%*z|*+mW+3DLL4<}oNN?Z_vjBt#`)JpA`pPZEH^HjMX$Wl3p1!QhdHSn^w=MqSaucMLjAH`bX%u~^Y`XWemmw(-lG+K@Og6CNH+=GcPtk#}J& z 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 N002ovPDHLkV1iora$^7h literal 0 HcmV?d00001 diff --git a/plugins/GranularPitchShifter/help_active.png b/plugins/GranularPitchShifter/help_active.png new file mode 100755 index 0000000000000000000000000000000000000000..d68707acb4641053ae2ef08919be562367aa20fe GIT binary patch literal 5486 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 QlK=n!07*qoM6N<$f=6_Y3jhEB literal 0 HcmV?d00001 From 9a0db6a17caad806cff9be2498b515e16716fade Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:41:54 -0500 Subject: [PATCH 18/31] Fix pitch shifter glide 0 division (#7348) --- plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp index ee796d8e3..edf24c332 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp @@ -87,7 +87,7 @@ bool GranularPitchShifterEffect::processAudioBuffer(sampleFrame* buf, const fpp_ if (glide != m_oldGlide) { m_oldGlide = glide; - m_glideCoef = std::exp(-1 / (glide * m_sampleRate)); + m_glideCoef = glide > 0 ? std::exp(-1 / (glide * m_sampleRate)) : 0; } const float shapeK = cosWindowApproxK(shape); From f2fbcecc5015b63968154d5133f21b3728e08b96 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:18:24 -0500 Subject: [PATCH 19/31] Fix bad Granular Pitch Shifter init values (#7354) --- .../GranularPitchShifterEffect.cpp | 15 +++++++++++---- .../GranularPitchShifterEffect.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp index edf24c332..90c6e86d3 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp @@ -96,8 +96,8 @@ bool GranularPitchShifterEffect::processAudioBuffer(sampleFrame* buf, const fpp_ for (fpp_t f = 0; f < frames; ++f) { - const double pitch = pitchBuf ? pitchBuf->value(f) : m_granularpitchshifterControls.m_pitchModel.value(); - const double pitchSpread = (pitchSpreadBuf ? pitchSpreadBuf->value(f) : m_granularpitchshifterControls.m_pitchSpreadModel.value()) * 0.5f; + const double pitch = (pitchBuf ? pitchBuf->value(f) : m_granularpitchshifterControls.m_pitchModel.value()) * (1. / 12.); + const double pitchSpread = (pitchSpreadBuf ? pitchSpreadBuf->value(f) : m_granularpitchshifterControls.m_pitchSpreadModel.value()) * (1. / 24.); // interpolate pitch depending on glide for (int i = 0; i < 2; ++i) @@ -118,8 +118,8 @@ bool GranularPitchShifterEffect::processAudioBuffer(sampleFrame* buf, const fpp_ m_updatePitches = false; std::array speed = { - std::exp2(m_truePitch[0] * (1. / 12.)), - std::exp2(m_truePitch[1] * (1. / 12.)) + std::exp2(m_truePitch[0]), + std::exp2(m_truePitch[1]) }; std::array ratio = { speed[0] / m_speed[0], @@ -274,6 +274,13 @@ void GranularPitchShifterEffect::changeSampleRate() m_grains.reserve(8);// arbitrary m_dcCoeff = std::exp(-2.0 * F_PI * DcRemovalHz / m_sampleRate); + + const double pitch = m_granularpitchshifterControls.m_pitchModel.value() * (1. / 12.); + const double pitchSpread = m_granularpitchshifterControls.m_pitchSpreadModel.value() * (1. / 24.); + m_truePitch[0] = pitch - pitchSpread; + m_truePitch[1] = pitch + pitchSpread; + m_speed[0] = std::exp2(m_truePitch[0]); + m_speed[1] = std::exp2(m_truePitch[1]); } diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h index 111d0538d..a50ea8238 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h @@ -168,7 +168,7 @@ private: int m_ringBufLength = 0; int m_writePoint = 0; int m_grainCount = 0; - int m_timeSinceLastGrain = 0; + int m_timeSinceLastGrain = 999999999; double m_oldGlide = -1; double m_glideCoef = 0; From 7c74fbc8c56c60df0afa3668376cad29ad292d78 Mon Sep 17 00:00:00 2001 From: Andrew Wiltshire <62200778+AW1534@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:29:33 +0100 Subject: [PATCH 20/31] Capitalise root sidebar widget (#7350) Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> --- src/gui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3522d0e2d..d534be96f 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -135,7 +135,7 @@ MainWindow::MainWindow() : embed::getIconPixmap("home").transformed(QTransform().rotate(90)), splitter, false)); QStringList root_paths; - QString title = tr( "Root directory" ); + QString title = tr("Root Directory"); bool dirs_as_items = false; #ifdef LMMS_BUILD_APPLE From 118ca4e9a23581b2465e412d0d6d0b06c99e13f6 Mon Sep 17 00:00:00 2001 From: FyiurAmron Date: Fri, 28 Jun 2024 17:16:44 +0200 Subject: [PATCH 21/31] Cleanup of MinGW-related scripts (#7327) Consolidate and simplify mingw-related scripts. Remove support for outdated Ubuntu versions. --- .github/workflows/build.yml | 13 +++-- cmake/build_win32.sh | 40 ------------- cmake/build_win64.sh | 3 - cmake/toolchains/MinGW-W64-32.cmake | 6 ++ cmake/toolchains/MinGW-W64-64.cmake | 9 +++ cmake/toolchains/Ubuntu-MinGW-W64-32.cmake | 2 - cmake/toolchains/Ubuntu-MinGW-W64-64.cmake | 4 -- .../toolchains/Ubuntu-MinGW-X-Trusty-32.cmake | 3 - .../toolchains/Ubuntu-MinGW-X-Trusty-64.cmake | 9 --- cmake/toolchains/common/MinGW-W64.cmake | 24 ++++++++ .../toolchains/common/Ubuntu-MinGW-W64.cmake | 17 ------ .../common/Ubuntu-MinGW-X-Trusty.cmake | 58 ------------------- cmake/toolchains/common/Win32.cmake | 6 -- cmake/toolchains/common/Win64.cmake | 7 --- cmake/toolchains/common/WinCrossCompile.cmake | 9 --- 15 files changed, 48 insertions(+), 162 deletions(-) delete mode 100755 cmake/build_win32.sh delete mode 100755 cmake/build_win64.sh create mode 100644 cmake/toolchains/MinGW-W64-32.cmake create mode 100644 cmake/toolchains/MinGW-W64-64.cmake delete mode 100644 cmake/toolchains/Ubuntu-MinGW-W64-32.cmake delete mode 100644 cmake/toolchains/Ubuntu-MinGW-W64-64.cmake delete mode 100644 cmake/toolchains/Ubuntu-MinGW-X-Trusty-32.cmake delete mode 100644 cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake create mode 100644 cmake/toolchains/common/MinGW-W64.cmake delete mode 100644 cmake/toolchains/common/Ubuntu-MinGW-W64.cmake delete mode 100644 cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake delete mode 100644 cmake/toolchains/common/Win32.cmake delete mode 100644 cmake/toolchains/common/Win64.cmake delete mode 100644 cmake/toolchains/common/WinCrossCompile.cmake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 11094720a..db397d848 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,8 +37,10 @@ jobs: run: | ccache --zero-stats source /opt/qt5*/bin/qt5*-env.sh || true - mkdir build && cd build - cmake .. $CMAKE_OPTS -DCMAKE_INSTALL_PREFIX=./install + cmake -S . \ + -B build \ + -DCMAKE_INSTALL_PREFIX=./install \ + $CMAKE_OPTS - name: Build run: cmake --build build - name: Run tests @@ -200,8 +202,11 @@ jobs: - name: Configure run: | ccache --zero-stats - mkdir build && cd build - ../cmake/build_win${{ matrix.arch }}.sh + cmake -S . \ + -B build \ + -DCMAKE_INSTALL_PREFIX=./install \ + -DCMAKE_TOOLCHAIN_FILE="./cmake/toolchains/MinGW-W64-${{ matrix.arch }}.cmake" \ + $CMAKE_OPTS - name: Build run: cmake --build build - name: Package diff --git a/cmake/build_win32.sh b/cmake/build_win32.sh deleted file mode 100755 index bccda3a48..000000000 --- a/cmake/build_win32.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# Accomodate both linux windows mingw locations -if [ -z "$ARCH" ]; then - ARCH=32 -fi - -MINGW=/mingw$ARCH - -if [ -z "$MSYSCON" ]; then - MINGW=/opt$MINGW - - DISTRO=$(lsb_release -si) - DISTRO_VERSION=$(lsb_release -sr) - - if [ "$DISTRO" != "Ubuntu" ]; then - echo "This script only supports Ubuntu" - exit 1 - fi - - if [ "$DISTRO_VERSION" == "14.04" ]; then - TOOLCHAIN="$DIR/toolchains/Ubuntu-MinGW-X-Trusty-$ARCH.cmake" - else - TOOLCHAIN="$DIR/toolchains/Ubuntu-MinGW-W64-$ARCH.cmake" - fi -else - TOOLCHAIN="$DIR/toolchains/MSYS-$ARCH.cmake" -fi - -export PATH=$MINGW/bin:$PATH -export CXXFLAGS="$CFLAGS" -if [ "$ARCH" == "32" ]; then - export CFLAGS="-march=pentium4 -mtune=generic -mpreferred-stack-boundary=5 -mfpmath=sse" -fi - -CMAKE_OPTS="-DCMAKE_PREFIX_PATH=$MINGW $CMAKE_OPTS" - -# shellcheck disable=SC2086 -cmake "$DIR/.." -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" $CMAKE_OPTS diff --git a/cmake/build_win64.sh b/cmake/build_win64.sh deleted file mode 100755 index 8dabe09f8..000000000 --- a/cmake/build_win64.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -ARCH=64 "$DIR/build_win32.sh" diff --git a/cmake/toolchains/MinGW-W64-32.cmake b/cmake/toolchains/MinGW-W64-32.cmake new file mode 100644 index 000000000..acbdef8dd --- /dev/null +++ b/cmake/toolchains/MinGW-W64-32.cmake @@ -0,0 +1,6 @@ + +set(WIN64 FALSE) + +set(CMAKE_SYSTEM_PROCESSOR i686) + +include(${CMAKE_CURRENT_LIST_DIR}/common/MinGW-W64.cmake) diff --git a/cmake/toolchains/MinGW-W64-64.cmake b/cmake/toolchains/MinGW-W64-64.cmake new file mode 100644 index 000000000..b3cf59b47 --- /dev/null +++ b/cmake/toolchains/MinGW-W64-64.cmake @@ -0,0 +1,9 @@ + +set(WIN64 TRUE) + +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_SYSTEM_PROCESSOR32 i686) + +set(CMAKE_TOOLCHAIN_FILE_32 "${CMAKE_CURRENT_LIST_DIR}/MinGW-W64-32.cmake") + +include(${CMAKE_CURRENT_LIST_DIR}/common/MinGW-W64.cmake) diff --git a/cmake/toolchains/Ubuntu-MinGW-W64-32.cmake b/cmake/toolchains/Ubuntu-MinGW-W64-32.cmake deleted file mode 100644 index 6f7ec6f23..000000000 --- a/cmake/toolchains/Ubuntu-MinGW-W64-32.cmake +++ /dev/null @@ -1,2 +0,0 @@ -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Win32.cmake) -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Ubuntu-MinGW-W64.cmake) diff --git a/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake b/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake deleted file mode 100644 index a1b33ec67..000000000 --- a/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake +++ /dev/null @@ -1,4 +0,0 @@ -SET(CMAKE_TOOLCHAIN_FILE_32 "${CMAKE_CURRENT_LIST_DIR}/Ubuntu-MinGW-W64-32.cmake") - -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Win64.cmake) -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Ubuntu-MinGW-W64.cmake) diff --git a/cmake/toolchains/Ubuntu-MinGW-X-Trusty-32.cmake b/cmake/toolchains/Ubuntu-MinGW-X-Trusty-32.cmake deleted file mode 100644 index 0103d35e7..000000000 --- a/cmake/toolchains/Ubuntu-MinGW-X-Trusty-32.cmake +++ /dev/null @@ -1,3 +0,0 @@ -SET(MINGW_PREFIX /opt/mingw32) - -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Ubuntu-MinGW-X-Trusty.cmake) diff --git a/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake b/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake deleted file mode 100644 index 0f448fef5..000000000 --- a/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake +++ /dev/null @@ -1,9 +0,0 @@ -SET(MINGW_PREFIX /opt/mingw64) -SET(MINGW_PREFIX32 /opt/mingw32) - -SET(WIN64 TRUE) - -SET(CMAKE_TOOLCHAIN_FILE_32 "${CMAKE_CURRENT_LIST_DIR}/Ubuntu-MinGW-X-Trusty-32.cmake") -SET(CMAKE_PREFIX_PATH_32 "${MINGW_PREFIX32}") - -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Ubuntu-MinGW-X-Trusty.cmake) diff --git a/cmake/toolchains/common/MinGW-W64.cmake b/cmake/toolchains/common/MinGW-W64.cmake new file mode 100644 index 000000000..11b6a92d4 --- /dev/null +++ b/cmake/toolchains/common/MinGW-W64.cmake @@ -0,0 +1,24 @@ +# Toolchain for MinGW compiler + +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_VERSION 1) + +set(TOOLCHAIN_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32) +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) +set(ENV{PKG_CONFIG} /usr/bin/${TOOLCHAIN_PREFIX}-pkg-config) + +if(WIN64) + set(TOOLCHAIN_PREFIX32 ${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32) + set(CMAKE_C_COMPILER32 ${TOOLCHAIN_PREFIX32}-gcc) + set(CMAKE_CXX_COMPILER32 ${TOOLCHAIN_PREFIX32}-g++) +endif() + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# Search for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake b/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake deleted file mode 100644 index 2f78a441e..000000000 --- a/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# Toolchain for Ubuntu MinGw compiler shipped with the mingw-w64 and -# g++-mingw-w64 packages -SET(TOOLCHAIN_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32) -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) - -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) -SET(ENV{PKG_CONFIG} /usr/bin/${TOOLCHAIN_PREFIX}-pkg-config) - -IF(WIN64) - SET(TOOLCHAIN_PREFIX32 ${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32) - SET(CMAKE_C_COMPILER32 ${TOOLCHAIN_PREFIX32}-gcc) - SET(CMAKE_CXX_COMPILER32 ${TOOLCHAIN_PREFIX32}-g++) -ENDIF() - -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/WinCrossCompile.cmake) diff --git a/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake b/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake deleted file mode 100644 index 686f4497f..000000000 --- a/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake +++ /dev/null @@ -1,58 +0,0 @@ -IF(WIN64) - INCLUDE(${CMAKE_CURRENT_LIST_DIR}/Win64.cmake) -ELSE() - INCLUDE(${CMAKE_CURRENT_LIST_DIR}/Win32.cmake) -ENDIF() -INCLUDE(${CMAKE_CURRENT_LIST_DIR}/WinCrossCompile.cmake) - -# The target environment -SET(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX}) -SET(CMAKE_INSTALL_PREFIX ${MINGW_PREFIX}) - -# Linux mingw requires explicitly defined tools to prevent clash with native system tools -SET(MINGW_TOOL_PREFIX ${MINGW_PREFIX}/bin/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-) - -# Specify the cross compiler -SET(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc) -SET(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++) -SET(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres) - -# Mingw tools -SET(STRIP ${MINGW_TOOL_PREFIX}strip) -SET(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config) - -# For 32-bit vst support -IF(WIN64) - # Specify the 32-bit cross compiler - SET(MINGW_TOOL_PREFIX32 ${MINGW_PREFIX32}/bin/${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32-) - SET(CMAKE_C_COMPILER32 ${MINGW_TOOL_PREFIX32}gcc) - SET(CMAKE_CXX_COMPILER32 ${MINGW_TOOL_PREFIX32}g++) -ENDIF() - -INCLUDE_DIRECTORIES(${MINGW_PREFIX}/include) - -LINK_DIRECTORIES(${MINGW_PREFIX}/lib ${MINGW_PREFIX}/bin) - -# Qt tools -SET(QT_BINARY_DIR ${MINGW_PREFIX}/bin) -SET(QT_QMAKE_EXECUTABLE ${QT_BINARY_DIR}/qmake) - -# Echo modified cmake vars to screen for debugging purposes -IF(NOT DEFINED ENV{MINGW_DEBUG_INFO}) - MESSAGE("") - MESSAGE("Custom cmake vars: (blank = system default)") - MESSAGE("-----------------------------------------") - MESSAGE("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}") - MESSAGE("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}") - MESSAGE("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}") - MESSAGE("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}") - MESSAGE("* MINGW_TOOL_PREFIX32 : ${MINGW_TOOL_PREFIX32}") - MESSAGE("* CMAKE_C_COMPILER32 : ${CMAKE_C_COMPILER32}") - MESSAGE("* CMAKE_CXX_COMPILER32 : ${CMAKE_CXX_COMPILER32}") - MESSAGE("* STRIP : ${STRIP}") - MESSAGE("* QT_BINARY_DIR : ${QT_BINARY_DIR}") - MESSAGE("* QT_QMAKE_EXECUTABLE : ${QT_QMAKE_EXECUTABLE}") - MESSAGE("") - # So that the debug info only appears once - SET(ENV{MINGW_DEBUG_INFO} SHOWN) -ENDIF() diff --git a/cmake/toolchains/common/Win32.cmake b/cmake/toolchains/common/Win32.cmake deleted file mode 100644 index bc20775d6..000000000 --- a/cmake/toolchains/common/Win32.cmake +++ /dev/null @@ -1,6 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Windows) -SET(CMAKE_SYSTEM_VERSION 1) - -SET(CMAKE_SYSTEM_PROCESSOR i686) - -SET(WIN64 FALSE) diff --git a/cmake/toolchains/common/Win64.cmake b/cmake/toolchains/common/Win64.cmake deleted file mode 100644 index 155a658f4..000000000 --- a/cmake/toolchains/common/Win64.cmake +++ /dev/null @@ -1,7 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Windows) -SET(CMAKE_SYSTEM_VERSION 1) - -SET(CMAKE_SYSTEM_PROCESSOR x86_64) -SET(CMAKE_SYSTEM_PROCESSOR32 i686) - -SET(WIN64 TRUE) diff --git a/cmake/toolchains/common/WinCrossCompile.cmake b/cmake/toolchains/common/WinCrossCompile.cmake deleted file mode 100644 index a2d6ff2e9..000000000 --- a/cmake/toolchains/common/WinCrossCompile.cmake +++ /dev/null @@ -1,9 +0,0 @@ -# Required by cmake if `uname -s` is inadaquate -SET(CMAKE_SYSTEM_NAME Windows) -SET(CMAKE_SYSTEM_VERSION 1) - -# Search for programs in the build host directories -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -# For libraries and headers in the target directories -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file From a0fbd7e7b4ba54b3e8ab3649031c10a27efb1716 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Sun, 30 Jun 2024 06:37:38 -0500 Subject: [PATCH 22/31] Initialize LOMM arrays (#7355) Fixes LOMM distortion and delay bug. --- plugins/LOMM/LOMM.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/LOMM/LOMM.cpp b/plugins/LOMM/LOMM.cpp index e24171cea..72478f6b5 100644 --- a/plugins/LOMM/LOMM.cpp +++ b/plugins/LOMM/LOMM.cpp @@ -64,14 +64,10 @@ LOMMEffect::LOMMEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* { autoQuitModel()->setValue(autoQuitModel()->maxValue()); - m_yL[0][0] = m_yL[0][1] = LOMM_MIN_FLOOR; - m_yL[1][0] = m_yL[1][1] = LOMM_MIN_FLOOR; - m_yL[2][0] = m_yL[2][1] = LOMM_MIN_FLOOR; - m_ap.setFilterType(BasicFilters<2>::FilterType::AllPass); connect(Engine::audioEngine(), SIGNAL(sampleRateChanged()), this, SLOT(changeSampleRate())); - emit changeSampleRate(); + changeSampleRate(); } void LOMMEffect::changeSampleRate() @@ -97,6 +93,11 @@ void LOMMEffect::changeSampleRate() m_scLookBuf[j][i].resize(m_lookBufLength, LOMM_MIN_FLOOR); } } + + std::fill(m_yL.begin(), m_yL.end(), std::array{LOMM_MIN_FLOOR, LOMM_MIN_FLOOR}); + m_rms = m_gainResult = m_displayIn = m_displayOut = m_prevOut = m_yL; + m_crestPeakVal[0] = m_crestPeakVal[1] = LOMM_MIN_FLOOR; + m_crestRmsVal = m_crestFactorVal = m_crestPeakVal; } From 286e62adf5561f0cb221b01fcb0608fa0f6db35b Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 30 Jun 2024 20:21:19 +0200 Subject: [PATCH 23/31] Simplify sample frame operations (make it a class) (#7156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove the struct StereoSample Remove the struct `StereoSample`. Let `AudioEngine::getPeakValues` return a `sampleFrame` instead. Adjust the calls in `Mixer` and `Oscilloscope`. * Simplify AudioEngine::getPeakValues * Remove surroundSampleFrame Some code assumes that `surroundSampleFrame` is interchangeable with `sampleFrame`. Thus, if the line `#define LMMS_DISABLE_SURROUND` is commented out in `lmms_basics.h` then the code does not compile anymore because `surroundSampleFrame` now is defined to be an array with four values instead of two. There also does not seem to be any support for surround sound (four channels instead of two) in the application. The faders and mixers do not seem to support more that two channels and the instruments and effects all expect a `sampleFrame`, i.e. stereo channels. It therefore makes sense to remove the "feature" because it also hinders the improvement of `sampleFrame`, e.g. by making it a class with some convenience methods that act on `sampleFrame` instances. All occurrences of `surroundSampleFrame` are replaced with `sampleFrame`. The version of `BufferManager::clear` that takes a `surroundSampleFrame` is removed completely. The define `SURROUND_CHANNELS` is removed. All its occurrences are replaced with `DEFAULT_CHANNELS`. Most of the audio devices classes, i.e. classes that inherit from `AudioDevice`, now clamp the configuration parameter between two values of `DEFAULT_CHANNELS`. This can be improved/streamlined later. `BYTES_PER_SURROUND_FRAME` has been removed as it was not used anywhere anyway. * Make sampleFrame a class Make `sampleFrame` a class with several convenience methods. As a first step and demonstration adjust the follow methods to make use of the new functionality: * `AudioEngine::getPeakValues`: Much more concise now. * `lmms::MixHelpers::sanitize`: Better structure, better readable, less dereferencing and juggling with indices. * `AddOp`, `AddMultipliedOp`, `multiply`: Make use of operators. Might become superfluous in the future. * More operators and methods for sampleFrame Add some more operators and methods to `sampleFrame`: * Constructor which initializes both channels from a single sample value * Assignment operator from a single sample value * Addition/multiplication operators * Scalar product Adjust some more plugins to the new functionality of `sampleFrame`. * Adjust DelayEffect to methods in sampleFrame * Use composition instead of inheritance Using inheritance was the quickest way to enable adding methods to `sampleFrame` without having to reimpement much of `std::array`s interface. This is changed with this commit. The array is now a member of `sampleFrame` and the interface is extended with the necessary methods `data` and the index operator. An `average` method was added so that no iterators need to be implemented (see changes in `SampleWaveform.cpp`). * Apply suggestions from code review Apply Veratil's suggestions from the code review Co-authored-by: Kevin Zander * Fix warnings: zeroing non-trivial type Fix several warnings of the following form: Warnung: »void* memset(void*, int, size_t)« Säubern eines Objekts von nichttrivialem Typ »class lmms::sampleFrame«; use assignment or value-initialization instead [-Wclass-memaccess] * Remove unnecessary reinterpret_casts Remove some unnecessary reinterpret_casts with regards to `sampleFrame` buffers. `PlayHandle::m_playHandleBuffer` already is a `sampleFrame*` and does not need a reinterpret_cast anymore. In `LadspaEffect::processAudioBuffer` the `QVarLengthArray` is now directly initialized as an array of `sampleFrame` instances. I guess in both places the `sampleFrame` previously was a `surroundSampleFrame` which has been removed. * Clean up zeroSampleFrames code * Fix warnings in RemotePlugin Fix some warnings related to calls to `memcpy` in conjunction with`sampleFrame` which is now a class. Add the helper functions `copyToSampleFrames` and `copyFromSampleFrames` and use them. The first function copies data from a `float` buffer into a `sampleFrame` buffer and the second copies vice versa. * Rename "sampleFrame" to "SampleFrame" Uppercase the name of `sampleFrame` so that it uses UpperCamelCase convention. * Move SampleFrame into its own file Move the class `SampleFrame` into its own class and remove it from `lmms_basics.h`. Add forward includes to all headers where possible or include the `SampleFrame` header if it's not just referenced but used. Add include to all cpp files where necessary. It's a bit surprising that the `SampleFrame` header does not need to be included much more often in the implementation/cpp files. This is an indicator that it seems to be included via an include chain that at one point includes one of the headers where an include instead of a forward declaration had to be added in this commit. * Return reference for += and *= Return a reference for the compound assignment operators `+=` and `-=`. * Explicit float constructor Make the constructor that takes a `float` explicit. Remove the assignment operator that takes a `float`. Clients must use the explicit `float` constructor and assign the result. Adjust the code in "BitInvader" accordingly. * Use std::fill in zeroSampleFrames * Use zeroSampleFrames in sanitize * Replace max with absMax Replace `SampleFrame::max` with `SampleFrame::absMax`. Use `absMax` in `DelayEffect::processAudioBuffer`. This should also fix a buggy implementation of the peak computation. Add the function `getAbsPeakValues`. It computes the absolute peak values for a buffer. Remove `AudioEngine::getPeakValues`. It's not really the business of the audio engine. Let `Mixer` and `Oscilloscope` use `getAbsPeakValues`. * Replace scalarProduct Replace the rather mathematical method `scalarProduct` with `sumOfSquaredAmplitudes`. It was always called on itself anyway. * Remove comment/TODO * Simplify sanitize Simplify the `sanitize` function by getting rid of the `bool found` and by zeroing the buffer as soon as a problem is found. * Put pointer symbols next to type * Code review adjustments * Remove "#pragme once" * Adjust name of include guard * Remove superfluous includes (leftovers from previous code changes) --------- Co-authored-by: Kevin Zander --- include/AudioDevice.h | 9 +- include/AudioDummy.h | 2 +- include/AudioEngine.h | 33 +-- include/AudioFileFlac.h | 2 +- include/AudioFileMP3.h | 2 +- include/AudioFileOgg.h | 2 +- include/AudioFileWave.h | 2 +- include/AudioJack.h | 2 +- include/AudioPort.h | 4 +- include/AudioPortAudio.h | 2 +- include/AudioSampleRecorder.h | 4 +- include/AudioSdl.h | 2 +- include/AudioSoundIo.h | 2 +- include/BufferManager.h | 12 +- include/DspEffectLibrary.h | 13 +- include/DummyEffect.h | 2 +- include/DummyInstrument.h | 5 +- include/Effect.h | 14 +- include/EffectChain.h | 3 +- include/Instrument.h | 9 +- include/InstrumentPlayHandle.h | 2 +- include/InstrumentSoundShaping.h | 3 +- include/InstrumentTrack.h | 4 +- include/Lv2ControlBase.h | 5 +- include/Lv2Ports.h | 7 +- include/Lv2Proc.h | 5 +- include/MixHelpers.h | 30 +-- include/Mixer.h | 6 +- include/NotePlayHandle.h | 2 +- include/Oscillator.h | 28 +-- include/Oscilloscope.h | 11 +- include/PlayHandle.h | 7 +- include/PresetPreviewPlayHandle.h | 2 +- include/RemotePlugin.h | 3 +- include/RemotePluginClient.h | 10 +- include/RingBuffer.h | 29 +-- include/Sample.h | 8 +- include/SampleBuffer.h | 26 +- include/SampleDecoder.h | 3 +- include/SampleFrame.h | 229 ++++++++++++++++++ include/SamplePlayHandle.h | 2 +- include/SampleRecordHandle.h | 6 +- include/SampleWaveform.h | 2 +- include/SweepOscillator.h | 2 +- include/lmms_basics.h | 17 +- plugins/Amplifier/Amplifier.cpp | 14 +- plugins/Amplifier/Amplifier.h | 2 +- .../AudioFileProcessor/AudioFileProcessor.cpp | 4 +- .../AudioFileProcessor/AudioFileProcessor.h | 2 +- plugins/BassBooster/BassBooster.cpp | 26 +- plugins/BassBooster/BassBooster.h | 2 +- plugins/BitInvader/BitInvader.cpp | 8 +- plugins/BitInvader/BitInvader.h | 2 +- plugins/Bitcrush/Bitcrush.cpp | 4 +- plugins/Bitcrush/Bitcrush.h | 4 +- plugins/CarlaBase/Carla.cpp | 4 +- plugins/CarlaBase/Carla.h | 2 +- plugins/Compressor/Compressor.cpp | 2 +- plugins/Compressor/Compressor.h | 4 +- plugins/CrossoverEQ/CrossoverEQ.cpp | 10 +- plugins/CrossoverEQ/CrossoverEQ.h | 8 +- plugins/Delay/DelayEffect.cpp | 35 +-- plugins/Delay/DelayEffect.h | 2 +- plugins/Delay/StereoDelay.cpp | 6 +- plugins/Delay/StereoDelay.h | 6 +- plugins/Dispersion/Dispersion.cpp | 2 +- plugins/Dispersion/Dispersion.h | 2 +- plugins/DualFilter/DualFilter.cpp | 2 +- plugins/DualFilter/DualFilter.h | 2 +- .../DynamicsProcessor/DynamicsProcessor.cpp | 2 +- plugins/DynamicsProcessor/DynamicsProcessor.h | 2 +- plugins/Eq/EqEffect.cpp | 6 +- plugins/Eq/EqEffect.h | 4 +- plugins/Eq/EqFilter.h | 2 +- plugins/Eq/EqSpectrumView.cpp | 2 +- plugins/Eq/EqSpectrumView.h | 3 +- plugins/Flanger/FlangerEffect.cpp | 2 +- plugins/Flanger/FlangerEffect.h | 2 +- plugins/FreeBoy/FreeBoy.cpp | 2 +- plugins/FreeBoy/FreeBoy.h | 2 +- plugins/GigPlayer/GigPlayer.cpp | 12 +- plugins/GigPlayer/GigPlayer.h | 8 +- .../GranularPitchShifterEffect.cpp | 2 +- .../GranularPitchShifterEffect.h | 2 +- plugins/Kicker/Kicker.cpp | 2 +- plugins/Kicker/Kicker.h | 2 +- plugins/Kicker/KickerOsc.h | 2 +- plugins/LOMM/LOMM.cpp | 2 +- plugins/LOMM/LOMM.h | 2 +- plugins/LadspaEffect/LadspaEffect.cpp | 8 +- plugins/LadspaEffect/LadspaEffect.h | 2 +- plugins/Lb302/Lb302.cpp | 6 +- plugins/Lb302/Lb302.h | 6 +- plugins/Lv2Effect/Lv2Effect.cpp | 2 +- plugins/Lv2Effect/Lv2Effect.h | 4 +- plugins/Lv2Instrument/Lv2Instrument.cpp | 4 +- plugins/Lv2Instrument/Lv2Instrument.h | 4 +- plugins/Monstro/Monstro.cpp | 4 +- plugins/Monstro/Monstro.h | 4 +- plugins/MultitapEcho/MultitapEcho.cpp | 6 +- plugins/MultitapEcho/MultitapEcho.h | 6 +- plugins/Nes/Nes.cpp | 4 +- plugins/Nes/Nes.h | 4 +- plugins/OpulenZ/OpulenZ.cpp | 2 +- plugins/OpulenZ/OpulenZ.h | 2 +- plugins/Organic/Organic.cpp | 2 +- plugins/Organic/Organic.h | 2 +- plugins/Patman/Patman.cpp | 6 +- plugins/Patman/Patman.h | 2 +- .../PeakControllerEffect.cpp | 2 +- .../PeakControllerEffect.h | 2 +- plugins/ReverbSC/ReverbSC.cpp | 2 +- plugins/ReverbSC/ReverbSC.h | 2 +- plugins/Sf2Player/Sf2Player.cpp | 10 +- plugins/Sf2Player/Sf2Player.h | 6 +- plugins/Sfxr/Sfxr.cpp | 8 +- plugins/Sfxr/Sfxr.h | 4 +- plugins/Sid/SidInstrument.cpp | 2 +- plugins/Sid/SidInstrument.h | 2 +- plugins/SlicerT/SlicerT.cpp | 2 +- plugins/SlicerT/SlicerT.h | 2 +- plugins/SpectrumAnalyzer/Analyzer.cpp | 2 +- plugins/SpectrumAnalyzer/Analyzer.h | 4 +- plugins/SpectrumAnalyzer/DataprocLauncher.h | 4 +- plugins/SpectrumAnalyzer/SaProcessor.cpp | 4 +- plugins/SpectrumAnalyzer/SaProcessor.h | 4 +- plugins/StereoEnhancer/StereoEnhancer.cpp | 4 +- plugins/StereoEnhancer/StereoEnhancer.h | 4 +- plugins/StereoMatrix/StereoMatrix.cpp | 2 +- plugins/StereoMatrix/StereoMatrix.h | 2 +- plugins/Stk/Mallets/Mallets.cpp | 2 +- plugins/Stk/Mallets/Mallets.h | 2 +- plugins/TripleOscillator/TripleOscillator.cpp | 2 +- plugins/TripleOscillator/TripleOscillator.h | 2 +- plugins/Vectorscope/VectorView.cpp | 2 +- plugins/Vectorscope/VectorView.h | 7 +- plugins/Vectorscope/Vectorscope.cpp | 2 +- plugins/Vectorscope/Vectorscope.h | 6 +- plugins/Vestige/Vestige.cpp | 2 +- plugins/Vestige/Vestige.h | 2 +- plugins/Vibed/Vibed.cpp | 2 +- plugins/Vibed/Vibed.h | 2 +- plugins/VstBase/RemoteVstPlugin.cpp | 4 +- plugins/VstEffect/VstEffect.cpp | 8 +- plugins/VstEffect/VstEffect.h | 2 +- plugins/Watsyn/Watsyn.cpp | 16 +- plugins/Watsyn/Watsyn.h | 10 +- plugins/WaveShaper/WaveShaper.cpp | 2 +- plugins/WaveShaper/WaveShaper.h | 2 +- plugins/Xpressive/ExprSynth.cpp | 3 +- plugins/Xpressive/ExprSynth.h | 3 +- plugins/Xpressive/Xpressive.cpp | 2 +- plugins/Xpressive/Xpressive.h | 2 +- plugins/ZynAddSubFx/LocalZynAddSubFx.cpp | 3 +- plugins/ZynAddSubFx/LocalZynAddSubFx.h | 4 +- plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp | 2 +- plugins/ZynAddSubFx/ZynAddSubFx.cpp | 2 +- plugins/ZynAddSubFx/ZynAddSubFx.h | 2 +- src/core/AudioEngine.cpp | 52 +--- src/core/BufferManager.cpp | 20 +- src/core/Effect.cpp | 5 +- src/core/EffectChain.cpp | 2 +- src/core/Instrument.cpp | 8 +- src/core/InstrumentPlayHandle.cpp | 2 +- src/core/InstrumentSoundShaping.cpp | 2 +- src/core/MixHelpers.cpp | 99 ++++---- src/core/Mixer.cpp | 14 +- src/core/NotePlayHandle.cpp | 2 +- src/core/Oscillator.cpp | 28 +-- src/core/PlayHandle.cpp | 4 +- src/core/PresetPreviewPlayHandle.cpp | 2 +- src/core/RemotePlugin.cpp | 13 +- src/core/RingBuffer.cpp | 76 +++--- src/core/Sample.cpp | 10 +- src/core/SampleBuffer.cpp | 10 +- src/core/SampleDecoder.cpp | 6 +- src/core/SamplePlayHandle.cpp | 10 +- src/core/SampleRecordHandle.cpp | 10 +- src/core/audio/AudioAlsa.cpp | 4 +- src/core/audio/AudioDevice.cpp | 10 +- src/core/audio/AudioFileFlac.cpp | 2 +- src/core/audio/AudioFileMP3.cpp | 4 +- src/core/audio/AudioFileOgg.cpp | 2 +- src/core/audio/AudioFileWave.cpp | 2 +- src/core/audio/AudioJack.cpp | 6 +- src/core/audio/AudioOss.cpp | 6 +- src/core/audio/AudioPortAudio.cpp | 8 +- src/core/audio/AudioPulseAudio.cpp | 8 +- src/core/audio/AudioSampleRecorder.cpp | 6 +- src/core/audio/AudioSdl.cpp | 14 +- src/core/audio/AudioSndio.cpp | 6 +- src/core/audio/AudioSoundIo.cpp | 4 +- src/core/lv2/Lv2ControlBase.cpp | 4 +- src/core/lv2/Lv2Ports.cpp | 7 +- src/core/lv2/Lv2Proc.cpp | 4 +- src/gui/AudioAlsaSetupWidget.cpp | 2 +- src/gui/SampleWaveform.cpp | 2 +- src/gui/widgets/Oscilloscope.cpp | 20 +- src/tracks/InstrumentTrack.cpp | 4 +- 199 files changed, 879 insertions(+), 668 deletions(-) create mode 100644 include/SampleFrame.h diff --git a/include/AudioDevice.h b/include/AudioDevice.h index 577bb7d0e..376aee26b 100644 --- a/include/AudioDevice.h +++ b/include/AudioDevice.h @@ -37,6 +37,7 @@ namespace lmms class AudioEngine; class AudioPort; +class SampleFrame; class AudioDevice @@ -92,14 +93,14 @@ public: protected: // subclasses can re-implement this for being used in conjunction with // processNextBuffer() - virtual void writeBuffer(const surroundSampleFrame* /* _buf*/, const fpp_t /*_frames*/) {} + virtual void writeBuffer(const SampleFrame* /* _buf*/, const fpp_t /*_frames*/) {} // called by according driver for fetching new sound-data - fpp_t getNextBuffer( surroundSampleFrame * _ab ); + fpp_t getNextBuffer(SampleFrame* _ab); // convert a given audio-buffer to a buffer in signed 16-bit samples // returns num of bytes in outbuf - int convertToS16( const surroundSampleFrame * _ab, + int convertToS16(const SampleFrame* _ab, const fpp_t _frames, int_sample_t * _output_buffer, const bool _convert_endian = false ); @@ -133,7 +134,7 @@ private: QMutex m_devMutex; - surroundSampleFrame * m_buffer; + SampleFrame* m_buffer; }; diff --git a/include/AudioDummy.h b/include/AudioDummy.h index 6907ad167..607ea40f2 100644 --- a/include/AudioDummy.h +++ b/include/AudioDummy.h @@ -94,7 +94,7 @@ private: while( true ) { timer.reset(); - const surroundSampleFrame* b = audioEngine()->nextBuffer(); + const SampleFrame* b = audioEngine()->nextBuffer(); if( !b ) { break; diff --git a/include/AudioEngine.h b/include/AudioEngine.h index 6aeb293c7..5e94ea6a2 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -38,6 +38,7 @@ #include #include "lmms_basics.h" +#include "SampleFrame.h" #include "LocklessList.h" #include "FifoBuffer.h" #include "AudioEngineProfiler.h" @@ -58,8 +59,7 @@ const fpp_t DEFAULT_BUFFER_SIZE = 256; const int BYTES_PER_SAMPLE = sizeof( sample_t ); const int BYTES_PER_INT_SAMPLE = sizeof( int_sample_t ); -const int BYTES_PER_FRAME = sizeof( sampleFrame ); -const int BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame ); +const int BYTES_PER_FRAME = sizeof( SampleFrame ); const float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f; @@ -267,15 +267,6 @@ public: } - struct StereoSample - { - StereoSample(sample_t _left, sample_t _right) : left(_left), right(_right) {} - sample_t left; - sample_t right; - }; - StereoSample getPeakValues(sampleFrame * ab, const f_cnt_t _frames) const; - - bool criticalXRuns() const; inline bool hasFifoWriter() const @@ -283,9 +274,9 @@ public: return m_fifoWriter != nullptr; } - void pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames ); + void pushInputFrames( SampleFrame* _ab, const f_cnt_t _frames ); - inline const sampleFrame * inputBuffer() + inline const SampleFrame* inputBuffer() { return m_inputBuffer[ m_inputBufferRead ]; } @@ -295,7 +286,7 @@ public: return m_inputBufferFrames[ m_inputBufferRead ]; } - inline const surroundSampleFrame * nextBuffer() + inline const SampleFrame* nextBuffer() { return hasFifoWriter() ? m_fifo->read() : renderNextBuffer(); } @@ -321,11 +312,11 @@ public: signals: void qualitySettingsChanged(); void sampleRateChanged(); - void nextAudioBuffer( const lmms::surroundSampleFrame * buffer ); + void nextAudioBuffer(const lmms::SampleFrame* buffer); private: - using Fifo = FifoBuffer; + using Fifo = FifoBuffer; class fifoWriter : public QThread { @@ -342,7 +333,7 @@ private: void run() override; - void write( surroundSampleFrame * buffer ); + void write(SampleFrame* buffer); } ; @@ -361,7 +352,7 @@ private: void renderStageEffects(); void renderStageMix(); - const surroundSampleFrame * renderNextBuffer(); + const SampleFrame* renderNextBuffer(); void swapBuffers(); @@ -375,14 +366,14 @@ private: fpp_t m_framesPerPeriod; - sampleFrame * m_inputBuffer[2]; + SampleFrame* m_inputBuffer[2]; f_cnt_t m_inputBufferFrames[2]; f_cnt_t m_inputBufferSize[2]; int m_inputBufferRead; int m_inputBufferWrite; - std::unique_ptr m_outputBufferRead; - std::unique_ptr m_outputBufferWrite; + std::unique_ptr m_outputBufferRead; + std::unique_ptr m_outputBufferWrite; // worker thread stuff std::vector m_workers; diff --git a/include/AudioFileFlac.h b/include/AudioFileFlac.h index 9432f4231..003450afa 100644 --- a/include/AudioFileFlac.h +++ b/include/AudioFileFlac.h @@ -65,7 +65,7 @@ private: SF_INFO m_sfinfo; SNDFILE* m_sf; - void writeBuffer(surroundSampleFrame const* _ab, fpp_t const frames) override; + void writeBuffer(const SampleFrame* _ab, fpp_t const frames) override; bool startEncoding(); void finishEncoding(); diff --git a/include/AudioFileMP3.h b/include/AudioFileMP3.h index 013c93a3e..e56ac0ba3 100644 --- a/include/AudioFileMP3.h +++ b/include/AudioFileMP3.h @@ -58,7 +58,7 @@ public: } protected: - void writeBuffer(const surroundSampleFrame* /* _buf*/, const fpp_t /*_frames*/) override; + void writeBuffer(const SampleFrame* /* _buf*/, const fpp_t /*_frames*/) override; private: void flushRemainingBuffers(); diff --git a/include/AudioFileOgg.h b/include/AudioFileOgg.h index fc3ce25b4..2608da359 100644 --- a/include/AudioFileOgg.h +++ b/include/AudioFileOgg.h @@ -58,7 +58,7 @@ public: private: - void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override; + void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override; bool startEncoding(); void finishEncoding(); diff --git a/include/AudioFileWave.h b/include/AudioFileWave.h index 22b124f93..040af95ea 100644 --- a/include/AudioFileWave.h +++ b/include/AudioFileWave.h @@ -56,7 +56,7 @@ public: private: - void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override; + void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override; bool startEncoding(); void finishEncoding(); diff --git a/include/AudioJack.h b/include/AudioJack.h index a1f9b777b..234f6ebf2 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -111,7 +111,7 @@ private: std::atomic m_midiClient; std::vector m_outputPorts; jack_default_audio_sample_t** m_tempOutBufs; - surroundSampleFrame* m_outBuf; + SampleFrame* m_outBuf; f_cnt_t m_framesDoneInCurBuf; f_cnt_t m_framesToDoInCurBuf; diff --git a/include/AudioPort.h b/include/AudioPort.h index 9e3ce2bd6..12a0ec7d8 100644 --- a/include/AudioPort.h +++ b/include/AudioPort.h @@ -46,7 +46,7 @@ public: BoolModel * mutedModel = nullptr ); virtual ~AudioPort(); - inline sampleFrame * buffer() + inline SampleFrame* buffer() { return m_portBuffer; } @@ -112,7 +112,7 @@ public: private: volatile bool m_bufferUsage; - sampleFrame * m_portBuffer; + SampleFrame* m_portBuffer; QMutex m_portBufferLock; bool m_extOutputEnabled; diff --git a/include/AudioPortAudio.h b/include/AudioPortAudio.h index 4465b18c1..dbe750c4f 100644 --- a/include/AudioPortAudio.h +++ b/include/AudioPortAudio.h @@ -150,7 +150,7 @@ private: bool m_wasPAInitError; - surroundSampleFrame * m_outBuf; + SampleFrame* m_outBuf; int m_outBufPos; int m_outBufSize; diff --git a/include/AudioSampleRecorder.h b/include/AudioSampleRecorder.h index a3e776881..691196be6 100644 --- a/include/AudioSampleRecorder.h +++ b/include/AudioSampleRecorder.h @@ -48,9 +48,9 @@ public: std::shared_ptr createSampleBuffer(); private: - void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override; + void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override; - using BufferList = QList>; + using BufferList = QList>; BufferList m_buffers; } ; diff --git a/include/AudioSdl.h b/include/AudioSdl.h index 5062f79ea..fcfe97318 100644 --- a/include/AudioSdl.h +++ b/include/AudioSdl.h @@ -85,7 +85,7 @@ private: SDL_AudioSpec m_audioHandle; - surroundSampleFrame * m_outBuf; + SampleFrame* m_outBuf; #ifdef LMMS_HAVE_SDL2 size_t m_currentBufferFramePos; diff --git a/include/AudioSoundIo.h b/include/AudioSoundIo.h index b327f7d84..1260951bf 100644 --- a/include/AudioSoundIo.h +++ b/include/AudioSoundIo.h @@ -110,7 +110,7 @@ private: SoundIo *m_soundio; SoundIoOutStream *m_outstream; - surroundSampleFrame * m_outBuf; + SampleFrame* m_outBuf; int m_outBufSize; fpp_t m_outBufFramesTotal; fpp_t m_outBufFrameIndex; diff --git a/include/BufferManager.h b/include/BufferManager.h index 712e420ff..98f6703db 100644 --- a/include/BufferManager.h +++ b/include/BufferManager.h @@ -32,20 +32,18 @@ namespace lmms { +class SampleFrame; class LMMS_EXPORT BufferManager { public: static void init( fpp_t fpp ); - static sampleFrame * acquire(); + static SampleFrame* acquire(); // audio-buffer-mgm - static void clear( sampleFrame * ab, const f_cnt_t frames, + static void clear( SampleFrame* ab, const f_cnt_t frames, const f_cnt_t offset = 0 ); -#ifndef LMMS_DISABLE_SURROUND - static void clear( surroundSampleFrame * ab, const f_cnt_t frames, - const f_cnt_t offset = 0 ); -#endif - static void release( sampleFrame * buf ); + + static void release( SampleFrame* buf ); private: static fpp_t s_framesPerPeriod; diff --git a/include/DspEffectLibrary.h b/include/DspEffectLibrary.h index 14dbd7ede..348c70765 100644 --- a/include/DspEffectLibrary.h +++ b/include/DspEffectLibrary.h @@ -28,7 +28,7 @@ #include "lmms_math.h" #include "lmms_constants.h" #include "lmms_basics.h" - +#include "SampleFrame.h" namespace lmms::DspEffectLibrary { @@ -80,6 +80,17 @@ namespace lmms::DspEffectLibrary { } + void setGain(float gain) + { + leftFX().setGain(gain); + rightFX().setGain(gain); + } + + void nextSample(SampleFrame & in) + { + nextSample(in.left(), in.right()); + } + void nextSample( sample_t& inLeft, sample_t& inRight ) { inLeft = m_leftFX.nextSample( inLeft ); diff --git a/include/DummyEffect.h b/include/DummyEffect.h index 0a80b90a9..e2e649ab5 100644 --- a/include/DummyEffect.h +++ b/include/DummyEffect.h @@ -107,7 +107,7 @@ public: return &m_controls; } - bool processAudioBuffer( sampleFrame *, const fpp_t ) override + bool processAudioBuffer( SampleFrame*, const fpp_t ) override { return false; } diff --git a/include/DummyInstrument.h b/include/DummyInstrument.h index aefa035db..0962dcd9e 100644 --- a/include/DummyInstrument.h +++ b/include/DummyInstrument.h @@ -49,10 +49,9 @@ public: ~DummyInstrument() override = default; - void playNote( NotePlayHandle *, sampleFrame * buffer ) override + void playNote( NotePlayHandle*, SampleFrame* buffer ) override { - memset( buffer, 0, sizeof( sampleFrame ) * - Engine::audioEngine()->framesPerPeriod() ); + zeroSampleFrames(buffer, Engine::audioEngine()->framesPerPeriod()); } void saveSettings( QDomDocument &, QDomElement & ) override diff --git a/include/Effect.h b/include/Effect.h index c3745a352..34f8be00a 100644 --- a/include/Effect.h +++ b/include/Effect.h @@ -64,7 +64,7 @@ public: } - virtual bool processAudioBuffer( sampleFrame * _buf, + virtual bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) = 0; inline ch_cnt_t processorCount() const @@ -187,8 +187,8 @@ protected: // some effects might not be capable of higher sample-rates so they can // sample it down before processing and back after processing - inline void sampleDown( const sampleFrame * _src_buf, - sampleFrame * _dst_buf, + inline void sampleDown( const SampleFrame* _src_buf, + SampleFrame* _dst_buf, sample_rate_t _dst_sr ) { resample( 0, _src_buf, @@ -197,8 +197,8 @@ protected: Engine::audioEngine()->framesPerPeriod() ); } - inline void sampleBack( const sampleFrame * _src_buf, - sampleFrame * _dst_buf, + inline void sampleBack( const SampleFrame* _src_buf, + SampleFrame* _dst_buf, sample_rate_t _src_sr ) { resample( 1, _src_buf, _src_sr, _dst_buf, @@ -213,9 +213,9 @@ protected: private: EffectChain * m_parent; - void resample( int _i, const sampleFrame * _src_buf, + void resample( int _i, const SampleFrame* _src_buf, sample_rate_t _src_sr, - sampleFrame * _dst_buf, sample_rate_t _dst_sr, + SampleFrame* _dst_buf, sample_rate_t _dst_sr, const f_cnt_t _frames ); ch_cnt_t m_processors; diff --git a/include/EffectChain.h b/include/EffectChain.h index f9482174e..0af23c4b8 100644 --- a/include/EffectChain.h +++ b/include/EffectChain.h @@ -34,6 +34,7 @@ namespace lmms { class Effect; +class SampleFrame; namespace gui { @@ -62,7 +63,7 @@ public: void removeEffect( Effect * _effect ); void moveDown( Effect * _effect ); void moveUp( Effect * _effect ); - bool processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, bool hasInputNoise ); + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames, bool hasInputNoise ); void startRunning(); void clear(); diff --git a/include/Instrument.h b/include/Instrument.h index e2e980372..3f701f12e 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -45,6 +45,7 @@ class InstrumentTrack; class MidiEvent; class NotePlayHandle; class Track; +class SampleFrame; class LMMS_EXPORT Instrument : public Plugin @@ -75,11 +76,11 @@ public: // if the plugin doesn't play each note, it can create an instrument- // play-handle and re-implement this method, so that it mixes its // output buffer only once per audio engine period - virtual void play( sampleFrame * _working_buffer ); + virtual void play( SampleFrame* _working_buffer ); // to be implemented by actual plugin virtual void playNote( NotePlayHandle * /* _note_to_play */, - sampleFrame * /* _working_buf */ ) + SampleFrame* /* _working_buf */ ) { } @@ -160,12 +161,12 @@ public: protected: // fade in to prevent clicks - void applyFadeIn(sampleFrame * buf, NotePlayHandle * n); + void applyFadeIn(SampleFrame* buf, NotePlayHandle * n); // instruments may use this to apply a soft fade out at the end of // notes - method does this only if really less or equal // desiredReleaseFrames() frames are left - void applyRelease( sampleFrame * buf, const NotePlayHandle * _n ); + void applyRelease( SampleFrame* buf, const NotePlayHandle * _n ); float computeReleaseTimeMsByFrameCount(f_cnt_t frames) const; diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h index dc744b4ff..c3d9c13bc 100644 --- a/include/InstrumentPlayHandle.h +++ b/include/InstrumentPlayHandle.h @@ -41,7 +41,7 @@ public: ~InstrumentPlayHandle() override = default; - void play(sampleFrame * working_buffer) override; + void play(SampleFrame* working_buffer) override; bool isFinished() const override { diff --git a/include/InstrumentSoundShaping.h b/include/InstrumentSoundShaping.h index fb5f1e8bd..7dfeaf58b 100644 --- a/include/InstrumentSoundShaping.h +++ b/include/InstrumentSoundShaping.h @@ -34,6 +34,7 @@ namespace lmms class InstrumentTrack; class EnvelopeAndLfoParameters; class NotePlayHandle; +class SampleFrame; namespace gui { @@ -48,7 +49,7 @@ public: InstrumentSoundShaping( InstrumentTrack * _instrument_track ); ~InstrumentSoundShaping() override = default; - void processAudioBuffer( sampleFrame * _ab, const fpp_t _frames, + void processAudioBuffer( SampleFrame* _ab, const fpp_t _frames, NotePlayHandle * _n ); enum class Target diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 3d84df597..45060f055 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -66,7 +66,7 @@ public: ~InstrumentTrack() override; // used by instrument - void processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, + void processAudioBuffer( SampleFrame* _buf, const fpp_t _frames, NotePlayHandle * _n ); MidiEvent applyMasterKey( const MidiEvent& event ); @@ -86,7 +86,7 @@ public: // for capturing note-play-events -> need that for arpeggio, // filter and so on - void playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ); + void playNote( NotePlayHandle * _n, SampleFrame* _working_buffer ); QString instrumentName() const; const Instrument *instrument() const diff --git a/include/Lv2ControlBase.h b/include/Lv2ControlBase.h index 9bfb40f87..8ee235ad8 100644 --- a/include/Lv2ControlBase.h +++ b/include/Lv2ControlBase.h @@ -43,6 +43,7 @@ namespace lmms class Lv2Proc; class PluginIssue; +class SampleFrame; /** Common base class for Lv2 plugins @@ -118,9 +119,9 @@ protected: void copyModelsToLmms() const; //! Copy buffer passed by LMMS into our ports - void copyBuffersFromLmms(const sampleFrame *buf, fpp_t frames); + void copyBuffersFromLmms(const SampleFrame* buf, fpp_t frames); //! Copy our ports into buffers passed by LMMS - void copyBuffersToLmms(sampleFrame *buf, fpp_t frames) const; + void copyBuffersToLmms(SampleFrame* buf, fpp_t frames) const; //! Run the Lv2 plugin instance for @param frames frames void run(fpp_t frames); diff --git a/include/Lv2Ports.h b/include/Lv2Ports.h index e4c896ff3..1b2986938 100644 --- a/include/Lv2Ports.h +++ b/include/Lv2Ports.h @@ -41,6 +41,7 @@ namespace lmms { +class SampleFrame; struct ConnectPortVisitor; using LV2_Evbuf = struct LV2_Evbuf_Impl; @@ -184,15 +185,15 @@ struct Audio : public VisitablePort //! Copy buffer passed by LMMS into our ports //! @param channel channel index into each sample frame - void copyBuffersFromCore(const sampleFrame *lmmsBuf, + void copyBuffersFromCore(const SampleFrame* lmmsBuf, unsigned channel, fpp_t frames); //! Add buffer passed by LMMS into our ports, and halve the result //! @param channel channel index into each sample frame - void averageWithBuffersFromCore(const sampleFrame *lmmsBuf, + void averageWithBuffersFromCore(const SampleFrame* lmmsBuf, unsigned channel, fpp_t frames); //! Copy our ports into buffers passed by LMMS //! @param channel channel index into each sample frame - void copyBuffersToCore(sampleFrame *lmmsBuf, + void copyBuffersToCore(SampleFrame* lmmsBuf, unsigned channel, fpp_t frames) const; bool isSideChain() const { return m_sidechain; } diff --git a/include/Lv2Proc.h b/include/Lv2Proc.h index 36b0fa600..f315c5d7a 100644 --- a/include/Lv2Proc.h +++ b/include/Lv2Proc.h @@ -49,6 +49,7 @@ namespace lmms { class PluginIssue; +class SampleFrame; // forward declare port structs/enums namespace Lv2Ports @@ -134,7 +135,7 @@ public: * @param num Number of channels we must read from @param buf (starting at * @p offset) */ - void copyBuffersFromCore(const sampleFrame *buf, + void copyBuffersFromCore(const SampleFrame* buf, unsigned firstChan, unsigned num, fpp_t frames); /** * Copy our ports into buffers passed by the core @@ -147,7 +148,7 @@ public: * @param num Number of channels we must write to @param buf (starting at * @p offset) */ - void copyBuffersToCore(sampleFrame *buf, unsigned firstChan, unsigned num, + void copyBuffersToCore(SampleFrame* buf, unsigned firstChan, unsigned num, fpp_t frames) const; //! Run the Lv2 plugin instance for @param frames frames void run(fpp_t frames); diff --git a/include/MixHelpers.h b/include/MixHelpers.h index dde17dd02..a55ad6058 100644 --- a/include/MixHelpers.h +++ b/include/MixHelpers.h @@ -31,52 +31,54 @@ namespace lmms { class ValueBuffer; +class SampleFrame; + namespace MixHelpers { -bool isSilent( const sampleFrame* src, int frames ); +bool isSilent( const SampleFrame* src, int frames ); bool useNaNHandler(); void setNaNHandler( bool use ); -bool sanitize( sampleFrame * src, int frames ); +bool sanitize( SampleFrame* src, int frames ); /*! \brief Add samples from src to dst */ -void add( sampleFrame* dst, const sampleFrame* src, int frames ); +void add( SampleFrame* dst, const SampleFrame* src, int frames ); /*! \brief Multiply samples from `dst` by `coeff` */ -void multiply(sampleFrame* dst, float coeff, int frames); +void multiply(SampleFrame* dst, float coeff, int frames); /*! \brief Add samples from src multiplied by coeffSrc to dst */ -void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); +void addMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames ); /*! \brief Add samples from src multiplied by coeffSrc to dst, swap inputs */ -void addSwappedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); +void addSwappedMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames ); /*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst */ -void addMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ); +void addMultipliedByBuffer( SampleFrame* dst, const SampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ); /*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst */ -void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ); +void addMultipliedByBuffers( SampleFrame* dst, const SampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ); /*! \brief Same as addMultiplied, but sanitize output (strip out infs/nans) */ -void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); +void addSanitizedMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames ); /*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */ -void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ); +void addSanitizedMultipliedByBuffer( SampleFrame* dst, const SampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ); /*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */ -void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ); +void addSanitizedMultipliedByBuffers( SampleFrame* dst, const SampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ); /*! \brief Add samples from src multiplied by coeffSrcLeft/coeffSrcRight to dst */ -void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ); +void addMultipliedStereo( SampleFrame* dst, const SampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ); /*! \brief Multiply dst by coeffDst and add samples from src multiplied by coeffSrc */ -void multiplyAndAddMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffDst, float coeffSrc, int frames ); +void multiplyAndAddMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffDst, float coeffSrc, int frames ); /*! \brief Multiply dst by coeffDst and add samples from srcLeft/srcRight multiplied by coeffSrc */ -void multiplyAndAddMultipliedJoined( sampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, float coeffDst, float coeffSrc, int frames ); +void multiplyAndAddMultipliedJoined( SampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, float coeffDst, float coeffSrc, int frames ); } // namespace MixHelpers diff --git a/include/Mixer.h b/include/Mixer.h index 302492cab..e65bde010 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -56,7 +56,7 @@ class MixerChannel : public ThreadableJob float m_peakLeft; float m_peakRight; - sampleFrame * m_buffer; + SampleFrame* m_buffer; bool m_muteBeforeSolo; BoolModel m_muteModel; BoolModel m_soloModel; @@ -137,10 +137,10 @@ public: Mixer(); ~Mixer() override; - void mixToChannel( const sampleFrame * _buf, mix_ch_t _ch ); + void mixToChannel( const SampleFrame* _buf, mix_ch_t _ch ); void prepareMasterMix(); - void masterMix( sampleFrame * _buf ); + void masterMix( SampleFrame* _buf ); void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; void loadSettings( const QDomElement & _this ) override; diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index f70268132..0c0acf694 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -110,7 +110,7 @@ public: float currentDetuning() const { return m_baseDetuning->value(); } /*! Renders one chunk using the attached instrument into the buffer */ - void play( sampleFrame* buffer ) override; + void play( SampleFrame* buffer ) override; /*! Returns whether playback of note is finished and thus handle can be deleted */ bool isFinished() const override diff --git a/include/Oscillator.h b/include/Oscillator.h index e7eccea50..f537044dc 100644 --- a/include/Oscillator.h +++ b/include/Oscillator.h @@ -109,7 +109,7 @@ public: m_userAntiAliasWaveTable = waveform; } - void update(sampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator = false); + void update(SampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator = false); // now follow the wave-shape-routines... static inline sample_t sinSample( const float _sample ) @@ -282,40 +282,40 @@ private: /* End Multiband wavetable */ - void updateNoSub( sampleFrame * _ab, const fpp_t _frames, + void updateNoSub( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); - void updatePM( sampleFrame * _ab, const fpp_t _frames, + void updatePM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); - void updateAM( sampleFrame * _ab, const fpp_t _frames, + void updateAM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); - void updateMix( sampleFrame * _ab, const fpp_t _frames, + void updateMix( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); - void updateSync( sampleFrame * _ab, const fpp_t _frames, + void updateSync( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); - void updateFM( sampleFrame * _ab, const fpp_t _frames, + void updateFM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); - float syncInit( sampleFrame * _ab, const fpp_t _frames, + float syncInit( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); inline bool syncOk( float _osc_coeff ); template - void updateNoSub( sampleFrame * _ab, const fpp_t _frames, + void updateNoSub( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); template - void updatePM( sampleFrame * _ab, const fpp_t _frames, + void updatePM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); template - void updateAM( sampleFrame * _ab, const fpp_t _frames, + void updateAM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); template - void updateMix( sampleFrame * _ab, const fpp_t _frames, + void updateMix( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); template - void updateSync( sampleFrame * _ab, const fpp_t _frames, + void updateSync( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); template - void updateFM( sampleFrame * _ab, const fpp_t _frames, + void updateFM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ); template diff --git a/include/Oscilloscope.h b/include/Oscilloscope.h index 13c946aa5..1e3c52b1e 100644 --- a/include/Oscilloscope.h +++ b/include/Oscilloscope.h @@ -30,6 +30,13 @@ #include "lmms_basics.h" +namespace lmms +{ + +class SampleFrame; + +} + namespace lmms::gui { @@ -67,7 +74,7 @@ protected: protected slots: - void updateAudioBuffer( const lmms::surroundSampleFrame * buffer ); + void updateAudioBuffer(const lmms::SampleFrame* buffer); private: bool clips(float level) const; @@ -76,7 +83,7 @@ private: QPixmap m_background; QPointF * m_points; - sampleFrame * m_buffer; + SampleFrame* m_buffer; bool m_active; QColor m_leftChannelColor; diff --git a/include/PlayHandle.h b/include/PlayHandle.h index 8f5d771ed..f2e87136a 100644 --- a/include/PlayHandle.h +++ b/include/PlayHandle.h @@ -41,6 +41,7 @@ namespace lmms class Track; class AudioPort; +class SampleFrame; class LMMS_EXPORT PlayHandle : public ThreadableJob { @@ -105,7 +106,7 @@ public: { return m_processingLock.tryLock(); } - virtual void play( sampleFrame* buffer ) = 0; + virtual void play( SampleFrame* buffer ) = 0; virtual bool isFinished() const = 0; // returns the frameoffset at the start of the playhandle, @@ -145,14 +146,14 @@ public: void releaseBuffer(); - sampleFrame * buffer(); + SampleFrame* buffer(); private: Type m_type; f_cnt_t m_offset; QThread* m_affinity; QMutex m_processingLock; - sampleFrame* m_playHandleBuffer; + SampleFrame* m_playHandleBuffer; bool m_bufferReleased; bool m_usesBuffer; AudioPort * m_audioPort; diff --git a/include/PresetPreviewPlayHandle.h b/include/PresetPreviewPlayHandle.h index b8199a71b..e464cf615 100644 --- a/include/PresetPreviewPlayHandle.h +++ b/include/PresetPreviewPlayHandle.h @@ -47,7 +47,7 @@ public: return true; } - void play( sampleFrame* buffer ) override; + void play( SampleFrame* buffer ) override; bool isFinished() const override; bool isFromTrack( const Track * _track ) const override; diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index c5fcd7dd2..d4676b52e 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -37,6 +37,7 @@ namespace lmms class RemotePlugin; +class SampleFrame; class ProcessWatcher : public QThread { @@ -96,7 +97,7 @@ public: bool processMessage( const message & _m ) override; - bool process( const sampleFrame * _in_buf, sampleFrame * _out_buf ); + bool process( const SampleFrame* _in_buf, SampleFrame* _out_buf ); void processMidiEvent( const MidiEvent&, const f_cnt_t _offset ); diff --git a/include/RemotePluginClient.h b/include/RemotePluginClient.h index 77eef68f0..22158f1b8 100644 --- a/include/RemotePluginClient.h +++ b/include/RemotePluginClient.h @@ -44,6 +44,8 @@ namespace lmms { +class SampleFrame; + class RemotePluginClient : public RemotePluginBase { public: @@ -58,8 +60,8 @@ public: bool processMessage( const message & _m ) override; - virtual void process( const sampleFrame * _in_buf, - sampleFrame * _out_buf ) = 0; + virtual void process( const SampleFrame* _in_buf, + SampleFrame* _out_buf ) = 0; virtual void processMidiEvent( const MidiEvent&, const f_cnt_t /* _offset */ ) { @@ -342,8 +344,8 @@ void RemotePluginClient::doProcessing() { if (m_audioBuffer) { - process( (sampleFrame *)( m_inputCount > 0 ? m_audioBuffer.get() : nullptr ), - (sampleFrame *)( m_audioBuffer.get() + + process( (SampleFrame*)( m_inputCount > 0 ? m_audioBuffer.get() : nullptr ), + (SampleFrame*)( m_audioBuffer.get() + ( m_inputCount*m_bufferSize ) ) ); } else diff --git a/include/RingBuffer.h b/include/RingBuffer.h index 98f726475..41595be19 100644 --- a/include/RingBuffer.h +++ b/include/RingBuffer.h @@ -35,6 +35,7 @@ namespace lmms { +class SampleFrame; /** \brief A basic LMMS ring buffer for single-thread use. For thread and realtime safe alternative see LocklessRingBuffer. */ @@ -105,7 +106,7 @@ public: * to a specified destination, and advances the position by one period * \param dst Destination pointer */ - void pop( sampleFrame * dst ); + void pop( SampleFrame* dst ); // note: ringbuffer position is unaffected by all other read functions beside pop() @@ -113,27 +114,27 @@ public: * \param dst Destination pointer * \param offset Offset in frames against current position, may be negative */ - void read( sampleFrame * dst, f_cnt_t offset=0 ); + void read( SampleFrame* dst, f_cnt_t offset = 0 ); /** \brief Reads a period-sized buffer from the ringbuffer and writes it to a specified destination * \param dst Destination pointer * \param offset Offset in milliseconds against current position, may be negative */ - void read( sampleFrame * dst, float offset ); + void read( SampleFrame* dst, float offset ); /** \brief Reads a buffer of specified size from the ringbuffer and writes it to a specified destination * \param dst Destination pointer * \param offset Offset in frames against current position, may be negative * \param length Length in frames of the buffer to read - must not be higher than the size of the ringbuffer! */ - void read( sampleFrame * dst, f_cnt_t offset, f_cnt_t length ); + void read( SampleFrame* dst, f_cnt_t offset, f_cnt_t length ); /** \brief Reads a buffer of specified size from the ringbuffer and writes it to a specified destination * \param dst Destination pointer * \param offset Offset in milliseconds against current position, may be negative * \param length Length in frames of the buffer to read - must not be higher than the size of the ringbuffer! */ - void read( sampleFrame * dst, float offset, f_cnt_t length ); + void read( SampleFrame* dst, float offset, f_cnt_t length ); // write functions @@ -143,28 +144,28 @@ public: * \param offset Offset in frames against current position, may *NOT* be negative * \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer! */ - void write( sampleFrame * src, f_cnt_t offset=0, f_cnt_t length=0 ); + void write( SampleFrame* src, f_cnt_t offset=0, f_cnt_t length=0 ); /** \brief Writes a buffer of sampleframes to the ringbuffer at specified position * \param src Pointer to the source buffer * \param offset Offset in milliseconds against current position, may *NOT* be negative * \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer! */ - void write( sampleFrame * src, float offset, f_cnt_t length=0 ); + void write( SampleFrame* src, float offset, f_cnt_t length=0 ); /** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position * \param src Pointer to the source buffer * \param offset Offset in frames against current position, may *NOT* be negative * \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer! */ - void writeAdding( sampleFrame * src, f_cnt_t offset=0, f_cnt_t length=0 ); + void writeAdding( SampleFrame* src, f_cnt_t offset=0, f_cnt_t length=0 ); /** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position * \param src Pointer to the source buffer * \param offset Offset in milliseconds against current position, may *NOT* be negative * \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer! */ - void writeAdding( sampleFrame * src, float offset, f_cnt_t length=0 ); + void writeAdding( SampleFrame* src, float offset, f_cnt_t length=0 ); /** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with * a specified multiplier applied to the frames @@ -173,7 +174,7 @@ public: * \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer! * \param level Multiplier applied to the frames before they're written to the ringbuffer */ - void writeAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt_t length, float level ); + void writeAddingMultiplied( SampleFrame* src, f_cnt_t offset, f_cnt_t length, float level ); /** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with * a specified multiplier applied to the frames @@ -182,7 +183,7 @@ public: * \param length Length of the source buffer, if zero, period size is used * \param level Multiplier applied to the frames before they're written to the ringbuffer */ - void writeAddingMultiplied( sampleFrame * src, float offset, f_cnt_t length, float level ); + void writeAddingMultiplied( SampleFrame* src, float offset, f_cnt_t length, float level ); /** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with * a specified multiplier applied to the frames, with swapped channels @@ -191,7 +192,7 @@ public: * \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer! * \param level Multiplier applied to the frames before they're written to the ringbuffer */ - void writeSwappedAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt_t length, float level ); + void writeSwappedAddingMultiplied( SampleFrame* src, f_cnt_t offset, f_cnt_t length, float level ); /** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with * a specified multiplier applied to the frames, with swapped channels @@ -200,7 +201,7 @@ public: * \param length Length of the source buffer, if zero, period size is used * \param level Multiplier applied to the frames before they're written to the ringbuffer */ - void writeSwappedAddingMultiplied( sampleFrame * src, float offset, f_cnt_t length, float level ); + void writeSwappedAddingMultiplied( SampleFrame* src, float offset, f_cnt_t length, float level ); protected slots: @@ -215,7 +216,7 @@ private: const fpp_t m_fpp; sample_rate_t m_samplerate; size_t m_size; - sampleFrame * m_buffer; + SampleFrame* m_buffer; volatile unsigned int m_position; }; diff --git a/include/Sample.h b/include/Sample.h index 92ac1a58a..3fd5bc38e 100644 --- a/include/Sample.h +++ b/include/Sample.h @@ -78,7 +78,7 @@ public: Sample() = default; Sample(const QByteArray& base64, int sampleRate = Engine::audioEngine()->outputSampleRate()); - Sample(const sampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate()); + Sample(const SampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate()); Sample(const Sample& other); Sample(Sample&& other); explicit Sample(const QString& audioFile); @@ -87,7 +87,7 @@ public: auto operator=(const Sample&) -> Sample&; auto operator=(Sample&&) -> Sample&; - auto play(sampleFrame* dst, PlaybackState* state, size_t numFrames, float desiredFrequency = DefaultBaseFreq, + auto play(SampleFrame* dst, PlaybackState* state, size_t numFrames, float desiredFrequency = DefaultBaseFreq, Loop loopMode = Loop::Off) const -> bool; auto sampleDuration() const -> std::chrono::milliseconds; @@ -97,7 +97,7 @@ public: auto toBase64() const -> QString { return m_buffer->toBase64(); } - auto data() const -> const sampleFrame* { return m_buffer->data(); } + auto data() const -> const SampleFrame* { return m_buffer->data(); } auto buffer() const -> std::shared_ptr { return m_buffer; } auto startFrame() const -> int { return m_startFrame.load(std::memory_order_relaxed); } auto endFrame() const -> int { return m_endFrame.load(std::memory_order_relaxed); } @@ -117,7 +117,7 @@ public: void setReversed(bool reversed) { m_reversed.store(reversed, std::memory_order_relaxed); } private: - void playRaw(sampleFrame* dst, size_t numFrames, const PlaybackState* state, Loop loopMode) const; + void playRaw(SampleFrame* dst, size_t numFrames, const PlaybackState* state, Loop loopMode) const; void advance(PlaybackState* state, size_t advanceAmount, Loop loopMode) const; private: diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 6f40b33d1..8ec6c5886 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -41,22 +41,22 @@ namespace lmms { class LMMS_EXPORT SampleBuffer { public: - using value_type = sampleFrame; - using reference = sampleFrame&; - using const_reference = const sampleFrame&; - using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; - using difference_type = std::vector::difference_type; - using size_type = std::vector::size_type; - using reverse_iterator = std::vector::reverse_iterator; - using const_reverse_iterator = std::vector::const_reverse_iterator; + using value_type = SampleFrame; + using reference = SampleFrame&; + using const_reference = const SampleFrame&; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + using difference_type = std::vector::difference_type; + using size_type = std::vector::size_type; + using reverse_iterator = std::vector::reverse_iterator; + using const_reverse_iterator = std::vector::const_reverse_iterator; SampleBuffer() = default; explicit SampleBuffer(const QString& audioFile); SampleBuffer(const QString& base64, int sampleRate); - SampleBuffer(std::vector data, int sampleRate); + SampleBuffer(std::vector data, int sampleRate); SampleBuffer( - const sampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate()); + const SampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate()); friend void swap(SampleBuffer& first, SampleBuffer& second) noexcept; auto toBase64() const -> QString; @@ -82,14 +82,14 @@ public: auto crbegin() const -> const_reverse_iterator { return m_data.crbegin(); } auto crend() const -> const_reverse_iterator { return m_data.crend(); } - auto data() const -> const sampleFrame* { return m_data.data(); } + auto data() const -> const SampleFrame* { return m_data.data(); } auto size() const -> size_type { return m_data.size(); } auto empty() const -> bool { return m_data.empty(); } static auto emptyBuffer() -> std::shared_ptr; private: - std::vector m_data; + std::vector m_data; QString m_audioFile; sample_rate_t m_sampleRate = Engine::audioEngine()->outputSampleRate(); }; diff --git a/include/SampleDecoder.h b/include/SampleDecoder.h index d7ce076dd..2cfd00977 100644 --- a/include/SampleDecoder.h +++ b/include/SampleDecoder.h @@ -32,6 +32,7 @@ #include #include "lmms_basics.h" +#include "SampleFrame.h" namespace lmms { class SampleDecoder @@ -39,7 +40,7 @@ class SampleDecoder public: struct Result { - std::vector data; + std::vector data; int sampleRate; }; diff --git a/include/SampleFrame.h b/include/SampleFrame.h new file mode 100644 index 000000000..5f02cd352 --- /dev/null +++ b/include/SampleFrame.h @@ -0,0 +1,229 @@ +/* + * SampleFrame.h - Representation of a stereo sample + * + * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program 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. + * + * This program 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 this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_SAMPLEFRAME_H +#define LMMS_SAMPLEFRAME_H + +#include "lmms_basics.h" + +#include + + +namespace lmms +{ + +class SampleFrame +{ +public: + SampleFrame() : SampleFrame(0., 0.) + { + } + + explicit SampleFrame(sample_t value) : SampleFrame(value, value) + { + } + + SampleFrame(sample_t left, sample_t right) : + m_samples({ left, right }) + { + } + + sample_t* data() + { + return m_samples.data(); + } + + const sample_t* data() const + { + return m_samples.data(); + } + + sample_t& left() + { + return m_samples[0]; + } + + const sample_t& left() const + { + return m_samples[0]; + } + + void setLeft(const sample_t& value) + { + m_samples[0] = value; + } + + sample_t& right() + { + return m_samples[1]; + } + + const sample_t& right() const + { + return m_samples[1]; + } + + void setRight(const sample_t& value) + { + m_samples[1] = value; + } + + sample_t& operator[](size_t index) + { + return m_samples[index]; + } + + const sample_t& operator[](size_t index) const + { + return m_samples[index]; + } + + SampleFrame operator+(const SampleFrame& other) const + { + return SampleFrame(left() + other.left(), right() + other.right()); + } + + SampleFrame& operator+=(const SampleFrame& other) + { + auto & l = left(); + auto & r = right(); + + l += other.left(); + r += other.right(); + + return *this; + } + + SampleFrame operator*(float value) const + { + return SampleFrame(left() * value, right() * value); + } + + SampleFrame& operator*=(float value) + { + setLeft(left() * value); + setRight(right() * value); + + return *this; + } + + SampleFrame operator*(const SampleFrame& other) const + { + return SampleFrame(left() * other.left(), right() * other.right()); + } + + void operator*=(const SampleFrame& other) + { + left() *= other.left(); + right() *= other.right(); + } + + sample_t sumOfSquaredAmplitudes() const + { + return left() * left() + right() * right(); + } + + SampleFrame abs() const + { + return SampleFrame{std::abs(this->left()), std::abs(this->right())}; + } + + SampleFrame absMax(const SampleFrame& other) + { + const auto a = abs(); + const auto b = other.abs(); + + return SampleFrame(std::max(a.left(), b.left()), std::max(a.right(), b.right())); + } + + sample_t average() const + { + return (left() + right()) / 2; + } + + void clamp(sample_t low, sample_t high) + { + auto & l = left(); + l = std::clamp(l, low, high); + + auto & r = right(); + r = std::clamp(r, low, high); + } + + bool containsInf() const + { + return std::isinf(left()) || std::isinf(right()); + } + + bool containsNaN() const + { + return std::isnan(left()) || std::isnan(right()); + } + +private: + std::array m_samples; +}; + +inline void zeroSampleFrames(SampleFrame* buffer, fpp_t frames) +{ + // The equivalent of the following operation which yields compiler warnings + // memset(buffer, 0, sizeof(SampleFrame) * frames); + + std::fill(buffer, buffer + frames, SampleFrame()); +} + +inline SampleFrame getAbsPeakValues(SampleFrame* buffer, fpp_t frames) +{ + SampleFrame peaks; + + for (f_cnt_t i = 0; i < frames; ++i) + { + peaks = peaks.absMax(buffer[i]); + } + + return peaks; +} + +inline void copyToSampleFrames(SampleFrame* target, const float* source, fpp_t frames) +{ + for (fpp_t i = 0; i < frames; ++i) + { + target[i].setLeft(source[2*i]); + target[i].setRight(source[2*i + 1]); + } +} + +inline void copyFromSampleFrames(float* target, const SampleFrame* source, fpp_t frames) +{ + for (fpp_t i = 0; i < frames; ++i) + { + target[2*i] = source[i].left(); + target[2*i + 1] = source[i].right(); + } +} + +} // namespace lmms + +#endif // LMMS_SAMPLEFRAME_H diff --git a/include/SamplePlayHandle.h b/include/SamplePlayHandle.h index 280010b06..dde29b49b 100644 --- a/include/SamplePlayHandle.h +++ b/include/SamplePlayHandle.h @@ -55,7 +55,7 @@ public: } - void play( sampleFrame * buffer ) override; + void play( SampleFrame* buffer ) override; bool isFinished() const override; bool isFromTrack( const Track * _track ) const override; diff --git a/include/SampleRecordHandle.h b/include/SampleRecordHandle.h index df2d7c772..b650c6760 100644 --- a/include/SampleRecordHandle.h +++ b/include/SampleRecordHandle.h @@ -48,7 +48,7 @@ public: SampleRecordHandle( SampleClip* clip ); ~SampleRecordHandle() override; - void play( sampleFrame * _working_buffer ) override; + void play( SampleFrame* _working_buffer ) override; bool isFinished() const override; bool isFromTrack( const Track * _track ) const override; @@ -58,10 +58,10 @@ public: private: - virtual void writeBuffer( const sampleFrame * _ab, + virtual void writeBuffer( const SampleFrame* _ab, const f_cnt_t _frames ); - using bufferList = QList>; + using bufferList = QList>; bufferList m_buffers; f_cnt_t m_framesRecorded; TimePos m_minLength; diff --git a/include/SampleWaveform.h b/include/SampleWaveform.h index 0185e0e98..ccfc9fb60 100644 --- a/include/SampleWaveform.h +++ b/include/SampleWaveform.h @@ -36,7 +36,7 @@ class LMMS_EXPORT SampleWaveform public: struct Parameters { - const sampleFrame* buffer; + const SampleFrame* buffer; size_t size; float amplification; bool reversed; diff --git a/include/SweepOscillator.h b/include/SweepOscillator.h index b5521da3b..c7c7938d1 100644 --- a/include/SweepOscillator.h +++ b/include/SweepOscillator.h @@ -43,7 +43,7 @@ public: virtual ~SweepOscillator() = default; - void update( sampleFrame* buf, const fpp_t frames, const float freq1, const float freq2, const float sampleRate ) + void update( SampleFrame* buf, const fpp_t frames, const float freq1, const float freq2, const float sampleRate ) { const float df = freq2 - freq1; for( fpp_t frame = 0; frame < frames; ++frame ) diff --git a/include/lmms_basics.h b/include/lmms_basics.h index 5c7292ab0..4695b4f8a 100644 --- a/include/lmms_basics.h +++ b/include/lmms_basics.h @@ -33,6 +33,9 @@ #include #include +#include +#include + namespace lmms { @@ -48,7 +51,7 @@ using int_sample_t = int16_t; // 16-bit-int-sample using sample_rate_t = uint32_t; // sample-rate using fpp_t = int16_t; // frames per period (0-16384) using f_cnt_t = int32_t; // standard frame-count -using ch_cnt_t = uint8_t; // channel-count (0-SURROUND_CHANNELS) +using ch_cnt_t = uint8_t; // channel-count (0-DEFAULT_CHANNELS) using bpm_t = uint16_t; // tempo (MIN_BPM to MAX_BPM) using bitrate_t = uint16_t; // bitrate in kbps using mix_ch_t = uint16_t; // Mixer-channel (0 to MAX_CHANNEL) @@ -109,14 +112,6 @@ inline bool typeInfo::isEqual( float x, float y ) constexpr ch_cnt_t DEFAULT_CHANNELS = 2; -constexpr ch_cnt_t SURROUND_CHANNELS = -#define LMMS_DISABLE_SURROUND -#ifndef LMMS_DISABLE_SURROUND - 4; -#else - 2; -#endif - constexpr char LADSPA_PATH_SEPERATOR = #ifdef LMMS_BUILD_WIN32 ';'; @@ -126,10 +121,6 @@ constexpr char LADSPA_PATH_SEPERATOR = -using sampleFrame = std::array; -using surroundSampleFrame = std::array; - - #define LMMS_STRINGIFY(s) LMMS_STR(s) #define LMMS_STR(PN) #PN diff --git a/plugins/Amplifier/Amplifier.cpp b/plugins/Amplifier/Amplifier.cpp index ac5fdf23b..2f4e57f77 100644 --- a/plugins/Amplifier/Amplifier.cpp +++ b/plugins/Amplifier/Amplifier.cpp @@ -57,7 +57,7 @@ AmplifierEffect::AmplifierEffect(Model* parent, const Descriptor::SubPluginFeatu } -bool AmplifierEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +bool AmplifierEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { return false ; } @@ -80,14 +80,14 @@ bool AmplifierEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) const float panLeft = std::min(1.0f, 1.0f - pan); const float panRight = std::min(1.0f, 1.0f + pan); - auto s = std::array{buf[f][0], buf[f][1]}; + auto& currentFrame = buf[f]; - s[0] *= volume * left * panLeft; - s[1] *= volume * right * panRight; + const auto s = currentFrame * SampleFrame(left * panLeft, right * panRight) * volume; - buf[f][0] = d * buf[f][0] + w * s[0]; - buf[f][1] = d * buf[f][1] + w * s[1]; - outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; + // Dry/wet mix + currentFrame = currentFrame * d + s * w; + + outSum += currentFrame.sumOfSquaredAmplitudes(); } checkGate(outSum / frames); diff --git a/plugins/Amplifier/Amplifier.h b/plugins/Amplifier/Amplifier.h index 8a39ffeb6..8be938001 100644 --- a/plugins/Amplifier/Amplifier.h +++ b/plugins/Amplifier/Amplifier.h @@ -37,7 +37,7 @@ class AmplifierEffect : public Effect public: AmplifierEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~AmplifierEffect() override = default; - bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/AudioFileProcessor/AudioFileProcessor.cpp b/plugins/AudioFileProcessor/AudioFileProcessor.cpp index fbbcbca73..767d15e73 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessor.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessor.cpp @@ -105,7 +105,7 @@ AudioFileProcessor::AudioFileProcessor( InstrumentTrack * _instrument_track ) : void AudioFileProcessor::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { const fpp_t frames = _n->framesLeftForCurrentPeriod(); const f_cnt_t offset = _n->noteOffset(); @@ -165,7 +165,7 @@ void AudioFileProcessor::playNote( NotePlayHandle * _n, } else { - memset( _working_buffer, 0, ( frames + offset ) * sizeof( sampleFrame ) ); + zeroSampleFrames(_working_buffer, frames + offset); emit isPlaying( 0 ); } } diff --git a/plugins/AudioFileProcessor/AudioFileProcessor.h b/plugins/AudioFileProcessor/AudioFileProcessor.h index 00ad92129..b39342fd1 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessor.h +++ b/plugins/AudioFileProcessor/AudioFileProcessor.h @@ -44,7 +44,7 @@ public: AudioFileProcessor( InstrumentTrack * _instrument_track ); void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; void saveSettings(QDomDocument& doc, QDomElement& elem) override; diff --git a/plugins/BassBooster/BassBooster.cpp b/plugins/BassBooster/BassBooster.cpp index aa0d3ebcd..f12fd6ace 100644 --- a/plugins/BassBooster/BassBooster.cpp +++ b/plugins/BassBooster/BassBooster.cpp @@ -69,7 +69,7 @@ BassBoosterEffect::BassBoosterEffect( Model* parent, const Descriptor::SubPlugin -bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +bool BassBoosterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { @@ -91,23 +91,19 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames const float d = dryLevel(); const float w = wetLevel(); - for( fpp_t f = 0; f < frames; ++f ) + for (fpp_t f = 0; f < frames; ++f) { - float gain = const_gain; - if (gainBuffer) { - //process period using sample exact data - gain = gainBuffer->value( f ); - } - //float gain = gainBuffer ? gainBuffer[f] : gain; - m_bbFX.leftFX().setGain( gain ); - m_bbFX.rightFX().setGain( gain); + auto& currentFrame = buf[f]; - auto s = std::array{buf[f][0], buf[f][1]}; - m_bbFX.nextSample( s[0], s[1] ); + // Process copy of current sample frame + m_bbFX.setGain(gainBuffer ? gainBuffer->value(f) : const_gain); + auto s = currentFrame; + m_bbFX.nextSample(s); - buf[f][0] = d * buf[f][0] + w * s[0]; - buf[f][1] = d * buf[f][1] + w * s[1]; - outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; + // Dry/wet mix + currentFrame = currentFrame * d + s * w; + + outSum += currentFrame.sumOfSquaredAmplitudes(); } checkGate( outSum / frames ); diff --git a/plugins/BassBooster/BassBooster.h b/plugins/BassBooster/BassBooster.h index ea3ba2d98..64c4e354d 100644 --- a/plugins/BassBooster/BassBooster.h +++ b/plugins/BassBooster/BassBooster.h @@ -38,7 +38,7 @@ class BassBoosterEffect : public Effect public: BassBoosterEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~BassBoosterEffect() override = default; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { diff --git a/plugins/BitInvader/BitInvader.cpp b/plugins/BitInvader/BitInvader.cpp index 21940182b..8d9bef4d3 100644 --- a/plugins/BitInvader/BitInvader.cpp +++ b/plugins/BitInvader/BitInvader.cpp @@ -256,7 +256,7 @@ QString BitInvader::nodeName() const void BitInvader::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { if (!_n->m_pluginData) { @@ -274,11 +274,7 @@ void BitInvader::playNote( NotePlayHandle * _n, auto ps = static_cast(_n->m_pluginData); for( fpp_t frame = offset; frame < frames + offset; ++frame ) { - const sample_t cur = ps->nextStringSample( m_graph.length() ); - for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) - { - _working_buffer[frame][chnl] = cur; - } + _working_buffer[frame] = SampleFrame(ps->nextStringSample(m_graph.length())); } applyRelease( _working_buffer, _n ); diff --git a/plugins/BitInvader/BitInvader.h b/plugins/BitInvader/BitInvader.h index f4d248ec8..2ed2dde1b 100644 --- a/plugins/BitInvader/BitInvader.h +++ b/plugins/BitInvader/BitInvader.h @@ -75,7 +75,7 @@ public: ~BitInvader() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/Bitcrush/Bitcrush.cpp b/plugins/Bitcrush/Bitcrush.cpp index 251750a32..76e8b9681 100644 --- a/plugins/Bitcrush/Bitcrush.cpp +++ b/plugins/Bitcrush/Bitcrush.cpp @@ -62,7 +62,7 @@ BitcrushEffect::BitcrushEffect( Model * parent, const Descriptor::SubPluginFeatu m_sampleRate( Engine::audioEngine()->outputSampleRate() ), m_filter( m_sampleRate ) { - m_buffer = new sampleFrame[Engine::audioEngine()->framesPerPeriod() * OS_RATE]; + m_buffer = new SampleFrame[Engine::audioEngine()->framesPerPeriod() * OS_RATE]; m_filter.setLowpass( m_sampleRate * ( CUTOFF_RATIO * OS_RATIO ) ); m_needsUpdate = true; @@ -100,7 +100,7 @@ inline float BitcrushEffect::noise( float amt ) return fastRandf( amt * 2.0f ) - amt; } -bool BitcrushEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +bool BitcrushEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { diff --git a/plugins/Bitcrush/Bitcrush.h b/plugins/Bitcrush/Bitcrush.h index a6e5556a2..009c7c02d 100644 --- a/plugins/Bitcrush/Bitcrush.h +++ b/plugins/Bitcrush/Bitcrush.h @@ -41,7 +41,7 @@ class BitcrushEffect : public Effect public: BitcrushEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~BitcrushEffect() override; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { @@ -55,7 +55,7 @@ private: BitcrushControls m_controls; - sampleFrame * m_buffer; + SampleFrame* m_buffer; float m_sampleRate; StereoLinkwitzRiley m_filter; diff --git a/plugins/CarlaBase/Carla.cpp b/plugins/CarlaBase/Carla.cpp index 197971ee9..f5d5aa574 100644 --- a/plugins/CarlaBase/Carla.cpp +++ b/plugins/CarlaBase/Carla.cpp @@ -495,11 +495,11 @@ void CarlaInstrument::loadSettings(const QDomElement& elem) #endif } -void CarlaInstrument::play(sampleFrame* workingBuffer) +void CarlaInstrument::play(SampleFrame* workingBuffer) { const uint bufsize = Engine::audioEngine()->framesPerPeriod(); - std::memset(workingBuffer, 0, sizeof(sample_t)*bufsize*DEFAULT_CHANNELS); + zeroSampleFrames(workingBuffer, bufsize); if (fHandle == nullptr) { diff --git a/plugins/CarlaBase/Carla.h b/plugins/CarlaBase/Carla.h index da0ae67cc..d8eab5fc4 100644 --- a/plugins/CarlaBase/Carla.h +++ b/plugins/CarlaBase/Carla.h @@ -193,7 +193,7 @@ public: QString nodeName() const override; void saveSettings(QDomDocument& doc, QDomElement& parent) override; void loadSettings(const QDomElement& elem) override; - void play(sampleFrame* workingBuffer) override; + void play(SampleFrame* workingBuffer) override; bool handleMidiEvent(const MidiEvent& event, const TimePos& time, f_cnt_t offset) override; gui::PluginView* instantiateView(QWidget* parent) override; diff --git a/plugins/Compressor/Compressor.cpp b/plugins/Compressor/Compressor.cpp index 1c51d6ddc..c04893361 100755 --- a/plugins/Compressor/Compressor.cpp +++ b/plugins/Compressor/Compressor.cpp @@ -233,7 +233,7 @@ void CompressorEffect::calcMix() -bool CompressorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +bool CompressorEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { diff --git a/plugins/Compressor/Compressor.h b/plugins/Compressor/Compressor.h index 4d6c05d7e..af322de97 100755 --- a/plugins/Compressor/Compressor.h +++ b/plugins/Compressor/Compressor.h @@ -43,7 +43,7 @@ class CompressorEffect : public Effect public: CompressorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~CompressorEffect() override = default; - bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { @@ -105,7 +105,7 @@ private: float m_coeffPrecalc; - sampleFrame m_maxLookaheadVal; + SampleFrame m_maxLookaheadVal; int m_maxLookaheadTimer[2] = {1, 1}; diff --git a/plugins/CrossoverEQ/CrossoverEQ.cpp b/plugins/CrossoverEQ/CrossoverEQ.cpp index 6e59627f6..2784f9b6b 100644 --- a/plugins/CrossoverEQ/CrossoverEQ.cpp +++ b/plugins/CrossoverEQ/CrossoverEQ.cpp @@ -64,9 +64,9 @@ CrossoverEQEffect::CrossoverEQEffect( Model* parent, const Descriptor::SubPlugin m_hp4( m_sampleRate ), m_needsUpdate( true ) { - m_tmp2 = new sampleFrame[Engine::audioEngine()->framesPerPeriod()]; - m_tmp1 = new sampleFrame[Engine::audioEngine()->framesPerPeriod()]; - m_work = new sampleFrame[Engine::audioEngine()->framesPerPeriod()]; + m_tmp2 = new SampleFrame[Engine::audioEngine()->framesPerPeriod()]; + m_tmp1 = new SampleFrame[Engine::audioEngine()->framesPerPeriod()]; + m_work = new SampleFrame[Engine::audioEngine()->framesPerPeriod()]; } CrossoverEQEffect::~CrossoverEQEffect() @@ -89,7 +89,7 @@ void CrossoverEQEffect::sampleRateChanged() } -bool CrossoverEQEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +bool CrossoverEQEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { @@ -139,7 +139,7 @@ bool CrossoverEQEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames m_needsUpdate = false; - memset( m_work, 0, sizeof( sampleFrame ) * frames ); + zeroSampleFrames(m_work, frames); // run temp bands for( int f = 0; f < frames; ++f ) diff --git a/plugins/CrossoverEQ/CrossoverEQ.h b/plugins/CrossoverEQ/CrossoverEQ.h index fe9b4541b..078e51c21 100644 --- a/plugins/CrossoverEQ/CrossoverEQ.h +++ b/plugins/CrossoverEQ/CrossoverEQ.h @@ -40,7 +40,7 @@ class CrossoverEQEffect : public Effect public: CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~CrossoverEQEffect() override; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { @@ -69,9 +69,9 @@ private: StereoLinkwitzRiley m_hp3; StereoLinkwitzRiley m_hp4; - sampleFrame * m_tmp1; - sampleFrame * m_tmp2; - sampleFrame * m_work; + SampleFrame* m_tmp1; + SampleFrame* m_tmp2; + SampleFrame* m_work; bool m_needsUpdate; diff --git a/plugins/Delay/DelayEffect.cpp b/plugins/Delay/DelayEffect.cpp index 71f6fdf9a..4e90c0fa8 100644 --- a/plugins/Delay/DelayEffect.cpp +++ b/plugins/Delay/DelayEffect.cpp @@ -81,7 +81,7 @@ DelayEffect::~DelayEffect() -bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +bool DelayEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { @@ -91,9 +91,8 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) const float sr = Engine::audioEngine()->outputSampleRate(); const float d = dryLevel(); const float w = wetLevel(); - auto dryS = std::array{}; - float lPeak = 0.0; - float rPeak = 0.0; + + SampleFrame peak; float length = m_delayControls.m_delayTimeModel.value(); float amplitude = m_delayControls.m_lfoAmountModel.value() * sr; float lfoTime = 1.0 / m_delayControls.m_lfoTimeModel.value(); @@ -116,26 +115,28 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) m_outGain = dbfsToAmp( m_delayControls.m_outGainModel.value() ); } - for( fpp_t f = 0; f < frames; ++f ) + for (fpp_t f = 0; f < frames; ++f) { - dryS[0] = buf[f][0]; - dryS[1] = buf[f][1]; + auto& currentFrame = buf[f]; + const auto dryS = currentFrame; + // Prepare delay for current sample m_delay->setFeedback( *feedbackPtr ); m_lfo->setFrequency( *lfoTimePtr ); m_currentLength = static_cast(*lengthPtr * Engine::audioEngine()->outputSampleRate()); m_delay->setLength( m_currentLength + ( *amplitudePtr * ( float )m_lfo->tick() ) ); - m_delay->tick( buf[f] ); - buf[f][0] *= m_outGain; - buf[f][1] *= m_outGain; + // Process the wet signal + m_delay->tick( currentFrame ); + currentFrame *= m_outGain; - lPeak = buf[f][0] > lPeak ? buf[f][0] : lPeak; - rPeak = buf[f][1] > rPeak ? buf[f][1] : rPeak; + // Calculate peak of wet signal + peak = peak.absMax(currentFrame); - buf[f][0] = ( d * dryS[0] ) + ( w * buf[f][0] ); - buf[f][1] = ( d * dryS[1] ) + ( w * buf[f][1] ); - outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; + // Dry/wet mix + currentFrame = dryS * d + currentFrame * w; + + outSum += currentFrame.sumOfSquaredAmplitudes(); lengthPtr += lengthInc; amplitudePtr += amplitudeInc; @@ -143,8 +144,8 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) feedbackPtr += feedbackInc; } checkGate( outSum / frames ); - m_delayControls.m_outPeakL = lPeak; - m_delayControls.m_outPeakR = rPeak; + m_delayControls.m_outPeakL = peak.left(); + m_delayControls.m_outPeakR = peak.right(); return isRunning(); } diff --git a/plugins/Delay/DelayEffect.h b/plugins/Delay/DelayEffect.h index b6c090ff0..b7e2cfef0 100644 --- a/plugins/Delay/DelayEffect.h +++ b/plugins/Delay/DelayEffect.h @@ -39,7 +39,7 @@ class DelayEffect : public Effect public: DelayEffect(Model* parent , const Descriptor::SubPluginFeatures::Key* key ); ~DelayEffect() override; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { return &m_delayControls; diff --git a/plugins/Delay/StereoDelay.cpp b/plugins/Delay/StereoDelay.cpp index c03cf68d0..3187b3f2a 100644 --- a/plugins/Delay/StereoDelay.cpp +++ b/plugins/Delay/StereoDelay.cpp @@ -23,7 +23,9 @@ */ #include "StereoDelay.h" + #include "lmms_basics.h" +#include "SampleFrame.h" namespace lmms { @@ -55,7 +57,7 @@ StereoDelay::~StereoDelay() -void StereoDelay::tick( sampleFrame& frame ) +void StereoDelay::tick( SampleFrame& frame ) { m_writeIndex = ( m_writeIndex + 1 ) % ( int )m_maxLength; int readIndex = m_writeIndex - static_cast(m_length); @@ -81,7 +83,7 @@ void StereoDelay::setSampleRate( int sampleRate ) } int bufferSize = ( int )( sampleRate * m_maxTime ); - m_buffer = new sampleFrame[bufferSize]; + m_buffer = new SampleFrame[bufferSize]; for( int i = 0 ; i < bufferSize ; i++) { m_buffer[i][0] = 0.0; diff --git a/plugins/Delay/StereoDelay.h b/plugins/Delay/StereoDelay.h index 0ea0efeed..ad0e020b5 100644 --- a/plugins/Delay/StereoDelay.h +++ b/plugins/Delay/StereoDelay.h @@ -31,6 +31,8 @@ namespace lmms { +class SampleFrame; + class StereoDelay { public: @@ -49,11 +51,11 @@ public: m_feedback = feedback; } - void tick( sampleFrame& frame ); + void tick( SampleFrame& frame ); void setSampleRate( int sampleRate ); private: - sampleFrame* m_buffer; + SampleFrame* m_buffer; int m_maxLength; float m_length; int m_writeIndex; diff --git a/plugins/Dispersion/Dispersion.cpp b/plugins/Dispersion/Dispersion.cpp index 72e4c2103..a2fada615 100644 --- a/plugins/Dispersion/Dispersion.cpp +++ b/plugins/Dispersion/Dispersion.cpp @@ -58,7 +58,7 @@ DispersionEffect::DispersionEffect(Model* parent, const Descriptor::SubPluginFea } -bool DispersionEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +bool DispersionEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { diff --git a/plugins/Dispersion/Dispersion.h b/plugins/Dispersion/Dispersion.h index 9e2014baf..e3d5d4b5c 100644 --- a/plugins/Dispersion/Dispersion.h +++ b/plugins/Dispersion/Dispersion.h @@ -41,7 +41,7 @@ class DispersionEffect : public Effect public: DispersionEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~DispersionEffect() override = default; - bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/DualFilter/DualFilter.cpp b/plugins/DualFilter/DualFilter.cpp index 6f91bb251..b337e1003 100644 --- a/plugins/DualFilter/DualFilter.cpp +++ b/plugins/DualFilter/DualFilter.cpp @@ -77,7 +77,7 @@ DualFilterEffect::~DualFilterEffect() -bool DualFilterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +bool DualFilterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { diff --git a/plugins/DualFilter/DualFilter.h b/plugins/DualFilter/DualFilter.h index 29161039a..6c53f61ef 100644 --- a/plugins/DualFilter/DualFilter.h +++ b/plugins/DualFilter/DualFilter.h @@ -40,7 +40,7 @@ class DualFilterEffect : public Effect public: DualFilterEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~DualFilterEffect() override; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { diff --git a/plugins/DynamicsProcessor/DynamicsProcessor.cpp b/plugins/DynamicsProcessor/DynamicsProcessor.cpp index a11cc28c6..5b251a6f0 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessor.cpp +++ b/plugins/DynamicsProcessor/DynamicsProcessor.cpp @@ -91,7 +91,7 @@ inline void DynProcEffect::calcRelease() } -bool DynProcEffect::processAudioBuffer( sampleFrame * _buf, +bool DynProcEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { if( !isEnabled() || !isRunning () ) diff --git a/plugins/DynamicsProcessor/DynamicsProcessor.h b/plugins/DynamicsProcessor/DynamicsProcessor.h index 576accdcc..970690d8d 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessor.h +++ b/plugins/DynamicsProcessor/DynamicsProcessor.h @@ -42,7 +42,7 @@ public: DynProcEffect( Model * _parent, const Descriptor::SubPluginFeatures::Key * _key ); ~DynProcEffect() override; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; EffectControls * controls() override diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index b81512c1c..662b85a8e 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -64,7 +64,7 @@ EqEffect::EqEffect( Model *parent, const Plugin::Descriptor::SubPluginFeatures:: -bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) +bool EqEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { const int sampleRate = Engine::audioEngine()->outputSampleRate(); @@ -157,7 +157,7 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) } const float outGain = m_outGain; - sampleFrame m_inPeak = { 0, 0 }; + SampleFrame m_inPeak = { 0, 0 }; if(m_eqControls.m_analyseInModel.value( true ) && outSum > 0 && m_eqControls.isViewVisible() ) { @@ -263,7 +263,7 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) } - sampleFrame outPeak = { 0, 0 }; + SampleFrame outPeak = { 0, 0 }; gain( buf, frames, outGain, &outPeak ); m_eqControls.m_outPeakL = m_eqControls.m_outPeakL < outPeak[0] ? outPeak[0] : m_eqControls.m_outPeakL; m_eqControls.m_outPeakR = m_eqControls.m_outPeakR < outPeak[1] ? outPeak[1] : m_eqControls.m_outPeakR; diff --git a/plugins/Eq/EqEffect.h b/plugins/Eq/EqEffect.h index 7e91ee401..ca0ebb1b9 100644 --- a/plugins/Eq/EqEffect.h +++ b/plugins/Eq/EqEffect.h @@ -40,12 +40,12 @@ class EqEffect : public Effect public: EqEffect( Model * parent , const Descriptor::SubPluginFeatures::Key * key ); ~EqEffect() override = default; - bool processAudioBuffer( sampleFrame * buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls * controls() override { return &m_eqControls; } - inline void gain( sampleFrame * buf, const fpp_t frames, float scale, sampleFrame * peak ) + inline void gain( SampleFrame* buf, const fpp_t frames, float scale, SampleFrame* peak ) { peak[0][0] = 0.0f; peak[0][1] = 0.0f; for( fpp_t f = 0; f < frames; ++f ) diff --git a/plugins/Eq/EqFilter.h b/plugins/Eq/EqFilter.h index df2b50493..5408d131c 100644 --- a/plugins/Eq/EqFilter.h +++ b/plugins/Eq/EqFilter.h @@ -432,7 +432,7 @@ public: - virtual void processBuffer( sampleFrame* buf, const fpp_t frames ) + virtual void processBuffer( SampleFrame* buf, const fpp_t frames ) { for ( fpp_t f = 0 ; f < frames ; ++f) { diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index 427fff796..75be48697 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -75,7 +75,7 @@ EqAnalyser::~EqAnalyser() -void EqAnalyser::analyze( sampleFrame *buf, const fpp_t frames ) +void EqAnalyser::analyze( SampleFrame* buf, const fpp_t frames ) { //only analyse if the view is visible if ( m_active ) diff --git a/plugins/Eq/EqSpectrumView.h b/plugins/Eq/EqSpectrumView.h index 947c55434..448c0e378 100644 --- a/plugins/Eq/EqSpectrumView.h +++ b/plugins/Eq/EqSpectrumView.h @@ -32,6 +32,7 @@ namespace lmms { +class SampleFrame; const int MAX_BANDS = 2048; class EqAnalyser @@ -44,7 +45,7 @@ public: bool getInProgress(); void clear(); - void analyze( sampleFrame *buf, const fpp_t frames ); + void analyze( SampleFrame* buf, const fpp_t frames ); float getEnergy() const; int getSampleRate() const; diff --git a/plugins/Flanger/FlangerEffect.cpp b/plugins/Flanger/FlangerEffect.cpp index c06747137..b8bb9d692 100644 --- a/plugins/Flanger/FlangerEffect.cpp +++ b/plugins/Flanger/FlangerEffect.cpp @@ -90,7 +90,7 @@ FlangerEffect::~FlangerEffect() -bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) +bool FlangerEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { diff --git a/plugins/Flanger/FlangerEffect.h b/plugins/Flanger/FlangerEffect.h index 8428d89a3..c4afb8841 100644 --- a/plugins/Flanger/FlangerEffect.h +++ b/plugins/Flanger/FlangerEffect.h @@ -42,7 +42,7 @@ class FlangerEffect : public Effect public: FlangerEffect( Model* parent , const Descriptor::SubPluginFeatures::Key* key ); ~FlangerEffect() override; - bool processAudioBuffer( sampleFrame *buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { return &m_flangerControls; diff --git a/plugins/FreeBoy/FreeBoy.cpp b/plugins/FreeBoy/FreeBoy.cpp index 07497f6c0..d801e82d4 100644 --- a/plugins/FreeBoy/FreeBoy.cpp +++ b/plugins/FreeBoy/FreeBoy.cpp @@ -228,7 +228,7 @@ float FreeBoyInstrument::desiredReleaseTimeMs() const -void FreeBoyInstrument::playNote(NotePlayHandle* nph, sampleFrame* workingBuffer) +void FreeBoyInstrument::playNote(NotePlayHandle* nph, SampleFrame* workingBuffer) { const f_cnt_t tfp = nph->totalFramesPlayed(); const int samplerate = Engine::audioEngine()->outputSampleRate(); diff --git a/plugins/FreeBoy/FreeBoy.h b/plugins/FreeBoy/FreeBoy.h index bba00efbf..3a178fdb1 100644 --- a/plugins/FreeBoy/FreeBoy.h +++ b/plugins/FreeBoy/FreeBoy.h @@ -55,7 +55,7 @@ public: FreeBoyInstrument( InstrumentTrack * _instrument_track ); ~FreeBoyInstrument() override = default; - void playNote(NotePlayHandle* nph, sampleFrame* workingBuffer) override; + void playNote(NotePlayHandle* nph, SampleFrame* workingBuffer) override; void deleteNotePluginData(NotePlayHandle* nph) override; void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index 7c0d0d26b..b6613de7f 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -289,7 +289,7 @@ QString GigInstrument::getCurrentPatchName() // A key has been pressed -void GigInstrument::playNote( NotePlayHandle * _n, sampleFrame * ) +void GigInstrument::playNote( NotePlayHandle * _n, SampleFrame* ) { const float LOG440 = 2.643452676f; @@ -320,7 +320,7 @@ void GigInstrument::playNote( NotePlayHandle * _n, sampleFrame * ) // Process the notes and output a certain number of frames (e.g. 256, set in // the preferences) -void GigInstrument::play( sampleFrame * _working_buffer ) +void GigInstrument::play( SampleFrame* _working_buffer ) { const fpp_t frames = Engine::audioEngine()->framesPerPeriod(); const int rate = Engine::audioEngine()->outputSampleRate(); @@ -441,7 +441,7 @@ void GigInstrument::play( sampleFrame * _working_buffer ) } // Load this note's data - sampleFrame sampleData[samples]; + SampleFrame sampleData[samples]; loadSample(sample, sampleData, samples); // Apply ADSR using a copy so if we don't use these samples when @@ -458,7 +458,7 @@ void GigInstrument::play( sampleFrame * _working_buffer ) // Output the data resampling if needed if( resample == true ) { - sampleFrame convertBuf[frames]; + SampleFrame convertBuf[frames]; // Only output if resampling is successful (note that "used" is output) if (sample.convertSampleRate(*sampleData, *convertBuf, samples, frames, freq_factor, used)) @@ -499,7 +499,7 @@ void GigInstrument::play( sampleFrame * _working_buffer ) -void GigInstrument::loadSample( GigSample& sample, sampleFrame* sampleData, f_cnt_t samples ) +void GigInstrument::loadSample( GigSample& sample, SampleFrame* sampleData, f_cnt_t samples ) { if( sampleData == nullptr || samples < 1 ) { @@ -1182,7 +1182,7 @@ void GigSample::updateSampleRate() -bool GigSample::convertSampleRate( sampleFrame & oldBuf, sampleFrame & newBuf, +bool GigSample::convertSampleRate( SampleFrame & oldBuf, SampleFrame & newBuf, f_cnt_t oldSize, f_cnt_t newSize, float freq_factor, f_cnt_t& used ) { if( srcState == nullptr ) diff --git a/plugins/GigPlayer/GigPlayer.h b/plugins/GigPlayer/GigPlayer.h index 50d1acd40..685c7f546 100644 --- a/plugins/GigPlayer/GigPlayer.h +++ b/plugins/GigPlayer/GigPlayer.h @@ -157,7 +157,7 @@ public: // Needed since libsamplerate stores data internally between calls void updateSampleRate(); - bool convertSampleRate( sampleFrame & oldBuf, sampleFrame & newBuf, + bool convertSampleRate( SampleFrame & oldBuf, SampleFrame & newBuf, f_cnt_t oldSize, f_cnt_t newSize, float freq_factor, f_cnt_t& used ); gig::Sample * sample; @@ -243,10 +243,10 @@ public: GigInstrument( InstrumentTrack * _instrument_track ); ~GigInstrument() override; - void play( sampleFrame * _working_buffer ) override; + void play( SampleFrame* _working_buffer ) override; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; @@ -312,7 +312,7 @@ private: Dimension getDimensions( gig::Region * pRegion, int velocity, bool release ); // Load sample data from the Gig file, looping the sample where needed - void loadSample( GigSample& sample, sampleFrame* sampleData, f_cnt_t samples ); + void loadSample( GigSample& sample, SampleFrame* sampleData, f_cnt_t samples ); f_cnt_t getLoopedIndex( f_cnt_t index, f_cnt_t startf, f_cnt_t endf ) const; f_cnt_t getPingPongIndex( f_cnt_t index, f_cnt_t startf, f_cnt_t endf ) const; diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp index 90c6e86d3..e5af1e8bf 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp @@ -60,7 +60,7 @@ GranularPitchShifterEffect::GranularPitchShifterEffect(Model* parent, const Desc } -bool GranularPitchShifterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +bool GranularPitchShifterEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { return false; } diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h index a50ea8238..c904b4c13 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h @@ -48,7 +48,7 @@ class GranularPitchShifterEffect : public Effect public: GranularPitchShifterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~GranularPitchShifterEffect() override = default; - bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/Kicker/Kicker.cpp b/plugins/Kicker/Kicker.cpp index 06385608f..a71941fc6 100644 --- a/plugins/Kicker/Kicker.cpp +++ b/plugins/Kicker/Kicker.cpp @@ -156,7 +156,7 @@ using DistFX = DspEffectLibrary::Distortion; using SweepOsc = KickerOsc>; void KickerInstrument::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { const fpp_t frames = _n->framesLeftForCurrentPeriod(); const f_cnt_t offset = _n->noteOffset(); diff --git a/plugins/Kicker/Kicker.h b/plugins/Kicker/Kicker.h index 508787707..2eadaa333 100644 --- a/plugins/Kicker/Kicker.h +++ b/plugins/Kicker/Kicker.h @@ -56,7 +56,7 @@ public: ~KickerInstrument() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; void saveSettings(QDomDocument& doc, QDomElement& elem) override; diff --git a/plugins/Kicker/KickerOsc.h b/plugins/Kicker/KickerOsc.h index 69436c5fc..420373512 100644 --- a/plugins/Kicker/KickerOsc.h +++ b/plugins/Kicker/KickerOsc.h @@ -60,7 +60,7 @@ public: virtual ~KickerOsc() = default; - void update( sampleFrame* buf, const fpp_t frames, const float sampleRate ) + void update( SampleFrame* buf, const fpp_t frames, const float sampleRate ) { for( fpp_t frame = 0; frame < frames; ++frame ) { diff --git a/plugins/LOMM/LOMM.cpp b/plugins/LOMM/LOMM.cpp index 72478f6b5..7c4574cd1 100644 --- a/plugins/LOMM/LOMM.cpp +++ b/plugins/LOMM/LOMM.cpp @@ -101,7 +101,7 @@ void LOMMEffect::changeSampleRate() } -bool LOMMEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +bool LOMMEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { diff --git a/plugins/LOMM/LOMM.h b/plugins/LOMM/LOMM.h index 9e03dc343..783233c5f 100644 --- a/plugins/LOMM/LOMM.h +++ b/plugins/LOMM/LOMM.h @@ -45,7 +45,7 @@ class LOMMEffect : public Effect public: LOMMEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~LOMMEffect() override = default; - bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp index ccf92474b..26901c65f 100644 --- a/plugins/LadspaEffect/LadspaEffect.cpp +++ b/plugins/LadspaEffect/LadspaEffect.cpp @@ -129,7 +129,7 @@ void LadspaEffect::changeSampleRate() -bool LadspaEffect::processAudioBuffer( sampleFrame * _buf, +bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { m_pluginMutex.lock(); @@ -140,13 +140,13 @@ bool LadspaEffect::processAudioBuffer( sampleFrame * _buf, } int frames = _frames; - sampleFrame * o_buf = nullptr; - QVarLengthArray sBuf(_frames * DEFAULT_CHANNELS); + SampleFrame* o_buf = nullptr; + QVarLengthArray sBuf(_frames); if( m_maxSampleRate < Engine::audioEngine()->outputSampleRate() ) { o_buf = _buf; - _buf = reinterpret_cast(sBuf.data()); + _buf = sBuf.data(); sampleDown( o_buf, _buf, m_maxSampleRate ); frames = _frames * m_maxSampleRate / Engine::audioEngine()->outputSampleRate(); diff --git a/plugins/LadspaEffect/LadspaEffect.h b/plugins/LadspaEffect/LadspaEffect.h index 8ad4f1411..d5b93d4e2 100644 --- a/plugins/LadspaEffect/LadspaEffect.h +++ b/plugins/LadspaEffect/LadspaEffect.h @@ -47,7 +47,7 @@ public: const Descriptor::SubPluginFeatures::Key * _key ); ~LadspaEffect() override; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; void setControl( int _control, LADSPA_Data _data ); diff --git a/plugins/Lb302/Lb302.cpp b/plugins/Lb302/Lb302.cpp index 17c9b7424..02038239a 100644 --- a/plugins/Lb302/Lb302.cpp +++ b/plugins/Lb302/Lb302.cpp @@ -462,7 +462,7 @@ inline float GET_INC(float freq) { return freq/Engine::audioEngine()->outputSampleRate(); // TODO: Use actual sampling rate. } -int Lb302Synth::process(sampleFrame *outbuf, const int size) +int Lb302Synth::process(SampleFrame* outbuf, const int size) { const float sampleRatio = 44100.f / Engine::audioEngine()->outputSampleRate(); @@ -732,7 +732,7 @@ void Lb302Synth::initSlide() } -void Lb302Synth::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) +void Lb302Synth::playNote( NotePlayHandle * _n, SampleFrame* _working_buffer ) { if( _n->isMasterNote() || ( _n->hasParent() && _n->isReleased() ) ) { @@ -791,7 +791,7 @@ void Lb302Synth::processNote( NotePlayHandle * _n ) -void Lb302Synth::play( sampleFrame * _working_buffer ) +void Lb302Synth::play( SampleFrame* _working_buffer ) { m_notesMutex.lock(); while( ! m_notes.isEmpty() ) diff --git a/plugins/Lb302/Lb302.h b/plugins/Lb302/Lb302.h index 2be9e9567..25a08592c 100644 --- a/plugins/Lb302/Lb302.h +++ b/plugins/Lb302/Lb302.h @@ -152,9 +152,9 @@ public: Lb302Synth( InstrumentTrack * _instrument_track ); ~Lb302Synth() override; - void play( sampleFrame * _working_buffer ) override; + void play( SampleFrame* _working_buffer ) override; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; @@ -246,7 +246,7 @@ private: void recalcFilter(); - int process(sampleFrame *outbuf, const int size); + int process(SampleFrame* outbuf, const int size); friend class gui::Lb302SynthView; diff --git a/plugins/Lv2Effect/Lv2Effect.cpp b/plugins/Lv2Effect/Lv2Effect.cpp index eef6305cc..d6b89a229 100644 --- a/plugins/Lv2Effect/Lv2Effect.cpp +++ b/plugins/Lv2Effect/Lv2Effect.cpp @@ -68,7 +68,7 @@ Lv2Effect::Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key *ke -bool Lv2Effect::processAudioBuffer(sampleFrame *buf, const fpp_t frames) +bool Lv2Effect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { return false; } Q_ASSERT(frames <= static_cast(m_tmpOutputSmps.size())); diff --git a/plugins/Lv2Effect/Lv2Effect.h b/plugins/Lv2Effect/Lv2Effect.h index a28182132..bc81eb590 100644 --- a/plugins/Lv2Effect/Lv2Effect.h +++ b/plugins/Lv2Effect/Lv2Effect.h @@ -42,7 +42,7 @@ public: */ Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key* _key); - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { return &m_controls; } Lv2FxControls* lv2Controls() { return &m_controls; } @@ -50,7 +50,7 @@ public: private: Lv2FxControls m_controls; - std::vector m_tmpOutputSmps; + std::vector m_tmpOutputSmps; }; diff --git a/plugins/Lv2Instrument/Lv2Instrument.cpp b/plugins/Lv2Instrument/Lv2Instrument.cpp index 766790cc1..8da2d913e 100644 --- a/plugins/Lv2Instrument/Lv2Instrument.cpp +++ b/plugins/Lv2Instrument/Lv2Instrument.cpp @@ -177,7 +177,7 @@ bool Lv2Instrument::handleMidiEvent( // not yet working #ifndef LV2_INSTRUMENT_USE_MIDI -void Lv2Instrument::playNote(NotePlayHandle *nph, sampleFrame *) +void Lv2Instrument::playNote(NotePlayHandle *nph, SampleFrame*) { } #endif @@ -185,7 +185,7 @@ void Lv2Instrument::playNote(NotePlayHandle *nph, sampleFrame *) -void Lv2Instrument::play(sampleFrame *buf) +void Lv2Instrument::play(SampleFrame* buf) { copyModelsFromLmms(); diff --git a/plugins/Lv2Instrument/Lv2Instrument.h b/plugins/Lv2Instrument/Lv2Instrument.h index 9ae48c64c..268e7fd10 100644 --- a/plugins/Lv2Instrument/Lv2Instrument.h +++ b/plugins/Lv2Instrument/Lv2Instrument.h @@ -77,9 +77,9 @@ public: bool handleMidiEvent(const MidiEvent &event, const TimePos &time = TimePos(), f_cnt_t offset = 0) override; #else - void playNote(NotePlayHandle *nph, sampleFrame *) override; + void playNote(NotePlayHandle *nph, SampleFrame*) override; #endif - void play(sampleFrame *buf) override; + void play(SampleFrame* buf) override; /* misc diff --git a/plugins/Monstro/Monstro.cpp b/plugins/Monstro/Monstro.cpp index 4278b7cdb..c9b715ba7 100644 --- a/plugins/Monstro/Monstro.cpp +++ b/plugins/Monstro/Monstro.cpp @@ -110,7 +110,7 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph ) : } -void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) +void MonstroSynth::renderOutput( fpp_t _frames, SampleFrame* _buf ) { float modtmp; // temp variable for freq modulation // macros for modulating with env/lfos @@ -1062,7 +1062,7 @@ MonstroInstrument::MonstroInstrument( InstrumentTrack * _instrument_track ) : void MonstroInstrument::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { const fpp_t frames = _n->framesLeftForCurrentPeriod(); const f_cnt_t offset = _n->noteOffset(); diff --git a/plugins/Monstro/Monstro.h b/plugins/Monstro/Monstro.h index 0df18d5c4..da705b9ff 100644 --- a/plugins/Monstro/Monstro.h +++ b/plugins/Monstro/Monstro.h @@ -177,7 +177,7 @@ public: MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph ); virtual ~MonstroSynth() = default; - void renderOutput( fpp_t _frames, sampleFrame * _buf ); + void renderOutput( fpp_t _frames, SampleFrame* _buf ); private: @@ -357,7 +357,7 @@ public: ~MonstroInstrument() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; void saveSettings( QDomDocument & _doc, diff --git a/plugins/MultitapEcho/MultitapEcho.cpp b/plugins/MultitapEcho/MultitapEcho.cpp index c64567f9b..e779f2283 100644 --- a/plugins/MultitapEcho/MultitapEcho.cpp +++ b/plugins/MultitapEcho/MultitapEcho.cpp @@ -58,7 +58,7 @@ MultitapEchoEffect::MultitapEchoEffect( Model* parent, const Descriptor::SubPlug m_sampleRate( Engine::audioEngine()->outputSampleRate() ), m_sampleRatio( 1.0f / m_sampleRate ) { - m_work = new sampleFrame[Engine::audioEngine()->framesPerPeriod()]; + m_work = new SampleFrame[Engine::audioEngine()->framesPerPeriod()]; m_buffer.reset(); m_stages = static_cast( m_controls.m_stages.value() ); updateFilters( 0, 19 ); @@ -83,7 +83,7 @@ void MultitapEchoEffect::updateFilters( int begin, int end ) } -void MultitapEchoEffect::runFilter( sampleFrame * dst, sampleFrame * src, StereoOnePole & filter, const fpp_t frames ) +void MultitapEchoEffect::runFilter( SampleFrame* dst, SampleFrame* src, StereoOnePole & filter, const fpp_t frames ) { for( int f = 0; f < frames; ++f ) { @@ -93,7 +93,7 @@ void MultitapEchoEffect::runFilter( sampleFrame * dst, sampleFrame * src, Stereo } -bool MultitapEchoEffect::processAudioBuffer( sampleFrame * buf, const fpp_t frames ) +bool MultitapEchoEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { diff --git a/plugins/MultitapEcho/MultitapEcho.h b/plugins/MultitapEcho/MultitapEcho.h index 6145b9f86..d6e981fbd 100644 --- a/plugins/MultitapEcho/MultitapEcho.h +++ b/plugins/MultitapEcho/MultitapEcho.h @@ -40,7 +40,7 @@ class MultitapEchoEffect : public Effect public: MultitapEchoEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~MultitapEchoEffect() override; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { @@ -49,7 +49,7 @@ public: private: void updateFilters( int begin, int end ); - void runFilter( sampleFrame * dst, sampleFrame * src, StereoOnePole & filter, const fpp_t frames ); + void runFilter( SampleFrame* dst, SampleFrame* src, StereoOnePole & filter, const fpp_t frames ); inline void setFilterFreq( float fc, StereoOnePole & f ) { @@ -70,7 +70,7 @@ private: float m_sampleRate; float m_sampleRatio; - sampleFrame * m_work; + SampleFrame* m_work; friend class MultitapEchoControls; diff --git a/plugins/Nes/Nes.cpp b/plugins/Nes/Nes.cpp index c5cc3b0d0..fb7c52459 100644 --- a/plugins/Nes/Nes.cpp +++ b/plugins/Nes/Nes.cpp @@ -103,7 +103,7 @@ NesObject::NesObject( NesInstrument * nes, const sample_rate_t samplerate, NoteP } -void NesObject::renderOutput( sampleFrame * buf, fpp_t frames ) +void NesObject::renderOutput( SampleFrame* buf, fpp_t frames ) { //////////////////////////////// // // @@ -545,7 +545,7 @@ NesInstrument::NesInstrument( InstrumentTrack * instrumentTrack ) : -void NesInstrument::playNote( NotePlayHandle * n, sampleFrame * workingBuffer ) +void NesInstrument::playNote( NotePlayHandle * n, SampleFrame* workingBuffer ) { const fpp_t frames = n->framesLeftForCurrentPeriod(); const f_cnt_t offset = n->noteOffset(); diff --git a/plugins/Nes/Nes.h b/plugins/Nes/Nes.h index e65cb3b13..207c22e83 100644 --- a/plugins/Nes/Nes.h +++ b/plugins/Nes/Nes.h @@ -95,7 +95,7 @@ public: NesObject( NesInstrument * nes, const sample_rate_t samplerate, NotePlayHandle * nph ); virtual ~NesObject() = default; - void renderOutput( sampleFrame * buf, fpp_t frames ); + void renderOutput( SampleFrame* buf, fpp_t frames ); void updateVibrato( float * freq ); void updatePitch(); @@ -212,7 +212,7 @@ public: ~NesInstrument() override = default; void playNote( NotePlayHandle * n, - sampleFrame * workingBuffer ) override; + SampleFrame* workingBuffer ) override; void deleteNotePluginData( NotePlayHandle * n ) override; diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index 3c6004477..5fd4bf58a 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -390,7 +390,7 @@ gui::PluginView* OpulenzInstrument::instantiateView( QWidget * _parent ) } -void OpulenzInstrument::play( sampleFrame * _working_buffer ) +void OpulenzInstrument::play( SampleFrame* _working_buffer ) { emulatorMutex.lock(); theEmulator->update(renderbuffer, frameCount); diff --git a/plugins/OpulenZ/OpulenZ.h b/plugins/OpulenZ/OpulenZ.h index a245b03ad..bd51c9cf5 100644 --- a/plugins/OpulenZ/OpulenZ.h +++ b/plugins/OpulenZ/OpulenZ.h @@ -65,7 +65,7 @@ public: gui::PluginView* instantiateView( QWidget * _parent ) override; bool handleMidiEvent( const MidiEvent& event, const TimePos& time, f_cnt_t offset = 0 ) override; - void play( sampleFrame * _working_buffer ) override; + void play( SampleFrame* _working_buffer ) override; void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; void loadSettings( const QDomElement & _this ) override; diff --git a/plugins/Organic/Organic.cpp b/plugins/Organic/Organic.cpp index e7b0cf792..54c36a510 100644 --- a/plugins/Organic/Organic.cpp +++ b/plugins/Organic/Organic.cpp @@ -221,7 +221,7 @@ QString OrganicInstrument::nodeName() const void OrganicInstrument::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { const fpp_t frames = _n->framesLeftForCurrentPeriod(); const f_cnt_t offset = _n->noteOffset(); diff --git a/plugins/Organic/Organic.h b/plugins/Organic/Organic.h index e50550e5e..5a066af43 100644 --- a/plugins/Organic/Organic.h +++ b/plugins/Organic/Organic.h @@ -125,7 +125,7 @@ public: ~OrganicInstrument() override; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/Patman/Patman.cpp b/plugins/Patman/Patman.cpp index d2f4aee4e..6165bd537 100644 --- a/plugins/Patman/Patman.cpp +++ b/plugins/Patman/Patman.cpp @@ -134,7 +134,7 @@ QString PatmanInstrument::nodeName() const void PatmanInstrument::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { if( m_patchFile == "" ) { @@ -160,7 +160,7 @@ void PatmanInstrument::playNote( NotePlayHandle * _n, } else { - memset( _working_buffer, 0, ( frames + offset ) * sizeof( sampleFrame ) ); + zeroSampleFrames(_working_buffer, frames + offset); } } @@ -342,7 +342,7 @@ PatmanInstrument::LoadError PatmanInstrument::loadPatch( } } - auto data = new sampleFrame[frames]; + auto data = new SampleFrame[frames]; for( f_cnt_t frame = 0; frame < frames; ++frame ) { diff --git a/plugins/Patman/Patman.h b/plugins/Patman/Patman.h index 16b98deee..a77c2607f 100644 --- a/plugins/Patman/Patman.h +++ b/plugins/Patman/Patman.h @@ -60,7 +60,7 @@ public: ~PatmanInstrument() override; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.cpp b/plugins/PeakControllerEffect/PeakControllerEffect.cpp index 7aff6f803..af64d0095 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffect.cpp @@ -93,7 +93,7 @@ PeakControllerEffect::~PeakControllerEffect() } -bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf, +bool PeakControllerEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { PeakControllerEffectControls & c = m_peakControls; diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.h b/plugins/PeakControllerEffect/PeakControllerEffect.h index f2bafedda..dc6e507f3 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.h +++ b/plugins/PeakControllerEffect/PeakControllerEffect.h @@ -41,7 +41,7 @@ public: PeakControllerEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * _key ); ~PeakControllerEffect() override; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; EffectControls * controls() override diff --git a/plugins/ReverbSC/ReverbSC.cpp b/plugins/ReverbSC/ReverbSC.cpp index c73e421ec..2def88d1d 100644 --- a/plugins/ReverbSC/ReverbSC.cpp +++ b/plugins/ReverbSC/ReverbSC.cpp @@ -75,7 +75,7 @@ ReverbSCEffect::~ReverbSCEffect() sp_destroy(&sp); } -bool ReverbSCEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +bool ReverbSCEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) { if( !isEnabled() || !isRunning () ) { diff --git a/plugins/ReverbSC/ReverbSC.h b/plugins/ReverbSC/ReverbSC.h index 2cb119bff..f3c196f5b 100644 --- a/plugins/ReverbSC/ReverbSC.h +++ b/plugins/ReverbSC/ReverbSC.h @@ -45,7 +45,7 @@ class ReverbSCEffect : public Effect public: ReverbSCEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~ReverbSCEffect() override; - bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override; + bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; EffectControls* controls() override { diff --git a/plugins/Sf2Player/Sf2Player.cpp b/plugins/Sf2Player/Sf2Player.cpp index c2a9eca98..fd1d6b1a3 100644 --- a/plugins/Sf2Player/Sf2Player.cpp +++ b/plugins/Sf2Player/Sf2Player.cpp @@ -647,7 +647,7 @@ void Sf2Instrument::reloadSynth() -void Sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * ) +void Sf2Instrument::playNote( NotePlayHandle * _n, SampleFrame* ) { if( _n->isMasterNote() || ( _n->hasParent() && _n->isReleased() ) ) { @@ -782,7 +782,7 @@ void Sf2Instrument::noteOff( Sf2PluginData * n ) } -void Sf2Instrument::play( sampleFrame * _working_buffer ) +void Sf2Instrument::play( SampleFrame* _working_buffer ) { const fpp_t frames = Engine::audioEngine()->framesPerPeriod(); @@ -868,7 +868,7 @@ void Sf2Instrument::play( sampleFrame * _working_buffer ) } -void Sf2Instrument::renderFrames( f_cnt_t frames, sampleFrame * buf ) +void Sf2Instrument::renderFrames( f_cnt_t frames, SampleFrame* buf ) { m_synthMutex.lock(); fluid_synth_get_gain(m_synth); // This flushes voice updates as a side effect @@ -877,9 +877,9 @@ void Sf2Instrument::renderFrames( f_cnt_t frames, sampleFrame * buf ) { const fpp_t f = frames * m_internalSampleRate / Engine::audioEngine()->outputSampleRate(); #ifdef __GNUC__ - sampleFrame tmp[f]; + SampleFrame tmp[f]; #else - sampleFrame * tmp = new sampleFrame[f]; + SampleFrame* tmp = new SampleFrame[f]; #endif fluid_synth_write_float( m_synth, f, tmp, 0, 2, tmp, 1, 2 ); diff --git a/plugins/Sf2Player/Sf2Player.h b/plugins/Sf2Player/Sf2Player.h index ec7ace47f..b752cd9c3 100644 --- a/plugins/Sf2Player/Sf2Player.h +++ b/plugins/Sf2Player/Sf2Player.h @@ -64,10 +64,10 @@ public: Sf2Instrument( InstrumentTrack * _instrument_track ); ~Sf2Instrument() override; - void play( sampleFrame * _working_buffer ) override; + void play( SampleFrame* _working_buffer ) override; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; @@ -150,7 +150,7 @@ private: void freeFont(); void noteOn( Sf2PluginData * n ); void noteOff( Sf2PluginData * n ); - void renderFrames( f_cnt_t frames, sampleFrame * buf ); + void renderFrames( f_cnt_t frames, SampleFrame* buf ); friend class gui::Sf2InstrumentView; diff --git a/plugins/Sfxr/Sfxr.cpp b/plugins/Sfxr/Sfxr.cpp index 3817706fc..0279eb41a 100644 --- a/plugins/Sfxr/Sfxr.cpp +++ b/plugins/Sfxr/Sfxr.cpp @@ -157,7 +157,7 @@ void SfxrSynth::resetSample( bool restart ) -void SfxrSynth::update( sampleFrame * buffer, const int32_t frameNum ) +void SfxrSynth::update( SampleFrame* buffer, const int32_t frameNum ) { for(int i=0;ioutputSampleRate(); @@ -454,7 +454,7 @@ void SfxrInstrument::playNote( NotePlayHandle * _n, sampleFrame * _working_buffe } else if( static_cast(_n->m_pluginData)->isPlaying() == false ) { - memset(_working_buffer + offset, 0, sizeof(sampleFrame) * frameNum); + zeroSampleFrames(_working_buffer + offset, frameNum); _n->noteOff(); return; } @@ -467,7 +467,7 @@ void SfxrInstrument::playNote( NotePlayHandle * _n, sampleFrame * _working_buffe // debug code // qDebug( "pFN %d", pitchedFrameNum ); - auto pitchedBuffer = new sampleFrame[pitchedFrameNum]; + auto pitchedBuffer = new SampleFrame[pitchedFrameNum]; static_cast(_n->m_pluginData)->update( pitchedBuffer, pitchedFrameNum ); for( fpp_t i=0; ioutputSampleRate(); diff --git a/plugins/Sid/SidInstrument.h b/plugins/Sid/SidInstrument.h index 8d5af8df0..79ad7f32a 100644 --- a/plugins/Sid/SidInstrument.h +++ b/plugins/Sid/SidInstrument.h @@ -102,7 +102,7 @@ public: ~SidInstrument() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/SlicerT/SlicerT.cpp b/plugins/SlicerT/SlicerT.cpp index d01cdfc36..3644060ed 100644 --- a/plugins/SlicerT/SlicerT.cpp +++ b/plugins/SlicerT/SlicerT.cpp @@ -75,7 +75,7 @@ SlicerT::SlicerT(InstrumentTrack* instrumentTrack) m_sliceSnap.setValue(0); } -void SlicerT::playNote(NotePlayHandle* handle, sampleFrame* workingBuffer) +void SlicerT::playNote(NotePlayHandle* handle, SampleFrame* workingBuffer) { if (m_originalSample.sampleSize() <= 1) { return; } diff --git a/plugins/SlicerT/SlicerT.h b/plugins/SlicerT/SlicerT.h index 010985dfc..06b55687b 100644 --- a/plugins/SlicerT/SlicerT.h +++ b/plugins/SlicerT/SlicerT.h @@ -75,7 +75,7 @@ signals: public: SlicerT(InstrumentTrack* instrumentTrack); - void playNote(NotePlayHandle* handle, sampleFrame* workingBuffer) override; + void playNote(NotePlayHandle* handle, SampleFrame* workingBuffer) override; void deleteNotePluginData(NotePlayHandle* handle) override; void saveSettings(QDomDocument& document, QDomElement& element) override; diff --git a/plugins/SpectrumAnalyzer/Analyzer.cpp b/plugins/SpectrumAnalyzer/Analyzer.cpp index 0bbada7db..dc2108eb9 100644 --- a/plugins/SpectrumAnalyzer/Analyzer.cpp +++ b/plugins/SpectrumAnalyzer/Analyzer.cpp @@ -77,7 +77,7 @@ Analyzer::~Analyzer() } // Take audio data and pass them to the spectrum processor. -bool Analyzer::processAudioBuffer(sampleFrame *buffer, const fpp_t frame_count) +bool Analyzer::processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) { // Measure time spent in audio thread; both average and peak should be well under 1 ms. #ifdef SA_DEBUG diff --git a/plugins/SpectrumAnalyzer/Analyzer.h b/plugins/SpectrumAnalyzer/Analyzer.h index 5be1f9ba8..da87ffd35 100644 --- a/plugins/SpectrumAnalyzer/Analyzer.h +++ b/plugins/SpectrumAnalyzer/Analyzer.h @@ -45,7 +45,7 @@ public: Analyzer(Model *parent, const Descriptor::SubPluginFeatures::Key *key); ~Analyzer() override; - bool processAudioBuffer(sampleFrame *buffer, const fpp_t frame_count) override; + bool processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) override; EffectControls *controls() override {return &m_controls;} SaProcessor *getProcessor() {return &m_processor;} @@ -63,7 +63,7 @@ private: //m_processorThread = QThread::create([=]{m_processor.analyze(m_inputBuffer);}); DataprocLauncher m_processorThread; - LocklessRingBuffer m_inputBuffer; + LocklessRingBuffer m_inputBuffer; #ifdef SA_DEBUG int m_last_dump_time; diff --git a/plugins/SpectrumAnalyzer/DataprocLauncher.h b/plugins/SpectrumAnalyzer/DataprocLauncher.h index 4325284c9..43bac6a43 100644 --- a/plugins/SpectrumAnalyzer/DataprocLauncher.h +++ b/plugins/SpectrumAnalyzer/DataprocLauncher.h @@ -37,7 +37,7 @@ namespace lmms class DataprocLauncher : public QThread { public: - explicit DataprocLauncher(SaProcessor &proc, LocklessRingBuffer &buffer) + explicit DataprocLauncher(SaProcessor &proc, LocklessRingBuffer &buffer) : m_processor(&proc), m_inputBuffer(&buffer) { @@ -50,7 +50,7 @@ private: } SaProcessor *m_processor; - LocklessRingBuffer *m_inputBuffer; + LocklessRingBuffer *m_inputBuffer; }; diff --git a/plugins/SpectrumAnalyzer/SaProcessor.cpp b/plugins/SpectrumAnalyzer/SaProcessor.cpp index b991ad3ea..e0eef8b59 100644 --- a/plugins/SpectrumAnalyzer/SaProcessor.cpp +++ b/plugins/SpectrumAnalyzer/SaProcessor.cpp @@ -98,9 +98,9 @@ SaProcessor::~SaProcessor() // Load data from audio thread ringbuffer and run FFT analysis if buffer is full enough. -void SaProcessor::analyze(LocklessRingBuffer &ring_buffer) +void SaProcessor::analyze(LocklessRingBuffer &ring_buffer) { - LocklessRingBufferReader reader(ring_buffer); + LocklessRingBufferReader reader(ring_buffer); // Processing thread loop while (!m_terminate) diff --git a/plugins/SpectrumAnalyzer/SaProcessor.h b/plugins/SpectrumAnalyzer/SaProcessor.h index 66b79788d..3903bf9d6 100644 --- a/plugins/SpectrumAnalyzer/SaProcessor.h +++ b/plugins/SpectrumAnalyzer/SaProcessor.h @@ -43,7 +43,7 @@ template class LocklessRingBuffer; class SaControls; - +class SampleFrame; //! Receives audio data, runs FFT analysis and stores the result. @@ -54,7 +54,7 @@ public: virtual ~SaProcessor(); // analysis thread and a method to terminate it - void analyze(LocklessRingBuffer &ring_buffer); + void analyze(LocklessRingBuffer &ring_buffer); void terminate() {m_terminate = true;} // inform processor if any processing is actually required diff --git a/plugins/StereoEnhancer/StereoEnhancer.cpp b/plugins/StereoEnhancer/StereoEnhancer.cpp index 784003056..d5ed8d99d 100644 --- a/plugins/StereoEnhancer/StereoEnhancer.cpp +++ b/plugins/StereoEnhancer/StereoEnhancer.cpp @@ -58,7 +58,7 @@ StereoEnhancerEffect::StereoEnhancerEffect( const Descriptor::SubPluginFeatures::Key * _key ) : Effect( &stereoenhancer_plugin_descriptor, _parent, _key ), m_seFX( DspEffectLibrary::StereoEnhancer( 0.0f ) ), - m_delayBuffer( new sampleFrame[DEFAULT_BUFFER_SIZE] ), + m_delayBuffer( new SampleFrame[DEFAULT_BUFFER_SIZE] ), m_currFrame( 0 ), m_bbControls( this ) { @@ -82,7 +82,7 @@ StereoEnhancerEffect::~StereoEnhancerEffect() -bool StereoEnhancerEffect::processAudioBuffer( sampleFrame * _buf, +bool StereoEnhancerEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { diff --git a/plugins/StereoEnhancer/StereoEnhancer.h b/plugins/StereoEnhancer/StereoEnhancer.h index 5872100d3..861187f8f 100644 --- a/plugins/StereoEnhancer/StereoEnhancer.h +++ b/plugins/StereoEnhancer/StereoEnhancer.h @@ -40,7 +40,7 @@ public: StereoEnhancerEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * _key ); ~StereoEnhancerEffect() override; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; EffectControls * controls() override @@ -54,7 +54,7 @@ public: private: DspEffectLibrary::StereoEnhancer m_seFX; - sampleFrame * m_delayBuffer; + SampleFrame* m_delayBuffer; int m_currFrame; StereoEnhancerControls m_bbControls; diff --git a/plugins/StereoMatrix/StereoMatrix.cpp b/plugins/StereoMatrix/StereoMatrix.cpp index b96d2e107..c4384fddd 100644 --- a/plugins/StereoMatrix/StereoMatrix.cpp +++ b/plugins/StereoMatrix/StereoMatrix.cpp @@ -64,7 +64,7 @@ StereoMatrixEffect::StereoMatrixEffect( -bool StereoMatrixEffect::processAudioBuffer( sampleFrame * _buf, +bool StereoMatrixEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { diff --git a/plugins/StereoMatrix/StereoMatrix.h b/plugins/StereoMatrix/StereoMatrix.h index ae7a59724..a254264f8 100644 --- a/plugins/StereoMatrix/StereoMatrix.h +++ b/plugins/StereoMatrix/StereoMatrix.h @@ -39,7 +39,7 @@ public: StereoMatrixEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * _key ); ~StereoMatrixEffect() override = default; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; EffectControls* controls() override diff --git a/plugins/Stk/Mallets/Mallets.cpp b/plugins/Stk/Mallets/Mallets.cpp index 4a3068d1c..00ddbf422 100644 --- a/plugins/Stk/Mallets/Mallets.cpp +++ b/plugins/Stk/Mallets/Mallets.cpp @@ -278,7 +278,7 @@ QString MalletsInstrument::nodeName() const void MalletsInstrument::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { if( m_filesMissing ) { diff --git a/plugins/Stk/Mallets/Mallets.h b/plugins/Stk/Mallets/Mallets.h index 91e2dfce1..cf05ace66 100644 --- a/plugins/Stk/Mallets/Mallets.h +++ b/plugins/Stk/Mallets/Mallets.h @@ -189,7 +189,7 @@ public: ~MalletsInstrument() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/TripleOscillator/TripleOscillator.cpp b/plugins/TripleOscillator/TripleOscillator.cpp index 97b773e67..f04cee818 100644 --- a/plugins/TripleOscillator/TripleOscillator.cpp +++ b/plugins/TripleOscillator/TripleOscillator.cpp @@ -307,7 +307,7 @@ QString TripleOscillator::nodeName() const void TripleOscillator::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { if (!_n->m_pluginData) { diff --git a/plugins/TripleOscillator/TripleOscillator.h b/plugins/TripleOscillator/TripleOscillator.h index 011352de4..fd6fc85ee 100644 --- a/plugins/TripleOscillator/TripleOscillator.h +++ b/plugins/TripleOscillator/TripleOscillator.h @@ -112,7 +112,7 @@ public: ~TripleOscillator() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/Vectorscope/VectorView.cpp b/plugins/Vectorscope/VectorView.cpp index c4776a688..2077d12cd 100644 --- a/plugins/Vectorscope/VectorView.cpp +++ b/plugins/Vectorscope/VectorView.cpp @@ -37,7 +37,7 @@ namespace lmms::gui { -VectorView::VectorView(VecControls *controls, LocklessRingBuffer *inputBuffer, unsigned short displaySize, QWidget *parent) : +VectorView::VectorView(VecControls *controls, LocklessRingBuffer *inputBuffer, unsigned short displaySize, QWidget *parent) : QWidget(parent), m_controls(controls), m_inputBuffer(inputBuffer), diff --git a/plugins/Vectorscope/VectorView.h b/plugins/Vectorscope/VectorView.h index 59ac99a77..c828fd139 100644 --- a/plugins/Vectorscope/VectorView.h +++ b/plugins/Vectorscope/VectorView.h @@ -30,6 +30,7 @@ namespace lmms { class VecControls; +class SampleFrame; } //#define VEC_DEBUG @@ -43,7 +44,7 @@ class VectorView : public QWidget { Q_OBJECT public: - explicit VectorView(VecControls *controls, LocklessRingBuffer *inputBuffer, unsigned short displaySize, QWidget *parent = 0); + explicit VectorView(VecControls *controls, LocklessRingBuffer *inputBuffer, unsigned short displaySize, QWidget *parent = 0); ~VectorView() override = default; QSize sizeHint() const override {return QSize(300, 300);} @@ -59,8 +60,8 @@ private slots: private: VecControls *m_controls; - LocklessRingBuffer *m_inputBuffer; - LocklessRingBufferReader m_bufferReader; + LocklessRingBuffer *m_inputBuffer; + LocklessRingBufferReader m_bufferReader; std::vector m_displayBuffer; const unsigned short m_displaySize; diff --git a/plugins/Vectorscope/Vectorscope.cpp b/plugins/Vectorscope/Vectorscope.cpp index f843fc86d..c94eb5d28 100644 --- a/plugins/Vectorscope/Vectorscope.cpp +++ b/plugins/Vectorscope/Vectorscope.cpp @@ -58,7 +58,7 @@ Vectorscope::Vectorscope(Model *parent, const Plugin::Descriptor::SubPluginFeatu // Take audio data and store them for processing and display in the GUI thread. -bool Vectorscope::processAudioBuffer(sampleFrame *buffer, const fpp_t frame_count) +bool Vectorscope::processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) { if (!isEnabled() || !isRunning ()) {return false;} diff --git a/plugins/Vectorscope/Vectorscope.h b/plugins/Vectorscope/Vectorscope.h index 54022ab90..66d20e639 100644 --- a/plugins/Vectorscope/Vectorscope.h +++ b/plugins/Vectorscope/Vectorscope.h @@ -39,16 +39,16 @@ public: Vectorscope(Model *parent, const Descriptor::SubPluginFeatures::Key *key); ~Vectorscope() override = default; - bool processAudioBuffer(sampleFrame *buffer, const fpp_t frame_count) override; + bool processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) override; EffectControls *controls() override {return &m_controls;} - LocklessRingBuffer *getBuffer() {return &m_inputBuffer;} + LocklessRingBuffer *getBuffer() {return &m_inputBuffer;} private: VecControls m_controls; // Maximum LMMS buffer size (hard coded, the actual constant is hard to get) const unsigned int m_maxBufferSize = 4096; - LocklessRingBuffer m_inputBuffer; + LocklessRingBuffer m_inputBuffer; }; diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index 1de713960..ffed82af7 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -395,7 +395,7 @@ void VestigeInstrument::loadFile( const QString & _file ) -void VestigeInstrument::play( sampleFrame * _buf ) +void VestigeInstrument::play( SampleFrame* _buf ) { if (!m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) {return;} diff --git a/plugins/Vestige/Vestige.h b/plugins/Vestige/Vestige.h index 529893ba0..6a308ad2c 100644 --- a/plugins/Vestige/Vestige.h +++ b/plugins/Vestige/Vestige.h @@ -61,7 +61,7 @@ public: VestigeInstrument( InstrumentTrack * _instrument_track ); virtual ~VestigeInstrument(); - virtual void play( sampleFrame * _working_buffer ); + virtual void play( SampleFrame* _working_buffer ); virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); virtual void loadSettings( const QDomElement & _this ); diff --git a/plugins/Vibed/Vibed.cpp b/plugins/Vibed/Vibed.cpp index f99c9140d..c4dd08afa 100644 --- a/plugins/Vibed/Vibed.cpp +++ b/plugins/Vibed/Vibed.cpp @@ -201,7 +201,7 @@ QString Vibed::nodeName() const return vibedstrings_plugin_descriptor.name; } -void Vibed::playNote(NotePlayHandle* n, sampleFrame* workingBuffer) +void Vibed::playNote(NotePlayHandle* n, SampleFrame* workingBuffer) { if (!n->m_pluginData) { diff --git a/plugins/Vibed/Vibed.h b/plugins/Vibed/Vibed.h index ec8395da1..f02f810de 100644 --- a/plugins/Vibed/Vibed.h +++ b/plugins/Vibed/Vibed.h @@ -57,7 +57,7 @@ public: Vibed(InstrumentTrack* instrumentTrack); ~Vibed() override = default; - void playNote(NotePlayHandle* n, sampleFrame* workingBuffer) override; + void playNote(NotePlayHandle* n, SampleFrame* workingBuffer) override; void deleteNotePluginData(NotePlayHandle* n) override; void saveSettings(QDomDocument& doc, QDomElement& elem) override; diff --git a/plugins/VstBase/RemoteVstPlugin.cpp b/plugins/VstBase/RemoteVstPlugin.cpp index 0ec60bea4..ba40bcb68 100644 --- a/plugins/VstBase/RemoteVstPlugin.cpp +++ b/plugins/VstBase/RemoteVstPlugin.cpp @@ -191,7 +191,7 @@ public: void hideEditor(); void destroyEditor(); - virtual void process( const sampleFrame * _in, sampleFrame * _out ); + virtual void process( const SampleFrame* _in, SampleFrame* _out ); virtual void processMidiEvent( const MidiEvent& event, const f_cnt_t offset ); @@ -1027,7 +1027,7 @@ bool RemoteVstPlugin::load( const std::string & _plugin_file ) -void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out ) +void RemoteVstPlugin::process( const SampleFrame* _in, SampleFrame* _out ) { // first we gonna post all MIDI-events we enqueued so far if( m_midiEvents.size() ) diff --git a/plugins/VstEffect/VstEffect.cpp b/plugins/VstEffect/VstEffect.cpp index bdbdea806..ecb8240c8 100644 --- a/plugins/VstEffect/VstEffect.cpp +++ b/plugins/VstEffect/VstEffect.cpp @@ -76,7 +76,7 @@ VstEffect::VstEffect( Model * _parent, -bool VstEffect::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) +bool VstEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { if( !isEnabled() || !isRunning () ) { @@ -87,11 +87,11 @@ bool VstEffect::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) { const float d = dryLevel(); #ifdef __GNUC__ - sampleFrame buf[_frames]; + SampleFrame buf[_frames]; #else - sampleFrame * buf = new sampleFrame[_frames]; + SampleFrame* buf = new SampleFrame[_frames]; #endif - memcpy( buf, _buf, sizeof( sampleFrame ) * _frames ); + memcpy( buf, _buf, sizeof( SampleFrame ) * _frames ); if (m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) { m_plugin->process( buf, buf ); diff --git a/plugins/VstEffect/VstEffect.h b/plugins/VstEffect/VstEffect.h index 987b1ecc2..c3f6e8091 100644 --- a/plugins/VstEffect/VstEffect.h +++ b/plugins/VstEffect/VstEffect.h @@ -45,7 +45,7 @@ public: const Descriptor::SubPluginFeatures::Key * _key ); ~VstEffect() override = default; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; EffectControls * controls() override diff --git a/plugins/Watsyn/Watsyn.cpp b/plugins/Watsyn/Watsyn.cpp index 822f9b519..2749b2daf 100644 --- a/plugins/Watsyn/Watsyn.cpp +++ b/plugins/Watsyn/Watsyn.cpp @@ -74,8 +74,8 @@ WatsynObject::WatsynObject( float * _A1wave, float * _A2wave, m_fpp( _frames ), m_parent( _w ) { - m_abuf = new sampleFrame[_frames]; - m_bbuf = new sampleFrame[_frames]; + m_abuf = new SampleFrame[_frames]; + m_bbuf = new SampleFrame[_frames]; m_lphase[A1_OSC] = 0.0f; m_lphase[A2_OSC] = 0.0f; @@ -107,9 +107,9 @@ WatsynObject::~WatsynObject() void WatsynObject::renderOutput( fpp_t _frames ) { if( m_abuf == nullptr ) - m_abuf = new sampleFrame[m_fpp]; + m_abuf = new SampleFrame[m_fpp]; if( m_bbuf == nullptr ) - m_bbuf = new sampleFrame[m_fpp]; + m_bbuf = new SampleFrame[m_fpp]; for( fpp_t frame = 0; frame < _frames; frame++ ) { @@ -327,7 +327,7 @@ WatsynInstrument::WatsynInstrument( InstrumentTrack * _instrument_track ) : void WatsynInstrument::playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) + SampleFrame* _working_buffer ) { if (!_n->m_pluginData) { @@ -339,12 +339,12 @@ void WatsynInstrument::playNote( NotePlayHandle * _n, const fpp_t frames = _n->framesLeftForCurrentPeriod(); const f_cnt_t offset = _n->noteOffset(); - sampleFrame * buffer = _working_buffer + offset; + SampleFrame* buffer = _working_buffer + offset; auto w = static_cast(_n->m_pluginData); - sampleFrame * abuf = w->abuf(); - sampleFrame * bbuf = w->bbuf(); + SampleFrame* abuf = w->abuf(); + SampleFrame* bbuf = w->bbuf(); w-> renderOutput( frames ); diff --git a/plugins/Watsyn/Watsyn.h b/plugins/Watsyn/Watsyn.h index b34e28f60..aebc74645 100644 --- a/plugins/Watsyn/Watsyn.h +++ b/plugins/Watsyn/Watsyn.h @@ -96,11 +96,11 @@ public: void renderOutput( fpp_t _frames ); - inline sampleFrame * abuf() const + inline SampleFrame* abuf() const { return m_abuf; } - inline sampleFrame * bbuf() const + inline SampleFrame* bbuf() const { return m_bbuf; } @@ -120,8 +120,8 @@ private: WatsynInstrument * m_parent; - sampleFrame * m_abuf; - sampleFrame * m_bbuf; + SampleFrame* m_abuf; + SampleFrame* m_bbuf; float m_lphase [NUM_OSCS]; float m_rphase [NUM_OSCS]; @@ -140,7 +140,7 @@ public: ~WatsynInstrument() override = default; void playNote( NotePlayHandle * _n, - sampleFrame * _working_buffer ) override; + SampleFrame* _working_buffer ) override; void deleteNotePluginData( NotePlayHandle * _n ) override; diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index acd5a933b..373785408 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -66,7 +66,7 @@ WaveShaperEffect::WaveShaperEffect( Model * _parent, -bool WaveShaperEffect::processAudioBuffer( sampleFrame * _buf, +bool WaveShaperEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) { if( !isEnabled() || !isRunning () ) diff --git a/plugins/WaveShaper/WaveShaper.h b/plugins/WaveShaper/WaveShaper.h index 4c63d5806..4c9d6e962 100644 --- a/plugins/WaveShaper/WaveShaper.h +++ b/plugins/WaveShaper/WaveShaper.h @@ -40,7 +40,7 @@ public: WaveShaperEffect( Model * _parent, const Descriptor::SubPluginFeatures::Key * _key ); ~WaveShaperEffect() override = default; - bool processAudioBuffer( sampleFrame * _buf, + bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) override; EffectControls * controls() override diff --git a/plugins/Xpressive/ExprSynth.cpp b/plugins/Xpressive/ExprSynth.cpp index 0dde9ff96..ef5d3dbf1 100644 --- a/plugins/Xpressive/ExprSynth.cpp +++ b/plugins/Xpressive/ExprSynth.cpp @@ -34,6 +34,7 @@ #include "interpolation.h" #include "lmms_math.h" #include "NotePlayHandle.h" +#include "SampleFrame.h" #include @@ -735,7 +736,7 @@ ExprSynth::~ExprSynth() } } -void ExprSynth::renderOutput(fpp_t frames, sampleFrame *buf) +void ExprSynth::renderOutput(fpp_t frames, SampleFrame* buf) { try { diff --git a/plugins/Xpressive/ExprSynth.h b/plugins/Xpressive/ExprSynth.h index 5d664c85e..3348ed9f4 100644 --- a/plugins/Xpressive/ExprSynth.h +++ b/plugins/Xpressive/ExprSynth.h @@ -37,6 +37,7 @@ namespace lmms class ExprFrontData; class NotePlayHandle; +class SampleFrame; namespace gui { @@ -106,7 +107,7 @@ public: const sample_rate_t sample_rate, const FloatModel* pan1, const FloatModel* pan2, float rel_trans); virtual ~ExprSynth(); - void renderOutput(fpp_t frames, sampleFrame* buf ); + void renderOutput(fpp_t frames, SampleFrame* buf ); private: diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index e90abb24c..3fb1fc5f2 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -196,7 +196,7 @@ QString Xpressive::nodeName() const { return (xpressive_plugin_descriptor.name); } -void Xpressive::playNote(NotePlayHandle* nph, sampleFrame* working_buffer) { +void Xpressive::playNote(NotePlayHandle* nph, SampleFrame* working_buffer) { m_A1=m_parameterA1.value(); m_A2=m_parameterA2.value(); m_A3=m_parameterA3.value(); diff --git a/plugins/Xpressive/Xpressive.h b/plugins/Xpressive/Xpressive.h index 974b82b17..7dd8dcfaa 100644 --- a/plugins/Xpressive/Xpressive.h +++ b/plugins/Xpressive/Xpressive.h @@ -68,7 +68,7 @@ public: Xpressive(InstrumentTrack* instrument_track ); void playNote(NotePlayHandle* nph, - sampleFrame* working_buffer ) override; + SampleFrame* working_buffer ) override; void deleteNotePluginData( NotePlayHandle* nph ) override; diff --git a/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp b/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp index a98cfa1e1..5dc8fb205 100644 --- a/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/LocalZynAddSubFx.cpp @@ -36,6 +36,7 @@ #endif #include "MidiEvent.h" +#include "SampleFrame.h" #include #include @@ -265,7 +266,7 @@ void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event ) -void LocalZynAddSubFx::processAudio( sampleFrame * _out ) +void LocalZynAddSubFx::processAudio( SampleFrame* _out ) { #ifdef _MSC_VER const auto outputl = static_cast(_alloca(synth->buffersize * sizeof(float))); diff --git a/plugins/ZynAddSubFx/LocalZynAddSubFx.h b/plugins/ZynAddSubFx/LocalZynAddSubFx.h index f37a3e0f4..096534d5e 100644 --- a/plugins/ZynAddSubFx/LocalZynAddSubFx.h +++ b/plugins/ZynAddSubFx/LocalZynAddSubFx.h @@ -34,10 +34,12 @@ namespace lmms { class MidiEvent; +class SampleFrame; class LocalZynAddSubFx { + public: LocalZynAddSubFx(); ~LocalZynAddSubFx(); @@ -59,7 +61,7 @@ public: void processMidiEvent( const MidiEvent& event ); - void processAudio( sampleFrame * _out ); + void processAudio( SampleFrame* _out ); inline Master * master() { diff --git a/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp b/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp index 104be5cac..d6b3b7b34 100644 --- a/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/RemoteZynAddSubFx.cpp @@ -141,7 +141,7 @@ public: } - void process( const sampleFrame * _in, sampleFrame * _out ) override + void process( const SampleFrame* _in, SampleFrame* _out ) override { LocalZynAddSubFx::processAudio( _out ); } diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.cpp b/plugins/ZynAddSubFx/ZynAddSubFx.cpp index a058c5b1e..c0287cd8b 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/ZynAddSubFx.cpp @@ -328,7 +328,7 @@ QString ZynAddSubFxInstrument::nodeName() const -void ZynAddSubFxInstrument::play( sampleFrame * _buf ) +void ZynAddSubFxInstrument::play( SampleFrame* _buf ) { if (!m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) {return;} if( m_remotePlugin ) diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.h b/plugins/ZynAddSubFx/ZynAddSubFx.h index 2b30c6a3e..a35bc8f79 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.h +++ b/plugins/ZynAddSubFx/ZynAddSubFx.h @@ -74,7 +74,7 @@ public: ZynAddSubFxInstrument( InstrumentTrack * _instrument_track ); ~ZynAddSubFxInstrument() override; - void play( sampleFrame * _working_buffer ) override; + void play( SampleFrame* _working_buffer ) override; bool handleMidiEvent( const MidiEvent& event, const TimePos& time = TimePos(), f_cnt_t offset = 0 ) override; diff --git a/src/core/AudioEngine.cpp b/src/core/AudioEngine.cpp index d4fd643ac..8bb8648ac 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -95,7 +95,7 @@ AudioEngine::AudioEngine( bool renderOnly ) : { m_inputBufferFrames[i] = 0; m_inputBufferSize[i] = DEFAULT_BUFFER_SIZE * 100; - m_inputBuffer[i] = new sampleFrame[ DEFAULT_BUFFER_SIZE * 100 ]; + m_inputBuffer[i] = new SampleFrame[ DEFAULT_BUFFER_SIZE * 100 ]; BufferManager::clear( m_inputBuffer[i], m_inputBufferSize[i] ); } @@ -136,8 +136,8 @@ AudioEngine::AudioEngine( bool renderOnly ) : // now that framesPerPeriod is fixed initialize global BufferManager BufferManager::init( m_framesPerPeriod ); - m_outputBufferRead = std::make_unique(m_framesPerPeriod); - m_outputBufferWrite = std::make_unique(m_framesPerPeriod); + m_outputBufferRead = std::make_unique(m_framesPerPeriod); + m_outputBufferWrite = std::make_unique(m_framesPerPeriod); for( int i = 0; i < m_numWorkers+1; ++i ) @@ -279,19 +279,19 @@ bool AudioEngine::criticalXRuns() const -void AudioEngine::pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames ) +void AudioEngine::pushInputFrames( SampleFrame* _ab, const f_cnt_t _frames ) { requestChangeInModel(); f_cnt_t frames = m_inputBufferFrames[ m_inputBufferWrite ]; int size = m_inputBufferSize[ m_inputBufferWrite ]; - sampleFrame * buf = m_inputBuffer[ m_inputBufferWrite ]; + SampleFrame* buf = m_inputBuffer[ m_inputBufferWrite ]; if( frames + _frames > size ) { size = std::max(size * 2, frames + _frames); - auto ab = new sampleFrame[size]; - memcpy( ab, buf, frames * sizeof( sampleFrame ) ); + auto ab = new SampleFrame[size]; + memcpy( ab, buf, frames * sizeof( SampleFrame ) ); delete [] buf; m_inputBufferSize[ m_inputBufferWrite ] = size; @@ -300,7 +300,7 @@ void AudioEngine::pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames ) buf = ab; } - memcpy( &buf[ frames ], _ab, _frames * sizeof( sampleFrame ) ); + memcpy( &buf[ frames ], _ab, _frames * sizeof( SampleFrame ) ); m_inputBufferFrames[ m_inputBufferWrite ] += _frames; doneChangeInModel(); @@ -429,7 +429,7 @@ void AudioEngine::renderStageMix() -const surroundSampleFrame* AudioEngine::renderNextBuffer() +const SampleFrame* AudioEngine::renderNextBuffer() { const auto lock = std::lock_guard{m_changeMutex}; @@ -457,7 +457,7 @@ void AudioEngine::swapBuffers() m_inputBufferFrames[m_inputBufferWrite] = 0; std::swap(m_outputBufferRead, m_outputBufferWrite); - std::fill_n(m_outputBufferWrite.get(), m_framesPerPeriod, surroundSampleFrame{}); + zeroSampleFrames(m_outputBufferWrite.get(), m_framesPerPeriod); } @@ -548,32 +548,6 @@ void AudioEngine::clearInternal() -AudioEngine::StereoSample AudioEngine::getPeakValues(sampleFrame * ab, const f_cnt_t frames) const -{ - sample_t peakLeft = 0.0f; - sample_t peakRight = 0.0f; - - for (f_cnt_t f = 0; f < frames; ++f) - { - float const absLeft = std::abs(ab[f][0]); - float const absRight = std::abs(ab[f][1]); - if (absLeft > peakLeft) - { - peakLeft = absLeft; - } - - if (absRight > peakRight) - { - peakRight = absRight; - } - } - - return StereoSample(peakLeft, peakRight); -} - - - - void AudioEngine::changeQuality(const struct qualitySettings & qs) { // don't delete the audio-device @@ -1226,9 +1200,9 @@ void AudioEngine::fifoWriter::run() const fpp_t frames = m_audioEngine->framesPerPeriod(); while( m_writing ) { - auto buffer = new surroundSampleFrame[frames]; - const surroundSampleFrame * b = m_audioEngine->renderNextBuffer(); - memcpy( buffer, b, frames * sizeof( surroundSampleFrame ) ); + auto buffer = new SampleFrame[frames]; + const SampleFrame* b = m_audioEngine->renderNextBuffer(); + memcpy(buffer, b, frames * sizeof(SampleFrame)); m_fifo->write(buffer); } diff --git a/src/core/BufferManager.cpp b/src/core/BufferManager.cpp index 2362be85a..a7a051e26 100644 --- a/src/core/BufferManager.cpp +++ b/src/core/BufferManager.cpp @@ -26,6 +26,8 @@ #include "BufferManager.h" +#include "SampleFrame.h" + #include @@ -40,26 +42,18 @@ void BufferManager::init( fpp_t fpp ) } -sampleFrame * BufferManager::acquire() +SampleFrame* BufferManager::acquire() { - return new sampleFrame[s_framesPerPeriod]; + return new SampleFrame[s_framesPerPeriod]; } -void BufferManager::clear( sampleFrame *ab, const f_cnt_t frames, const f_cnt_t offset ) +void BufferManager::clear( SampleFrame* ab, const f_cnt_t frames, const f_cnt_t offset ) { - memset( ab + offset, 0, sizeof( *ab ) * frames ); + zeroSampleFrames(ab + offset, frames); } -#ifndef LMMS_DISABLE_SURROUND -void BufferManager::clear( surroundSampleFrame * ab, const f_cnt_t frames, - const f_cnt_t offset ) -{ - memset( ab + offset, 0, sizeof( *ab ) * frames ); -} -#endif - -void BufferManager::release( sampleFrame * buf ) +void BufferManager::release( SampleFrame* buf ) { delete[] buf; } diff --git a/src/core/Effect.cpp b/src/core/Effect.cpp index aa6e56cd2..61680be2a 100644 --- a/src/core/Effect.cpp +++ b/src/core/Effect.cpp @@ -31,6 +31,7 @@ #include "EffectView.h" #include "ConfigManager.h" +#include "SampleFrame.h" namespace lmms { @@ -199,9 +200,9 @@ void Effect::reinitSRC() -void Effect::resample( int _i, const sampleFrame * _src_buf, +void Effect::resample( int _i, const SampleFrame* _src_buf, sample_rate_t _src_sr, - sampleFrame * _dst_buf, sample_rate_t _dst_sr, + SampleFrame* _dst_buf, sample_rate_t _dst_sr, f_cnt_t _frames ) { if( m_srcState[_i] == nullptr ) diff --git a/src/core/EffectChain.cpp b/src/core/EffectChain.cpp index 4da5c5197..0a6a496f3 100644 --- a/src/core/EffectChain.cpp +++ b/src/core/EffectChain.cpp @@ -184,7 +184,7 @@ void EffectChain::moveUp( Effect * _effect ) -bool EffectChain::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, bool hasInputNoise ) +bool EffectChain::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames, bool hasInputNoise ) { if( m_enabledModel.value() == false ) { diff --git a/src/core/Instrument.cpp b/src/core/Instrument.cpp index ca7ea7f25..893fccbf5 100644 --- a/src/core/Instrument.cpp +++ b/src/core/Instrument.cpp @@ -45,7 +45,7 @@ Instrument::Instrument(InstrumentTrack * _instrument_track, { } -void Instrument::play( sampleFrame * ) +void Instrument::play( SampleFrame* ) { } @@ -89,7 +89,7 @@ bool Instrument::isFromTrack( const Track * _track ) const } // helper function for Instrument::applyFadeIn -static int countZeroCrossings(sampleFrame *buf, fpp_t start, fpp_t frames) +static int countZeroCrossings(SampleFrame* buf, fpp_t start, fpp_t frames) { // zero point crossing counts of all channels auto zeroCrossings = std::array{}; @@ -128,7 +128,7 @@ fpp_t getFadeInLength(float maxLength, fpp_t frames, int zeroCrossings) } -void Instrument::applyFadeIn(sampleFrame * buf, NotePlayHandle * n) +void Instrument::applyFadeIn(SampleFrame* buf, NotePlayHandle * n) { const static float MAX_FADE_IN_LENGTH = 85.0; f_cnt_t total = n->totalFramesPlayed(); @@ -179,7 +179,7 @@ void Instrument::applyFadeIn(sampleFrame * buf, NotePlayHandle * n) } } -void Instrument::applyRelease( sampleFrame * buf, const NotePlayHandle * _n ) +void Instrument::applyRelease( SampleFrame* buf, const NotePlayHandle * _n ) { const auto fpp = Engine::audioEngine()->framesPerPeriod(); const auto releaseFrames = desiredReleaseFrames(); diff --git a/src/core/InstrumentPlayHandle.cpp b/src/core/InstrumentPlayHandle.cpp index ef7d78f3f..afae852a0 100644 --- a/src/core/InstrumentPlayHandle.cpp +++ b/src/core/InstrumentPlayHandle.cpp @@ -40,7 +40,7 @@ InstrumentPlayHandle::InstrumentPlayHandle(Instrument * instrument, InstrumentTr setAudioPort(instrumentTrack->audioPort()); } -void InstrumentPlayHandle::play(sampleFrame * working_buffer) +void InstrumentPlayHandle::play(SampleFrame* working_buffer) { InstrumentTrack * instrumentTrack = m_instrument->instrumentTrack(); diff --git a/src/core/InstrumentSoundShaping.cpp b/src/core/InstrumentSoundShaping.cpp index a7e344a7a..a57ce6ce5 100644 --- a/src/core/InstrumentSoundShaping.cpp +++ b/src/core/InstrumentSoundShaping.cpp @@ -127,7 +127,7 @@ float InstrumentSoundShaping::volumeLevel( NotePlayHandle* n, const f_cnt_t fram -void InstrumentSoundShaping::processAudioBuffer( sampleFrame* buffer, +void InstrumentSoundShaping::processAudioBuffer( SampleFrame* buffer, const fpp_t frames, NotePlayHandle* n ) { diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index 209640b70..01ea0386e 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -32,6 +32,7 @@ #include #include "ValueBuffer.h" +#include "SampleFrame.h" @@ -43,7 +44,7 @@ namespace lmms::MixHelpers /*! \brief Function for applying MIXOP on all sample frames */ template -static inline void run( sampleFrame* dst, const sampleFrame* src, int frames, const MIXOP& OP ) +static inline void run( SampleFrame* dst, const SampleFrame* src, int frames, const MIXOP& OP ) { for( int i = 0; i < frames; ++i ) { @@ -53,18 +54,18 @@ static inline void run( sampleFrame* dst, const sampleFrame* src, int frames, co /*! \brief Function for applying MIXOP on all sample frames - split source */ template -static inline void run( sampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, int frames, const MIXOP& OP ) +static inline void run( SampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, int frames, const MIXOP& OP ) { for( int i = 0; i < frames; ++i ) { - const sampleFrame src = { srcLeft[i], srcRight[i] }; + const SampleFrame src = { srcLeft[i], srcRight[i] }; OP( dst[i], src ); } } -bool isSilent( const sampleFrame* src, int frames ) +bool isSilent( const SampleFrame* src, int frames ) { const float silenceThreshold = 0.0000001f; @@ -90,55 +91,49 @@ void setNaNHandler( bool use ) } /*! \brief Function for sanitizing a buffer of infs/nans - returns true if those are found */ -bool sanitize( sampleFrame * src, int frames ) +bool sanitize( SampleFrame* src, int frames ) { if( !useNaNHandler() ) { return false; } - bool found = false; - for( int f = 0; f < frames; ++f ) + for (int f = 0; f < frames; ++f) { - for( int c = 0; c < 2; ++c ) + auto& currentFrame = src[f]; + + if (currentFrame.containsInf() || currentFrame.containsNaN()) { - if( std::isinf( src[f][c] ) || std::isnan( src[f][c] ) ) - { - #ifdef LMMS_DEBUG + #ifdef LMMS_DEBUG // TODO don't use printf here printf("Bad data, clearing buffer. frame: "); - printf("%d: value %f\n", f, src[f][c]); - #endif - for( int f = 0; f < frames; ++f ) - { - for( int c = 0; c < 2; ++c ) - { - src[f][c] = 0.0f; - } - } - found = true; - return found; - } - else - { - src[f][c] = std::clamp(src[f][c], -1000.0f, 1000.0f); - } + printf("%d: value %f, %f\n", f, currentFrame.left(), currentFrame.right()); + #endif + + // Clear the whole buffer if a problem is found + zeroSampleFrames(src, frames); + + return true; } - } - return found; + else + { + currentFrame.clamp(sample_t(-1000.0), sample_t(1000.0)); + } + }; + + return false; } struct AddOp { - void operator()( sampleFrame& dst, const sampleFrame& src ) const + void operator()( SampleFrame& dst, const SampleFrame& src ) const { - dst[0] += src[0]; - dst[1] += src[1]; + dst += src; } } ; -void add( sampleFrame* dst, const sampleFrame* src, int frames ) +void add( SampleFrame* dst, const SampleFrame* src, int frames ) { run<>( dst, src, frames, AddOp() ); } @@ -149,17 +144,16 @@ struct AddMultipliedOp { AddMultipliedOp( float coeff ) : m_coeff( coeff ) { } - void operator()( sampleFrame& dst, const sampleFrame& src ) const + void operator()( SampleFrame& dst, const SampleFrame& src ) const { - dst[0] += src[0] * m_coeff; - dst[1] += src[1] * m_coeff; + dst += src * m_coeff; } const float m_coeff; } ; -void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) +void addMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames ) { run<>( dst, src, frames, AddMultipliedOp(coeffSrc) ); } @@ -169,7 +163,7 @@ struct AddSwappedMultipliedOp { AddSwappedMultipliedOp( float coeff ) : m_coeff( coeff ) { } - void operator()( sampleFrame& dst, const sampleFrame& src ) const + void operator()( SampleFrame& dst, const SampleFrame& src ) const { dst[0] += src[1] * m_coeff; dst[1] += src[0] * m_coeff; @@ -178,22 +172,21 @@ struct AddSwappedMultipliedOp const float m_coeff; }; -void multiply(sampleFrame* dst, float coeff, int frames) +void multiply(SampleFrame* dst, float coeff, int frames) { for (int i = 0; i < frames; ++i) { - dst[i][0] *= coeff; - dst[i][1] *= coeff; + dst[i] *= coeff; } } -void addSwappedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) +void addSwappedMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames ) { run<>( dst, src, frames, AddSwappedMultipliedOp(coeffSrc) ); } -void addMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) +void addMultipliedByBuffer( SampleFrame* dst, const SampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) { for( int f = 0; f < frames; ++f ) { @@ -202,7 +195,7 @@ void addMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coef } } -void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) +void addMultipliedByBuffers( SampleFrame* dst, const SampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) { for( int f = 0; f < frames; ++f ) { @@ -212,7 +205,7 @@ void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuff } -void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) +void addSanitizedMultipliedByBuffer( SampleFrame* dst, const SampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) { if ( !useNaNHandler() ) { @@ -228,7 +221,7 @@ void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, f } } -void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) +void addSanitizedMultipliedByBuffers( SampleFrame* dst, const SampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) { if ( !useNaNHandler() ) { @@ -254,7 +247,7 @@ struct AddSanitizedMultipliedOp { AddSanitizedMultipliedOp( float coeff ) : m_coeff( coeff ) { } - void operator()( sampleFrame& dst, const sampleFrame& src ) const + void operator()( SampleFrame& dst, const SampleFrame& src ) const { dst[0] += ( std::isinf( src[0] ) || std::isnan( src[0] ) ) ? 0.0f : src[0] * m_coeff; dst[1] += ( std::isinf( src[1] ) || std::isnan( src[1] ) ) ? 0.0f : src[1] * m_coeff; @@ -263,7 +256,7 @@ struct AddSanitizedMultipliedOp const float m_coeff; }; -void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) +void addSanitizedMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames ) { if ( !useNaNHandler() ) { @@ -284,7 +277,7 @@ struct AddMultipliedStereoOp m_coeffs[1] = coeffRight; } - void operator()( sampleFrame& dst, const sampleFrame& src ) const + void operator()( SampleFrame& dst, const SampleFrame& src ) const { dst[0] += src[0] * m_coeffs[0]; dst[1] += src[1] * m_coeffs[1]; @@ -294,7 +287,7 @@ struct AddMultipliedStereoOp } ; -void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ) +void addMultipliedStereo( SampleFrame* dst, const SampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ) { run<>( dst, src, frames, AddMultipliedStereoOp(coeffSrcLeft, coeffSrcRight) ); @@ -312,7 +305,7 @@ struct MultiplyAndAddMultipliedOp m_coeffs[1] = coeffSrc; } - void operator()( sampleFrame& dst, const sampleFrame& src ) const + void operator()( SampleFrame& dst, const SampleFrame& src ) const { dst[0] = dst[0]*m_coeffs[0] + src[0]*m_coeffs[1]; dst[1] = dst[1]*m_coeffs[0] + src[1]*m_coeffs[1]; @@ -322,14 +315,14 @@ struct MultiplyAndAddMultipliedOp } ; -void multiplyAndAddMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffDst, float coeffSrc, int frames ) +void multiplyAndAddMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffDst, float coeffSrc, int frames ) { run<>( dst, src, frames, MultiplyAndAddMultipliedOp(coeffDst, coeffSrc) ); } -void multiplyAndAddMultipliedJoined( sampleFrame* dst, +void multiplyAndAddMultipliedJoined( SampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, float coeffDst, float coeffSrc, int frames ) diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index dd68b55d3..0b0689eb5 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -64,7 +64,7 @@ MixerChannel::MixerChannel( int idx, Model * _parent ) : m_stillRunning( false ), m_peakLeft( 0.0f ), m_peakRight( 0.0f ), - m_buffer( new sampleFrame[Engine::audioEngine()->framesPerPeriod()] ), + m_buffer( new SampleFrame[Engine::audioEngine()->framesPerPeriod()] ), m_muteModel( false, _parent ), m_soloModel( false, _parent ), m_volumeModel(1.f, 0.f, 2.f, 0.001f, _parent), @@ -134,7 +134,7 @@ void MixerChannel::doProcessing() ValueBuffer * volBuf = sender->m_volumeModel.valueBuffer(); // mix it's output with this one's output - sampleFrame * ch_buf = sender->m_buffer; + SampleFrame* ch_buf = sender->m_buffer; // use sample-exact mixing if sample-exact values are available if( ! volBuf && ! sendBuf ) // neither volume nor send has sample-exact data... @@ -171,9 +171,9 @@ void MixerChannel::doProcessing() m_stillRunning = m_fxChain.processAudioBuffer( m_buffer, fpp, m_hasInput ); - AudioEngine::StereoSample peakSamples = Engine::audioEngine()->getPeakValues(m_buffer, fpp); - m_peakLeft = std::max(m_peakLeft, peakSamples.left * v); - m_peakRight = std::max(m_peakRight, peakSamples.right * v); + SampleFrame peakSamples = getAbsPeakValues(m_buffer, fpp); + m_peakLeft = std::max(m_peakLeft, peakSamples[0] * v); + m_peakRight = std::max(m_peakRight, peakSamples[1] * v); } else { @@ -596,7 +596,7 @@ FloatModel * Mixer::channelSendModel( mix_ch_t fromChannel, mix_ch_t toChannel ) -void Mixer::mixToChannel( const sampleFrame * _buf, mix_ch_t _ch ) +void Mixer::mixToChannel( const SampleFrame* _buf, mix_ch_t _ch ) { if( m_mixerChannels[_ch]->m_muteModel.value() == false ) { @@ -618,7 +618,7 @@ void Mixer::prepareMasterMix() -void Mixer::masterMix( sampleFrame * _buf ) +void Mixer::masterMix( SampleFrame* _buf ) { const int fpp = Engine::audioEngine()->framesPerPeriod(); diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index d7882b525..4ee30054a 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -183,7 +183,7 @@ int NotePlayHandle::midiKey() const -void NotePlayHandle::play( sampleFrame * _working_buffer ) +void NotePlayHandle::play( SampleFrame* _working_buffer ) { if (m_muted) { diff --git a/src/core/Oscillator.cpp b/src/core/Oscillator.cpp index e45a3aa87..d24e82d98 100644 --- a/src/core/Oscillator.cpp +++ b/src/core/Oscillator.cpp @@ -77,7 +77,7 @@ Oscillator::Oscillator(const IntModel *wave_shape_model, -void Oscillator::update(sampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator) +void Oscillator::update(SampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator) { if (m_freq >= Engine::audioEngine()->outputSampleRate() / 2) { @@ -316,7 +316,7 @@ void Oscillator::generateWaveTables() -void Oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateNoSub( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { switch( static_cast(m_waveShapeModel->value()) ) @@ -352,7 +352,7 @@ void Oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames, -void Oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updatePM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { switch( static_cast(m_waveShapeModel->value()) ) @@ -388,7 +388,7 @@ void Oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames, -void Oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateAM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { switch( static_cast(m_waveShapeModel->value()) ) @@ -424,7 +424,7 @@ void Oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames, -void Oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateMix( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { switch( static_cast(m_waveShapeModel->value()) ) @@ -460,7 +460,7 @@ void Oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames, -void Oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateSync( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { switch( static_cast(m_waveShapeModel->value()) ) @@ -496,7 +496,7 @@ void Oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames, -void Oscillator::updateFM( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateFM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { switch( static_cast(m_waveShapeModel->value()) ) @@ -558,7 +558,7 @@ inline bool Oscillator::syncOk( float _osc_coeff ) -float Oscillator::syncInit( sampleFrame * _ab, const fpp_t _frames, +float Oscillator::syncInit( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { if( m_subOsc != nullptr ) @@ -574,7 +574,7 @@ float Oscillator::syncInit( sampleFrame * _ab, const fpp_t _frames, // if we have no sub-osc, we can't do any modulation... just get our samples template -void Oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateNoSub( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { recalcPhase(); @@ -592,7 +592,7 @@ void Oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames, // do pm by using sub-osc as modulator template -void Oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updatePM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { m_subOsc->update( _ab, _frames, _chnl, true ); @@ -613,7 +613,7 @@ void Oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames, // do am by using sub-osc as modulator template -void Oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateAM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { m_subOsc->update( _ab, _frames, _chnl, false ); @@ -632,7 +632,7 @@ void Oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames, // do mix by using sub-osc as mix-sample template -void Oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateMix( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { m_subOsc->update( _ab, _frames, _chnl, false ); @@ -652,7 +652,7 @@ void Oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames, // sync with sub-osc (every time sub-osc starts new period, we also start new // period) template -void Oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateSync( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { const float sub_osc_coeff = m_subOsc->syncInit( _ab, _frames, _chnl ); @@ -675,7 +675,7 @@ void Oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames, // do fm by using sub-osc as modulator template -void Oscillator::updateFM( sampleFrame * _ab, const fpp_t _frames, +void Oscillator::updateFM( SampleFrame* _ab, const fpp_t _frames, const ch_cnt_t _chnl ) { m_subOsc->update( _ab, _frames, _chnl, true ); diff --git a/src/core/PlayHandle.cpp b/src/core/PlayHandle.cpp index 168121e0f..eb90f6b65 100644 --- a/src/core/PlayHandle.cpp +++ b/src/core/PlayHandle.cpp @@ -70,9 +70,9 @@ void PlayHandle::releaseBuffer() m_bufferReleased = true; } -sampleFrame* PlayHandle::buffer() +SampleFrame* PlayHandle::buffer() { - return m_bufferReleased ? nullptr : reinterpret_cast(m_playHandleBuffer); + return m_bufferReleased ? nullptr : m_playHandleBuffer; }; } // namespace lmms \ No newline at end of file diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index 0930de0de..8db5644c6 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -206,7 +206,7 @@ PresetPreviewPlayHandle::~PresetPreviewPlayHandle() -void PresetPreviewPlayHandle::play( sampleFrame * _working_buffer ) +void PresetPreviewPlayHandle::play( SampleFrame* _working_buffer ) { // Do nothing; the preview instrument is played by m_previewNote, which // has been added to the audio engine diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index b46c547da..4cfcc313c 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -325,7 +325,7 @@ bool RemotePlugin::init(const QString &pluginExecutable, -bool RemotePlugin::process( const sampleFrame * _in_buf, sampleFrame * _out_buf ) +bool RemotePlugin::process( const SampleFrame* _in_buf, SampleFrame* _out_buf ) { const fpp_t frames = Engine::audioEngine()->framesPerPeriod(); @@ -376,11 +376,12 @@ bool RemotePlugin::process( const sampleFrame * _in_buf, sampleFrame * _out_buf } else if( inputs == DEFAULT_CHANNELS ) { - memcpy( m_audioBuffer.get(), _in_buf, frames * BYTES_PER_FRAME ); + auto target = m_audioBuffer.get(); + copyFromSampleFrames(target, _in_buf, frames); } else { - auto o = (sampleFrame*)m_audioBuffer.get(); + auto o = (SampleFrame*)m_audioBuffer.get(); for( ch_cnt_t ch = 0; ch < inputs; ++ch ) { for( fpp_t frame = 0; frame < frames; ++frame ) @@ -418,12 +419,12 @@ bool RemotePlugin::process( const sampleFrame * _in_buf, sampleFrame * _out_buf } else if( outputs == DEFAULT_CHANNELS ) { - memcpy( _out_buf, m_audioBuffer.get() + m_inputCount * frames, - frames * BYTES_PER_FRAME ); + auto source = m_audioBuffer.get() + m_inputCount * frames; + copyToSampleFrames(_out_buf, source, frames); } else { - auto o = (sampleFrame*)(m_audioBuffer.get() + m_inputCount * frames); + auto o = (SampleFrame*)(m_audioBuffer.get() + m_inputCount * frames); // clear buffer, if plugin didn't fill up both channels BufferManager::clear( _out_buf, frames ); diff --git a/src/core/RingBuffer.cpp b/src/core/RingBuffer.cpp index 6cd3613ed..133af843a 100644 --- a/src/core/RingBuffer.cpp +++ b/src/core/RingBuffer.cpp @@ -37,8 +37,8 @@ RingBuffer::RingBuffer( f_cnt_t size ) : m_samplerate( Engine::audioEngine()->outputSampleRate() ), m_size( size + m_fpp ) { - m_buffer = new sampleFrame[ m_size ]; - memset( m_buffer, 0, m_size * sizeof( sampleFrame ) ); + m_buffer = new SampleFrame[ m_size ]; + zeroSampleFrames(m_buffer, m_size); m_position = 0; } @@ -48,8 +48,8 @@ RingBuffer::RingBuffer( float size ) : m_samplerate( Engine::audioEngine()->outputSampleRate() ) { m_size = msToFrames( size ) + m_fpp; - m_buffer = new sampleFrame[ m_size ]; - memset( m_buffer, 0, m_size * sizeof( sampleFrame ) ); + m_buffer = new SampleFrame[ m_size ]; + zeroSampleFrames(m_buffer, m_size); m_position = 0; setSamplerateAware( true ); //qDebug( "m_size %d, m_position %d", m_size, m_position ); @@ -64,7 +64,7 @@ RingBuffer::~RingBuffer() void RingBuffer::reset() { - memset( m_buffer, 0, m_size * sizeof( sampleFrame ) ); + zeroSampleFrames(m_buffer, m_size); m_position = 0; } @@ -72,10 +72,10 @@ void RingBuffer::reset() void RingBuffer::changeSize( f_cnt_t size ) { size += m_fpp; - sampleFrame * tmp = m_buffer; + SampleFrame* tmp = m_buffer; m_size = size; - m_buffer = new sampleFrame[ m_size ]; - memset( m_buffer, 0, m_size * sizeof( sampleFrame ) ); + m_buffer = new SampleFrame[ m_size ]; + zeroSampleFrames(m_buffer, m_size); m_position = 0; delete[] tmp; } @@ -118,111 +118,111 @@ void RingBuffer::movePosition( float amount ) } -void RingBuffer::pop( sampleFrame * dst ) +void RingBuffer::pop( SampleFrame* dst ) { if( m_position + m_fpp <= m_size ) // we won't go over the edge so we can just memcpy here { - memcpy( dst, & m_buffer [ m_position ], m_fpp * sizeof( sampleFrame ) ); - memset( & m_buffer[m_position], 0, m_fpp * sizeof( sampleFrame ) ); + memcpy( dst, & m_buffer [ m_position ], m_fpp * sizeof( SampleFrame ) ); + zeroSampleFrames(&m_buffer[m_position], m_fpp); } else { f_cnt_t first = m_size - m_position; f_cnt_t second = m_fpp - first; - memcpy( dst, & m_buffer [ m_position ], first * sizeof( sampleFrame ) ); - memset( & m_buffer [m_position], 0, first * sizeof( sampleFrame ) ); + memcpy( dst, & m_buffer [ m_position ], first * sizeof( SampleFrame ) ); + zeroSampleFrames(&m_buffer[m_position], first); - memcpy( & dst [first], m_buffer, second * sizeof( sampleFrame ) ); - memset( m_buffer, 0, second * sizeof( sampleFrame ) ); + memcpy( & dst [first], m_buffer, second * sizeof( SampleFrame ) ); + zeroSampleFrames(m_buffer, second); } m_position = ( m_position + m_fpp ) % m_size; } -void RingBuffer::read( sampleFrame * dst, f_cnt_t offset ) +void RingBuffer::read( SampleFrame* dst, f_cnt_t offset ) { f_cnt_t pos = ( m_position + offset ) % m_size; if( pos < 0 ) { pos += m_size; } if( pos + m_fpp <= m_size ) // we won't go over the edge so we can just memcpy here { - memcpy( dst, & m_buffer [pos], m_fpp * sizeof( sampleFrame ) ); + memcpy( dst, & m_buffer [pos], m_fpp * sizeof( SampleFrame ) ); } else { f_cnt_t first = m_size - pos; f_cnt_t second = m_fpp - first; - memcpy( dst, & m_buffer [pos], first * sizeof( sampleFrame ) ); + memcpy( dst, & m_buffer [pos], first * sizeof( SampleFrame ) ); - memcpy( & dst [first], m_buffer, second * sizeof( sampleFrame ) ); + memcpy( & dst [first], m_buffer, second * sizeof( SampleFrame ) ); } } -void RingBuffer::read( sampleFrame * dst, float offset ) +void RingBuffer::read( SampleFrame* dst, float offset ) { read( dst, msToFrames( offset ) ); } -void RingBuffer::read( sampleFrame * dst, f_cnt_t offset, f_cnt_t length ) +void RingBuffer::read( SampleFrame* dst, f_cnt_t offset, f_cnt_t length ) { f_cnt_t pos = ( m_position + offset ) % m_size; if( pos < 0 ) { pos += m_size; } if( pos + length <= m_size ) // we won't go over the edge so we can just memcpy here { - memcpy( dst, & m_buffer [pos], length * sizeof( sampleFrame ) ); + memcpy( dst, & m_buffer [pos], length * sizeof( SampleFrame ) ); } else { f_cnt_t first = m_size - pos; f_cnt_t second = length - first; - memcpy( dst, & m_buffer [pos], first * sizeof( sampleFrame ) ); + memcpy( dst, & m_buffer [pos], first * sizeof( SampleFrame ) ); - memcpy( & dst [first], m_buffer, second * sizeof( sampleFrame ) ); + memcpy( & dst [first], m_buffer, second * sizeof( SampleFrame ) ); } } -void RingBuffer::read( sampleFrame * dst, float offset, f_cnt_t length ) +void RingBuffer::read( SampleFrame* dst, float offset, f_cnt_t length ) { read( dst, msToFrames( offset ), length ); } -void RingBuffer::write( sampleFrame * src, f_cnt_t offset, f_cnt_t length ) +void RingBuffer::write( SampleFrame* src, f_cnt_t offset, f_cnt_t length ) { const f_cnt_t pos = ( m_position + offset ) % m_size; if( length == 0 ) { length = m_fpp; } if( pos + length <= m_size ) // we won't go over the edge so we can just memcpy here { - memcpy( & m_buffer [pos], src, length * sizeof( sampleFrame ) ); + memcpy( & m_buffer [pos], src, length * sizeof( SampleFrame ) ); } else { f_cnt_t first = m_size - pos; f_cnt_t second = length - first; - memcpy( & m_buffer [pos], src, first * sizeof( sampleFrame ) ); + memcpy( & m_buffer [pos], src, first * sizeof( SampleFrame ) ); - memcpy( m_buffer, & src [first], second * sizeof( sampleFrame ) ); + memcpy( m_buffer, & src [first], second * sizeof( SampleFrame ) ); } } -void RingBuffer::write( sampleFrame * src, float offset, f_cnt_t length ) +void RingBuffer::write( SampleFrame* src, float offset, f_cnt_t length ) { write( src, msToFrames( offset ), length ); } -void RingBuffer::writeAdding( sampleFrame * src, f_cnt_t offset, f_cnt_t length ) +void RingBuffer::writeAdding( SampleFrame* src, f_cnt_t offset, f_cnt_t length ) { const f_cnt_t pos = ( m_position + offset ) % m_size; if( length == 0 ) { length = m_fpp; } @@ -243,13 +243,13 @@ void RingBuffer::writeAdding( sampleFrame * src, f_cnt_t offset, f_cnt_t length } -void RingBuffer::writeAdding( sampleFrame * src, float offset, f_cnt_t length ) +void RingBuffer::writeAdding( SampleFrame* src, float offset, f_cnt_t length ) { writeAdding( src, msToFrames( offset ), length ); } -void RingBuffer::writeAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt_t length, float level ) +void RingBuffer::writeAddingMultiplied( SampleFrame* src, f_cnt_t offset, f_cnt_t length, float level ) { const f_cnt_t pos = ( m_position + offset ) % m_size; //qDebug( "pos %d m_pos %d ofs %d siz %d", pos, m_position, offset, m_size ); @@ -271,14 +271,14 @@ void RingBuffer::writeAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt } -void RingBuffer::writeAddingMultiplied( sampleFrame * src, float offset, f_cnt_t length, float level ) +void RingBuffer::writeAddingMultiplied( SampleFrame* src, float offset, f_cnt_t length, float level ) { f_cnt_t ofs = msToFrames( offset ); writeAddingMultiplied( src, ofs, length, level ); } -void RingBuffer::writeSwappedAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt_t length, float level ) +void RingBuffer::writeSwappedAddingMultiplied( SampleFrame* src, f_cnt_t offset, f_cnt_t length, float level ) { const f_cnt_t pos = ( m_position + offset ) % m_size; if( length == 0 ) { length = m_fpp; } @@ -299,7 +299,7 @@ void RingBuffer::writeSwappedAddingMultiplied( sampleFrame * src, f_cnt_t offset } -void RingBuffer::writeSwappedAddingMultiplied( sampleFrame * src, float offset, f_cnt_t length, float level ) +void RingBuffer::writeSwappedAddingMultiplied( SampleFrame* src, float offset, f_cnt_t length, float level ) { writeSwappedAddingMultiplied( src, msToFrames( offset ), length, level ); } @@ -311,8 +311,8 @@ void RingBuffer::updateSamplerate() m_size = static_cast( ceilf( newsize ) ) + m_fpp; m_samplerate = Engine::audioEngine()->outputSampleRate(); delete[] m_buffer; - m_buffer = new sampleFrame[ m_size ]; - memset( m_buffer, 0, m_size * sizeof( sampleFrame ) ); + m_buffer = new SampleFrame[ m_size ]; + zeroSampleFrames(m_buffer, m_size); m_position = 0; } diff --git a/src/core/Sample.cpp b/src/core/Sample.cpp index f1fe1ec1a..7bbb4e9b9 100644 --- a/src/core/Sample.cpp +++ b/src/core/Sample.cpp @@ -46,7 +46,7 @@ Sample::Sample(const QByteArray& base64, int sampleRate) { } -Sample::Sample(const sampleFrame* data, size_t numFrames, int sampleRate) +Sample::Sample(const SampleFrame* data, size_t numFrames, int sampleRate) : m_buffer(std::make_shared(data, numFrames, sampleRate)) , m_startFrame(0) , m_endFrame(m_buffer->size()) @@ -116,7 +116,7 @@ auto Sample::operator=(Sample&& other) -> Sample& return *this; } -bool Sample::play(sampleFrame* dst, PlaybackState* state, size_t numFrames, float desiredFrequency, Loop loopMode) const +bool Sample::play(SampleFrame* dst, PlaybackState* state, size_t numFrames, float desiredFrequency, Loop loopMode) const { assert(numFrames > 0); assert(desiredFrequency > 0); @@ -131,7 +131,7 @@ bool Sample::play(sampleFrame* dst, PlaybackState* state, size_t numFrames, floa state->m_frameIndex = std::max(m_startFrame, state->m_frameIndex); - auto playBuffer = std::vector(numFrames / resampleRatio + marginSize); + auto playBuffer = std::vector(numFrames / resampleRatio + marginSize); playRaw(playBuffer.data(), playBuffer.size(), state, loopMode); state->resampler().setRatio(resampleRatio); @@ -141,7 +141,7 @@ bool Sample::play(sampleFrame* dst, PlaybackState* state, size_t numFrames, floa advance(state, resampleResult.inputFramesUsed, loopMode); const auto outputFrames = resampleResult.outputFramesGenerated; - if (outputFrames < numFrames) { std::fill_n(dst + outputFrames, numFrames - outputFrames, sampleFrame{}); } + if (outputFrames < numFrames) { std::fill_n(dst + outputFrames, numFrames - outputFrames, SampleFrame{}); } if (!typeInfo::isEqual(m_amplification, 1.0f)) { @@ -170,7 +170,7 @@ void Sample::setAllPointFrames(int startFrame, int endFrame, int loopStartFrame, setLoopEndFrame(loopEndFrame); } -void Sample::playRaw(sampleFrame* dst, size_t numFrames, const PlaybackState* state, Loop loopMode) const +void Sample::playRaw(SampleFrame* dst, size_t numFrames, const PlaybackState* state, Loop loopMode) const { if (m_buffer->size() < 1) { return; } diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 6483dd522..fda3f2f66 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -31,7 +31,7 @@ namespace lmms { -SampleBuffer::SampleBuffer(const sampleFrame* data, size_t numFrames, int sampleRate) +SampleBuffer::SampleBuffer(const SampleFrame* data, size_t numFrames, int sampleRate) : m_data(data, data + numFrames) , m_sampleRate(sampleRate) { @@ -60,11 +60,11 @@ SampleBuffer::SampleBuffer(const QString& base64, int sampleRate) { // TODO: Replace with non-Qt equivalent const auto bytes = QByteArray::fromBase64(base64.toUtf8()); - m_data.resize(bytes.size() / sizeof(sampleFrame)); - std::memcpy(reinterpret_cast(m_data.data()), bytes, m_data.size() * sizeof(sampleFrame)); + m_data.resize(bytes.size() / sizeof(SampleFrame)); + std::memcpy(reinterpret_cast(m_data.data()), bytes, m_data.size() * sizeof(SampleFrame)); } -SampleBuffer::SampleBuffer(std::vector data, int sampleRate) +SampleBuffer::SampleBuffer(std::vector data, int sampleRate) : m_data(std::move(data)) , m_sampleRate(sampleRate) { @@ -82,7 +82,7 @@ QString SampleBuffer::toBase64() const { // TODO: Replace with non-Qt equivalent const auto data = reinterpret_cast(m_data.data()); - const auto size = static_cast(m_data.size() * sizeof(sampleFrame)); + const auto size = static_cast(m_data.size() * sizeof(SampleFrame)); const auto byteArray = QByteArray{data, size}; return byteArray.toBase64(); } diff --git a/src/core/SampleDecoder.cpp b/src/core/SampleDecoder.cpp index ec0fcc39a..1e1ddb545 100644 --- a/src/core/SampleDecoder.cpp +++ b/src/core/SampleDecoder.cpp @@ -75,7 +75,7 @@ auto decodeSampleSF(const QString& audioFile) -> std::optional(sfInfo.frames); + auto result = std::vector(sfInfo.frames); for (int i = 0; i < static_cast(result.size()); ++i) { if (sfInfo.channels == 1) @@ -107,7 +107,7 @@ auto decodeSampleDS(const QString& audioFile) -> std::optional(frames); + auto result = std::vector(frames); src_short_to_float_array(data.get(), &result[0][0], frames * DEFAULT_CHANNELS); return SampleDecoder::Result{std::move(result), static_cast(engineRate)}; @@ -173,7 +173,7 @@ auto decodeSampleOggVorbis(const QString& audioFile) -> std::optional(totalSamplesRead / numChannels); + auto result = std::vector(totalSamplesRead / numChannels); for (int i = 0; i < result.size(); ++i) { if (numChannels == 1) { result[i] = {buffer[i], buffer[i]}; } diff --git a/src/core/SamplePlayHandle.cpp b/src/core/SamplePlayHandle.cpp index e23cfa473..f2ddc2a4a 100644 --- a/src/core/SamplePlayHandle.cpp +++ b/src/core/SamplePlayHandle.cpp @@ -85,23 +85,23 @@ SamplePlayHandle::~SamplePlayHandle() -void SamplePlayHandle::play( sampleFrame * buffer ) +void SamplePlayHandle::play( SampleFrame* buffer ) { const fpp_t fpp = Engine::audioEngine()->framesPerPeriod(); //play( 0, _try_parallelizing ); if( framesDone() >= totalFrames() ) { - memset( buffer, 0, sizeof( sampleFrame ) * fpp ); + zeroSampleFrames(buffer, fpp); return; } - sampleFrame * workingBuffer = buffer; + SampleFrame* workingBuffer = buffer; f_cnt_t frames = fpp; // apply offset for the first period if( framesDone() == 0 ) { - memset( buffer, 0, sizeof( sampleFrame ) * offset() ); + zeroSampleFrames(buffer, offset()); workingBuffer += offset(); frames -= offset(); } @@ -116,7 +116,7 @@ void SamplePlayHandle::play( sampleFrame * buffer ) // it is used only for previews, SampleTracks and the metronome. if (!m_sample->play(workingBuffer, &m_state, frames, DefaultBaseFreq)) { - memset(workingBuffer, 0, frames * sizeof(sampleFrame)); + zeroSampleFrames(workingBuffer, frames); } } diff --git a/src/core/SampleRecordHandle.cpp b/src/core/SampleRecordHandle.cpp index 6857efa83..f7003f3be 100644 --- a/src/core/SampleRecordHandle.cpp +++ b/src/core/SampleRecordHandle.cpp @@ -64,9 +64,9 @@ SampleRecordHandle::~SampleRecordHandle() -void SampleRecordHandle::play( sampleFrame * /*_working_buffer*/ ) +void SampleRecordHandle::play( SampleFrame* /*_working_buffer*/ ) { - const sampleFrame * recbuf = Engine::audioEngine()->inputBuffer(); + const SampleFrame* recbuf = Engine::audioEngine()->inputBuffer(); const f_cnt_t frames = Engine::audioEngine()->inputBufferFrames(); writeBuffer( recbuf, frames ); m_framesRecorded += frames; @@ -110,7 +110,7 @@ std::shared_ptr SampleRecordHandle::createSampleBuffer() { const f_cnt_t frames = framesRecorded(); // create buffer to store all recorded buffers in - auto bigBuffer = std::vector(frames); + auto bigBuffer = std::vector(frames); // now copy all buffers into big buffer auto framesCopied = 0; @@ -127,9 +127,9 @@ std::shared_ptr SampleRecordHandle::createSampleBuffer() -void SampleRecordHandle::writeBuffer( const sampleFrame * _ab, const f_cnt_t _frames ) +void SampleRecordHandle::writeBuffer( const SampleFrame* _ab, const f_cnt_t _frames ) { - auto buf = new sampleFrame[_frames]; + auto buf = new SampleFrame[_frames]; for( f_cnt_t frame = 0; frame < _frames; ++frame ) { for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index eda0f7a31..c41703e22 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -39,7 +39,7 @@ AudioAlsa::AudioAlsa( bool & _success_ful, AudioEngine* _audioEngine ) : AudioDevice(std::clamp( ConfigManager::inst()->value("audioalsa", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine), + DEFAULT_CHANNELS), _audioEngine), m_handle( nullptr ), m_hwParams( nullptr ), m_swParams( nullptr ), @@ -242,7 +242,7 @@ void AudioAlsa::stopProcessing() void AudioAlsa::run() { - auto temp = new surroundSampleFrame[audioEngine()->framesPerPeriod()]; + auto temp = new SampleFrame[audioEngine()->framesPerPeriod()]; auto outbuf = new int_sample_t[audioEngine()->framesPerPeriod() * channels()]; auto pcmbuf = new int_sample_t[m_periodSize * channels()]; diff --git a/src/core/audio/AudioDevice.cpp b/src/core/audio/AudioDevice.cpp index 988230d5b..2047fffe9 100644 --- a/src/core/audio/AudioDevice.cpp +++ b/src/core/audio/AudioDevice.cpp @@ -37,7 +37,7 @@ AudioDevice::AudioDevice( const ch_cnt_t _channels, AudioEngine* _audioEngine ) m_sampleRate( _audioEngine->outputSampleRate() ), m_channels( _channels ), m_audioEngine( _audioEngine ), - m_buffer( new surroundSampleFrame[audioEngine()->framesPerPeriod()] ) + m_buffer(new SampleFrame[audioEngine()->framesPerPeriod()]) { } @@ -64,14 +64,14 @@ void AudioDevice::processNextBuffer() } } -fpp_t AudioDevice::getNextBuffer(surroundSampleFrame* _ab) +fpp_t AudioDevice::getNextBuffer(SampleFrame* _ab) { fpp_t frames = audioEngine()->framesPerPeriod(); + const SampleFrame* b = audioEngine()->nextBuffer(); - const surroundSampleFrame* b = audioEngine()->nextBuffer(); if (!b) { return 0; } - memcpy(_ab, b, frames * sizeof(surroundSampleFrame)); + memcpy(_ab, b, frames * sizeof(SampleFrame)); if (audioEngine()->hasFifoWriter()) { delete[] b; } return frames; @@ -127,7 +127,7 @@ void AudioDevice::renamePort( AudioPort * ) { } -int AudioDevice::convertToS16( const surroundSampleFrame * _ab, +int AudioDevice::convertToS16(const SampleFrame* _ab, const fpp_t _frames, int_sample_t * _output_buffer, const bool _convert_endian ) diff --git a/src/core/audio/AudioFileFlac.cpp b/src/core/audio/AudioFileFlac.cpp index 097fbdd89..dfb97a6be 100644 --- a/src/core/audio/AudioFileFlac.cpp +++ b/src/core/audio/AudioFileFlac.cpp @@ -89,7 +89,7 @@ bool AudioFileFlac::startEncoding() return true; } -void AudioFileFlac::writeBuffer(surroundSampleFrame const* _ab, fpp_t const frames) +void AudioFileFlac::writeBuffer(const SampleFrame* _ab, fpp_t const frames) { OutputSettings::BitDepth depth = getOutputSettings().getBitDepth(); float clipvalue = std::nextafterf( -1.0f, 0.0f ); diff --git a/src/core/audio/AudioFileMP3.cpp b/src/core/audio/AudioFileMP3.cpp index 2141fabfc..4d1dbc020 100644 --- a/src/core/audio/AudioFileMP3.cpp +++ b/src/core/audio/AudioFileMP3.cpp @@ -25,6 +25,8 @@ #include "AudioFileMP3.h" +#include "SampleFrame.h" + #ifdef LMMS_HAVE_MP3LAME @@ -53,7 +55,7 @@ AudioFileMP3::~AudioFileMP3() tearDownEncoder(); } -void AudioFileMP3::writeBuffer(const surroundSampleFrame* _buf, const fpp_t _frames) +void AudioFileMP3::writeBuffer(const SampleFrame* _buf, const fpp_t _frames) { if (_frames < 1) { diff --git a/src/core/audio/AudioFileOgg.cpp b/src/core/audio/AudioFileOgg.cpp index 3818273d6..59b796730 100644 --- a/src/core/audio/AudioFileOgg.cpp +++ b/src/core/audio/AudioFileOgg.cpp @@ -179,7 +179,7 @@ bool AudioFileOgg::startEncoding() return true; } -void AudioFileOgg::writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) +void AudioFileOgg::writeBuffer(const SampleFrame* _ab, const fpp_t _frames) { int eos = 0; diff --git a/src/core/audio/AudioFileWave.cpp b/src/core/audio/AudioFileWave.cpp index 612b98982..4b4b928c5 100644 --- a/src/core/audio/AudioFileWave.cpp +++ b/src/core/audio/AudioFileWave.cpp @@ -93,7 +93,7 @@ bool AudioFileWave::startEncoding() return true; } -void AudioFileWave::writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) +void AudioFileWave::writeBuffer(const SampleFrame* _ab, const fpp_t _frames) { OutputSettings::BitDepth bitDepth = getOutputSettings().getBitDepth(); diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index 4d27602ef..bd5b8e514 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -48,7 +48,7 @@ AudioJack::AudioJack(bool& successful, AudioEngine* audioEngineParam) std::clamp( ConfigManager::inst()->value("audiojack", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS + DEFAULT_CHANNELS ), // clang-format on audioEngineParam) @@ -56,7 +56,7 @@ AudioJack::AudioJack(bool& successful, AudioEngine* audioEngineParam) , m_active(false) , m_midiClient(nullptr) , m_tempOutBufs(new jack_default_audio_sample_t*[channels()]) - , m_outBuf(new surroundSampleFrame[audioEngine()->framesPerPeriod()]) + , m_outBuf(new SampleFrame[audioEngine()->framesPerPeriod()]) , m_framesDoneInCurBuf(0) , m_framesToDoInCurBuf(0) { @@ -392,7 +392,7 @@ AudioJack::setupWidget::setupWidget(QWidget* parent) form->addRow(tr("Client name"), m_clientName); auto m = new gui::LcdSpinBoxModel(/* this */); - m->setRange(DEFAULT_CHANNELS, SURROUND_CHANNELS); + m->setRange(DEFAULT_CHANNELS, DEFAULT_CHANNELS); m->setStep(2); m->setValue(ConfigManager::inst()->value("audiojack", "channels").toInt()); diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index e18260d61..1321a8a24 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -72,7 +72,7 @@ AudioOss::AudioOss( bool & _success_ful, AudioEngine* _audioEngine ) : AudioDevice(std::clamp( ConfigManager::inst()->value("audiooss", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine), + DEFAULT_CHANNELS), _audioEngine), m_convertEndian( false ) { _success_ful = false; @@ -256,7 +256,7 @@ void AudioOss::stopProcessing() void AudioOss::run() { - auto temp = new surroundSampleFrame[audioEngine()->framesPerPeriod()]; + auto temp = new SampleFrame[audioEngine()->framesPerPeriod()]; auto outbuf = new int_sample_t[audioEngine()->framesPerPeriod() * channels()]; while( true ) @@ -291,7 +291,7 @@ AudioOss::setupWidget::setupWidget( QWidget * _parent ) : form->addRow(tr("Device"), m_device); auto m = new gui::LcdSpinBoxModel(/* this */); - m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setRange(DEFAULT_CHANNELS, DEFAULT_CHANNELS); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audiooss", "channels" ).toInt() ); diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index bc5d7dd9d..00bbec2e4 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -64,10 +64,10 @@ AudioPortAudio::AudioPortAudio( bool & _success_ful, AudioEngine * _audioEngine AudioDevice(std::clamp( ConfigManager::inst()->value("audioportaudio", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine), + DEFAULT_CHANNELS), _audioEngine), m_paStream( nullptr ), m_wasPAInitError( false ), - m_outBuf( new surroundSampleFrame[audioEngine()->framesPerPeriod()] ), + m_outBuf(new SampleFrame[audioEngine()->framesPerPeriod()]), m_outBufPos( 0 ) { _success_ful = false; @@ -236,7 +236,7 @@ int AudioPortAudio::process_callback( { if( supportsCapture() ) { - audioEngine()->pushInputFrames( (sampleFrame*)_inputBuffer, _framesPerBuffer ); + audioEngine()->pushInputFrames( (SampleFrame*)_inputBuffer, _framesPerBuffer ); } if( m_stopped ) @@ -387,7 +387,7 @@ AudioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : form->addRow(tr("Device"), m_device); /* LcdSpinBoxModel * m = new LcdSpinBoxModel( ); - m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setRange( DEFAULT_CHANNELS, DEFAULT_CHANNELS ); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audioportaudio", "channels" ).toInt() ); diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index b32e6eaf2..aa4344871 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -49,7 +49,7 @@ AudioPulseAudio::AudioPulseAudio( bool & _success_ful, AudioEngine* _audioEngin AudioDevice(std::clamp( ConfigManager::inst()->value("audiopa", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine), + DEFAULT_CHANNELS), _audioEngine), m_s( nullptr ), m_quit( false ), m_convertEndian( false ) @@ -230,7 +230,7 @@ void AudioPulseAudio::run() else { const fpp_t fpp = audioEngine()->framesPerPeriod(); - auto temp = new surroundSampleFrame[fpp]; + auto temp = new SampleFrame[fpp]; while( getNextBuffer( temp ) ) { } @@ -249,7 +249,7 @@ void AudioPulseAudio::run() void AudioPulseAudio::streamWriteCallback( pa_stream *s, size_t length ) { const fpp_t fpp = audioEngine()->framesPerPeriod(); - auto temp = new surroundSampleFrame[fpp]; + auto temp = new SampleFrame[fpp]; auto pcmbuf = (int_sample_t*)pa_xmalloc(fpp * channels() * sizeof(int_sample_t)); size_t fd = 0; @@ -298,7 +298,7 @@ AudioPulseAudio::setupWidget::setupWidget( QWidget * _parent ) : form->addRow(tr("Device"), m_device); auto m = new gui::LcdSpinBoxModel(); - m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setRange(DEFAULT_CHANNELS, DEFAULT_CHANNELS); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audiopa", "channels" ).toInt() ); diff --git a/src/core/audio/AudioSampleRecorder.cpp b/src/core/audio/AudioSampleRecorder.cpp index c9448b89e..0e51c9d2d 100644 --- a/src/core/audio/AudioSampleRecorder.cpp +++ b/src/core/audio/AudioSampleRecorder.cpp @@ -71,7 +71,7 @@ std::shared_ptr AudioSampleRecorder::createSampleBuffer() { const f_cnt_t frames = framesRecorded(); // create buffer to store all recorded buffers in - auto bigBuffer = std::vector(frames); + auto bigBuffer = std::vector(frames); // now copy all buffers into big buffer auto framesCopied = 0; @@ -85,9 +85,9 @@ std::shared_ptr AudioSampleRecorder::createSampleBuffer() return std::make_shared(std::move(bigBuffer), sampleRate()); } -void AudioSampleRecorder::writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) +void AudioSampleRecorder::writeBuffer(const SampleFrame* _ab, const fpp_t _frames) { - auto buf = new sampleFrame[_frames]; + auto buf = new SampleFrame[_frames]; for( fpp_t frame = 0; frame < _frames; ++frame ) { for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 0d960c107..2a5414049 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -38,7 +38,7 @@ namespace lmms AudioSdl::AudioSdl( bool & _success_ful, AudioEngine* _audioEngine ) : AudioDevice( DEFAULT_CHANNELS, _audioEngine ), - m_outBuf( new surroundSampleFrame[audioEngine()->framesPerPeriod()] ) + m_outBuf(new SampleFrame[audioEngine()->framesPerPeriod()]) { _success_ful = false; @@ -225,13 +225,13 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len ) m_currentBufferFramesCount = frames; } - const uint min_frames_count = std::min(_len/sizeof(sampleFrame), + const uint min_frames_count = std::min(_len/sizeof(SampleFrame), m_currentBufferFramesCount - m_currentBufferFramePos); - memcpy( _buf, m_outBuf + m_currentBufferFramePos, min_frames_count*sizeof(sampleFrame) ); - _buf += min_frames_count*sizeof(sampleFrame); - _len -= min_frames_count*sizeof(sampleFrame); + memcpy( _buf, m_outBuf + m_currentBufferFramePos, min_frames_count*sizeof(SampleFrame) ); + _buf += min_frames_count*sizeof(SampleFrame); + _len -= min_frames_count*sizeof(SampleFrame); m_currentBufferFramePos += min_frames_count; m_currentBufferFramePos %= m_currentBufferFramesCount; @@ -274,8 +274,8 @@ void AudioSdl::sdlInputAudioCallback(void *_udata, Uint8 *_buf, int _len) { } void AudioSdl::sdlInputAudioCallback(Uint8 *_buf, int _len) { - auto samples_buffer = (sampleFrame*)_buf; - fpp_t frames = _len / sizeof ( sampleFrame ); + auto samples_buffer = (SampleFrame*)_buf; + fpp_t frames = _len / sizeof ( SampleFrame ); audioEngine()->pushInputFrames (samples_buffer, frames); } diff --git a/src/core/audio/AudioSndio.cpp b/src/core/audio/AudioSndio.cpp index 535b885da..95fab473a 100644 --- a/src/core/audio/AudioSndio.cpp +++ b/src/core/audio/AudioSndio.cpp @@ -46,7 +46,7 @@ AudioSndio::AudioSndio(bool & _success_ful, AudioEngine * _audioEngine) : AudioDevice(std::clamp( ConfigManager::inst()->value("audiosndio", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine), + DEFAULT_CHANNELS), _audioEngine), m_convertEndian ( false ) { _success_ful = false; @@ -141,7 +141,7 @@ void AudioSndio::stopProcessing() void AudioSndio::run() { - surroundSampleFrame * temp = new surroundSampleFrame[audioEngine()->framesPerPeriod()]; + SampleFrame* temp = new SampleFrame[audioEngine()->framesPerPeriod()]; int_sample_t * outbuf = new int_sample_t[audioEngine()->framesPerPeriod() * channels()]; while( true ) @@ -173,7 +173,7 @@ AudioSndio::setupWidget::setupWidget( QWidget * _parent ) : form->addRow(tr("Device"), m_device); gui::LcdSpinBoxModel * m = new gui::LcdSpinBoxModel( /* this */ ); - m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setRange(DEFAULT_CHANNELS, DEFAULT_CHANNELS); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audiosndio", "channels" ).toInt() ); diff --git a/src/core/audio/AudioSoundIo.cpp b/src/core/audio/AudioSoundIo.cpp index c16327a90..c7fa380e4 100644 --- a/src/core/audio/AudioSoundIo.cpp +++ b/src/core/audio/AudioSoundIo.cpp @@ -42,7 +42,7 @@ AudioSoundIo::AudioSoundIo( bool & outSuccessful, AudioEngine * _audioEngine ) : AudioDevice(std::clamp( ConfigManager::inst()->value("audiosoundio", "channels").toInt(), DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine) + DEFAULT_CHANNELS), _audioEngine) { outSuccessful = false; m_soundio = nullptr; @@ -213,7 +213,7 @@ void AudioSoundIo::startProcessing() m_outBufFramesTotal = 0; m_outBufSize = audioEngine()->framesPerPeriod(); - m_outBuf = new surroundSampleFrame[m_outBufSize]; + m_outBuf = new SampleFrame[m_outBufSize]; if (! m_outstreamStarted) { diff --git a/src/core/lv2/Lv2ControlBase.cpp b/src/core/lv2/Lv2ControlBase.cpp index 5741866e9..0147ebd6e 100644 --- a/src/core/lv2/Lv2ControlBase.cpp +++ b/src/core/lv2/Lv2ControlBase.cpp @@ -137,7 +137,7 @@ void Lv2ControlBase::copyModelsToLmms() const -void Lv2ControlBase::copyBuffersFromLmms(const sampleFrame *buf, fpp_t frames) { +void Lv2ControlBase::copyBuffersFromLmms(const SampleFrame* buf, fpp_t frames) { unsigned firstChan = 0; // tell the procs which channels they shall read from for (const auto& c : m_procs) { @@ -149,7 +149,7 @@ void Lv2ControlBase::copyBuffersFromLmms(const sampleFrame *buf, fpp_t frames) { -void Lv2ControlBase::copyBuffersToLmms(sampleFrame *buf, fpp_t frames) const { +void Lv2ControlBase::copyBuffersToLmms(SampleFrame* buf, fpp_t frames) const { unsigned firstChan = 0; // tell the procs which channels they shall write to for (const auto& c : m_procs) { c->copyBuffersToCore(buf, firstChan, m_channelsPerProc, frames); diff --git a/src/core/lv2/Lv2Ports.cpp b/src/core/lv2/Lv2Ports.cpp index 657046817..bdb0d4f00 100644 --- a/src/core/lv2/Lv2Ports.cpp +++ b/src/core/lv2/Lv2Ports.cpp @@ -34,6 +34,7 @@ #include "Lv2Basics.h" #include "Lv2Manager.h" #include "Lv2Evbuf.h" +#include "SampleFrame.h" namespace lmms::Lv2Ports @@ -311,7 +312,7 @@ Audio::Audio(std::size_t bufferSize, bool isSidechain) -void Audio::copyBuffersFromCore(const sampleFrame *lmmsBuf, +void Audio::copyBuffersFromCore(const SampleFrame* lmmsBuf, unsigned channel, fpp_t frames) { for (std::size_t f = 0; f < static_cast(frames); ++f) @@ -323,7 +324,7 @@ void Audio::copyBuffersFromCore(const sampleFrame *lmmsBuf, -void Audio::averageWithBuffersFromCore(const sampleFrame *lmmsBuf, +void Audio::averageWithBuffersFromCore(const SampleFrame* lmmsBuf, unsigned channel, fpp_t frames) { for (std::size_t f = 0; f < static_cast(frames); ++f) @@ -335,7 +336,7 @@ void Audio::averageWithBuffersFromCore(const sampleFrame *lmmsBuf, -void Audio::copyBuffersToCore(sampleFrame *lmmsBuf, +void Audio::copyBuffersToCore(SampleFrame* lmmsBuf, unsigned channel, fpp_t frames) const { for (std::size_t f = 0; f < static_cast(frames); ++f) diff --git a/src/core/lv2/Lv2Proc.cpp b/src/core/lv2/Lv2Proc.cpp index 7dfdbc767..27d18ef27 100644 --- a/src/core/lv2/Lv2Proc.cpp +++ b/src/core/lv2/Lv2Proc.cpp @@ -324,7 +324,7 @@ void Lv2Proc::copyModelsToCore() -void Lv2Proc::copyBuffersFromCore(const sampleFrame *buf, +void Lv2Proc::copyBuffersFromCore(const SampleFrame* buf, unsigned firstChan, unsigned num, fpp_t frames) { @@ -349,7 +349,7 @@ void Lv2Proc::copyBuffersFromCore(const sampleFrame *buf, -void Lv2Proc::copyBuffersToCore(sampleFrame* buf, +void Lv2Proc::copyBuffersToCore(SampleFrame* buf, unsigned firstChan, unsigned num, fpp_t frames) const { diff --git a/src/gui/AudioAlsaSetupWidget.cpp b/src/gui/AudioAlsaSetupWidget.cpp index bc0ecde8e..43872a12f 100644 --- a/src/gui/AudioAlsaSetupWidget.cpp +++ b/src/gui/AudioAlsaSetupWidget.cpp @@ -70,7 +70,7 @@ AudioAlsaSetupWidget::AudioAlsaSetupWidget( QWidget * _parent ) : form->addRow(tr("Device"), m_deviceComboBox); auto m = new LcdSpinBoxModel(/* this */); - m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setRange(DEFAULT_CHANNELS, DEFAULT_CHANNELS); m->setStep( 2 ); m->setValue( ConfigManager::inst()->value( "audioalsa", "channels" ).toInt() ); diff --git a/src/gui/SampleWaveform.cpp b/src/gui/SampleWaveform.cpp index 783543ac5..91b6e26c3 100644 --- a/src/gui/SampleWaveform.cpp +++ b/src/gui/SampleWaveform.cpp @@ -59,7 +59,7 @@ void SampleWaveform::visualize(Parameters parameters, QPainter& painter, const Q const int frameIndex = !parameters.reversed ? i : maxFrames - i; const auto& frame = parameters.buffer[frameIndex]; - const float value = std::accumulate(frame.begin(), frame.end(), 0.0f) / frame.size(); + const auto value = frame.average(); if (value > max[pixelIndex]) { max[pixelIndex] = value; } if (value < min[pixelIndex]) { min[pixelIndex] = value; } diff --git a/src/gui/widgets/Oscilloscope.cpp b/src/gui/widgets/Oscilloscope.cpp index 8c342cc34..8cb840592 100644 --- a/src/gui/widgets/Oscilloscope.cpp +++ b/src/gui/widgets/Oscilloscope.cpp @@ -55,7 +55,7 @@ Oscilloscope::Oscilloscope( QWidget * _p ) : setActive( ConfigManager::inst()->value( "ui", "displaywaveform").toInt() ); const fpp_t frames = Engine::audioEngine()->framesPerPeriod(); - m_buffer = new sampleFrame[frames]; + m_buffer = new SampleFrame[frames]; BufferManager::clear( m_buffer, frames ); @@ -75,12 +75,12 @@ Oscilloscope::~Oscilloscope() -void Oscilloscope::updateAudioBuffer( const surroundSampleFrame * buffer ) +void Oscilloscope::updateAudioBuffer(const SampleFrame* buffer) { if( !Engine::getSong()->isExporting() ) { const fpp_t fpp = Engine::audioEngine()->framesPerPeriod(); - memcpy( m_buffer, buffer, sizeof( surroundSampleFrame ) * fpp ); + memcpy(m_buffer, buffer, sizeof(SampleFrame) * fpp); } } @@ -96,8 +96,8 @@ void Oscilloscope::setActive( bool _active ) SIGNAL(periodicUpdate()), this, SLOT(update())); connect( Engine::audioEngine(), - SIGNAL(nextAudioBuffer(const lmms::surroundSampleFrame*)), - this, SLOT(updateAudioBuffer(const lmms::surroundSampleFrame*)) ); + SIGNAL(nextAudioBuffer(const lmms::SampleFrame*)), + this, SLOT(updateAudioBuffer(const lmms::SampleFrame*))); } else { @@ -105,8 +105,8 @@ void Oscilloscope::setActive( bool _active ) SIGNAL(periodicUpdate()), this, SLOT(update())); disconnect( Engine::audioEngine(), - SIGNAL( nextAudioBuffer( const lmms::surroundSampleFrame* ) ), - this, SLOT( updateAudioBuffer( const lmms::surroundSampleFrame* ) ) ); + SIGNAL(nextAudioBuffer(const lmms::SampleFrame*)), + this, SLOT(updateAudioBuffer(const lmms::SampleFrame*))); // we have to update (remove last waves), // because timer doesn't do that anymore update(); @@ -168,10 +168,10 @@ void Oscilloscope::paintEvent( QPaintEvent * ) float masterOutput = audioEngine->masterGain(); const fpp_t frames = audioEngine->framesPerPeriod(); - AudioEngine::StereoSample peakValues = audioEngine->getPeakValues(m_buffer, frames); + SampleFrame peakValues = getAbsPeakValues(m_buffer, frames); - auto const leftChannelClips = clips(peakValues.left * masterOutput); - auto const rightChannelClips = clips(peakValues.right * masterOutput); + auto const leftChannelClips = clips(peakValues.left() * masterOutput); + auto const rightChannelClips = clips(peakValues.right() * masterOutput); p.setRenderHint( QPainter::Antialiasing ); diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 3317ea71b..14cf19153 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -220,7 +220,7 @@ InstrumentTrack::~InstrumentTrack() -void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, NotePlayHandle* n ) +void InstrumentTrack::processAudioBuffer( SampleFrame* buf, const fpp_t frames, NotePlayHandle* n ) { // we must not play the sound if this InstrumentTrack is muted... if( isMuted() || ( Engine::getSong()->playMode() != Song::PlayMode::MidiClip && @@ -567,7 +567,7 @@ f_cnt_t InstrumentTrack::beatLen( NotePlayHandle * _n ) const -void InstrumentTrack::playNote( NotePlayHandle* n, sampleFrame* workingBuffer ) +void InstrumentTrack::playNote( NotePlayHandle* n, SampleFrame* workingBuffer ) { // Note: under certain circumstances the working buffer is a nullptr. // These cases are triggered in PlayHandle::doProcessing when the play method is called with a nullptr. From 13a05b99d3f6216b5bf7e1f9637211e648929c04 Mon Sep 17 00:00:00 2001 From: saker Date: Sun, 30 Jun 2024 14:54:20 -0400 Subject: [PATCH 24/31] Use recursive mutex for `requestChangeInModel`/`doneChangeInModel` (#7359) * Make model change mutex recursive * Initialize s_renderingThread --- include/AudioEngine.h | 2 +- src/core/AudioEngine.cpp | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/include/AudioEngine.h b/include/AudioEngine.h index 5e94ea6a2..923bc0092 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -410,7 +410,7 @@ private: bool m_clearSignal; - std::mutex m_changeMutex; + std::recursive_mutex m_changeMutex; friend class Engine; friend class AudioEngineWorkerThread; diff --git a/src/core/AudioEngine.cpp b/src/core/AudioEngine.cpp index 8bb8648ac..8e4cc8e29 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -66,8 +66,7 @@ namespace lmms using LocklessListElement = LocklessList::Element; -static thread_local bool s_renderingThread; -static thread_local bool s_runningChange; +static thread_local bool s_renderingThread = false; @@ -758,16 +757,14 @@ void AudioEngine::removePlayHandlesOfTypes(Track * track, PlayHandle::Types type void AudioEngine::requestChangeInModel() { - if (s_renderingThread || s_runningChange) { return; } + if (s_renderingThread) { return; } m_changeMutex.lock(); - s_runningChange = true; } void AudioEngine::doneChangeInModel() { - if (s_renderingThread || !s_runningChange) { return; } + if (s_renderingThread) { return; } m_changeMutex.unlock(); - s_runningChange = false; } bool AudioEngine::isAudioDevNameValid(QString name) From edf6bf8dfe2a1354dc04b05f679754613e8f1a40 Mon Sep 17 00:00:00 2001 From: FyiurAmron Date: Sun, 30 Jun 2024 21:49:06 +0200 Subject: [PATCH 25/31] Remove mingw-std-threads from 3rd party deps and use native libs/headers instead (#7283) * Remove mingw-std-threads from 3rd party deps and use native libs/headers instead * switch MinGW to POSIX in CI --- .github/workflows/build.yml | 6 ++++++ .gitmodules | 3 --- include/AudioEngine.h | 4 ---- include/ThreadPool.h | 7 ------- plugins/VstBase/RemoteVstPlugin.cpp | 6 +----- plugins/VstBase/RemoteVstPlugin/CMakeLists.txt | 15 --------------- plugins/ZynAddSubFx/CMakeLists.txt | 6 ------ plugins/ZynAddSubFx/ThreadShims.h | 6 ------ src/3rdparty/CMakeLists.txt | 6 ------ src/3rdparty/mingw-std-threads | 1 - src/CMakeLists.txt | 4 ---- src/core/FileSearch.cpp | 4 ---- 12 files changed, 7 insertions(+), 61 deletions(-) delete mode 160000 src/3rdparty/mingw-std-threads diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index db397d848..9a63375c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -183,6 +183,12 @@ jobs: CCACHE_NOCOMPRESS: 1 MAKEFLAGS: -j2 steps: + - name: Enable POSIX MinGW + run: | + update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix + update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix + update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix + update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix - name: Configure git run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Check out diff --git a/.gitmodules b/.gitmodules index 1c43fd1b3..58c4d8526 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,9 +25,6 @@ [submodule "src/3rdparty/weakjack/weakjack"] path = src/3rdparty/weakjack/weakjack url = https://github.com/x42/weakjack.git -[submodule "src/3rdparty/mingw-std-threads"] - path = src/3rdparty/mingw-std-threads - url = https://github.com/meganz/mingw-std-threads.git [submodule "doc/wiki"] path = doc/wiki url = https://github.com/lmms/lmms.wiki.git diff --git a/include/AudioEngine.h b/include/AudioEngine.h index 923bc0092..f80c860d8 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -25,11 +25,7 @@ #ifndef LMMS_AUDIO_ENGINE_H #define LMMS_AUDIO_ENGINE_H -#ifdef __MINGW32__ -#include -#else #include -#endif #include #include diff --git a/include/ThreadPool.h b/include/ThreadPool.h index b1d7900a6..ad4d79850 100644 --- a/include/ThreadPool.h +++ b/include/ThreadPool.h @@ -31,17 +31,10 @@ #include #include -#ifdef __MINGW32__ -#include -#include -#include -#include -#else #include #include #include #include -#endif namespace lmms { //! A thread pool that can be used for asynchronous processing. diff --git a/plugins/VstBase/RemoteVstPlugin.cpp b/plugins/VstBase/RemoteVstPlugin.cpp index ba40bcb68..ef31cfdb8 100644 --- a/plugins/VstBase/RemoteVstPlugin.cpp +++ b/plugins/VstBase/RemoteVstPlugin.cpp @@ -87,11 +87,7 @@ #undef Unsorted #endif -#ifdef USE_MINGW_THREADS_REPLACEMENT -# include -#else -# include -#endif +#include #include #include diff --git a/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt b/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt index a3cd517ff..dd15bb0bd 100644 --- a/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/VstBase/RemoteVstPlugin/CMakeLists.txt @@ -66,21 +66,6 @@ endif() if(IS_MINGW) SET(CMAKE_REQUIRED_FLAGS "-std=c++17") - - CHECK_CXX_SOURCE_COMPILES(" - #include - int main(int argc, const char* argv[]) { - std::mutex m; - return 0; - } - " HAS_STD_MUTEX) - - if(NOT HAS_STD_MUTEX) - target_include_directories(${EXE_NAME} SYSTEM PRIVATE - "${LMMS_SOURCE_DIR}/src/3rdparty/mingw-std-threads") - target_compile_definitions(${EXE_NAME} PRIVATE - -DUSE_MINGW_THREADS_REPLACEMENT) - endif() endif() if(LMMS_BUILD_WIN32) diff --git a/plugins/ZynAddSubFx/CMakeLists.txt b/plugins/ZynAddSubFx/CMakeLists.txt index a0eb6f36a..b3490a50f 100644 --- a/plugins/ZynAddSubFx/CMakeLists.txt +++ b/plugins/ZynAddSubFx/CMakeLists.txt @@ -111,12 +111,6 @@ set_target_properties(zynaddsubfx_nio PROPERTIES SYSTEM TRUE) set_target_properties(zynaddsubfx_gui PROPERTIES SYSTEM TRUE) set_target_properties(zynaddsubfx_synth PROPERTIES SYSTEM TRUE) -if(MINGW) - target_link_libraries(zynaddsubfx_nio PUBLIC mingw_stdthreads) - target_link_libraries(zynaddsubfx_gui PUBLIC mingw_stdthreads) - target_link_libraries(zynaddsubfx_synth PUBLIC mingw_stdthreads) -endif() - # Relative include paths don't work automatically for the GUI, because the # generated C++ files aren't in the source directory. Thus, add the expected # source directory as an additional include directory. diff --git a/plugins/ZynAddSubFx/ThreadShims.h b/plugins/ZynAddSubFx/ThreadShims.h index 843b50fb5..ff947b3d0 100644 --- a/plugins/ZynAddSubFx/ThreadShims.h +++ b/plugins/ZynAddSubFx/ThreadShims.h @@ -1,9 +1,3 @@ #include #include #include - -#if defined(__MINGW32__) && !defined(_GLIBCXX_HAS_GTHREADS) -# include -# include -# include -#endif diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 4467cd075..e5cb62527 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -11,12 +11,6 @@ target_include_directories(jack_headers INTERFACE jack2/common) ADD_SUBDIRECTORY(hiir) ADD_SUBDIRECTORY(weakjack) -if(MINGW) - option(MINGW_STDTHREADS_GENERATE_STDHEADERS "" ON) - add_subdirectory(mingw-std-threads) - set(LMMS_USE_MINGW_STD_THREADS ON PARENT_SCOPE) -endif() - # The lockless ring buffer library is linked as part of the core add_library(ringbuffer OBJECT ringbuffer/src/lib/ringbuffer.cpp diff --git a/src/3rdparty/mingw-std-threads b/src/3rdparty/mingw-std-threads deleted file mode 160000 index 6c2061b7d..000000000 --- a/src/3rdparty/mingw-std-threads +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6c2061b7da41d6aa1b2162ff4383ec3ece864bc6 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 940d485f9..5aefebf7a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -154,10 +154,6 @@ if(LMMS_HAVE_OGGVORBIS) list(APPEND EXTRA_LIBRARIES Vorbis::vorbisenc Vorbis::vorbisfile) endif() -if(LMMS_USE_MINGW_STD_THREADS) - list(APPEND EXTRA_LIBRARIES mingw_stdthreads) -endif() - SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${QT_LIBRARIES} diff --git a/src/core/FileSearch.cpp b/src/core/FileSearch.cpp index fe1efd97e..8a668360e 100644 --- a/src/core/FileSearch.cpp +++ b/src/core/FileSearch.cpp @@ -28,11 +28,7 @@ #include #include -#ifdef __MINGW32__ -#include -#else #include -#endif namespace lmms { FileSearch::FileSearch(const QString& filter, const QStringList& paths, const QStringList& extensions, From fb5268ebaea52d4b711762429689098078fb1450 Mon Sep 17 00:00:00 2001 From: Andrew Wiltshire <62200778+AW1534@users.noreply.github.com> Date: Sun, 30 Jun 2024 21:23:19 +0100 Subject: [PATCH 26/31] Adds "Show Hidden Content" checkbox (#7309) * Adds "Show Hidden Content Dialogue" * Update FileBrowser.cpp * Automatically rearrange layout to fit check boxes * check if files are hidden in a cross platform manner * put the hidden files checkbox below the user and factory check boxes at all times * removed layout rearrangement code * moved checkbox code to FileBrowser * Removed unused include * Cleanup in FileBrowser Move the method `addContentCheckBox` to the other private methods. Remove the method parameters because it can use the members. Remove the conditional when adding the "Hidden content" checkbox because it was always true. --------- Co-authored-by: Michael Gregorius --- include/FileBrowser.h | 10 ++++- src/gui/FileBrowser.cpp | 83 ++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 9185f5147..9193da5e4 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -90,7 +90,7 @@ public: }; return s_excludedPaths; } - static QDir::Filters dirFilters() { return QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot; } + static QDir::Filters dirFilters() { return QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden; } static QDir::SortFlags sortFlags() { return QDir::LocaleAware | QDir::DirsFirst | QDir::Name | QDir::IgnoreCase; } private slots: @@ -111,6 +111,8 @@ private: void onSearch(const QString& filter); void displaySearch(bool on); + void addContentCheckBox(); + FileBrowserTreeWidget * m_fileBrowserTreeWidget; FileBrowserTreeWidget * m_searchTreeWidget; @@ -124,9 +126,13 @@ private: bool m_dirsAsItems; - void addContentCheckBox(); QCheckBox* m_showUserContent = nullptr; QCheckBox* m_showFactoryContent = nullptr; + QCheckBox* m_showHiddenContent = nullptr; + + QBoxLayout *filterWidgetLayout = nullptr; + QBoxLayout *hiddenWidgetLayout = nullptr; + QBoxLayout *outerLayout = nullptr; QString m_userDir; QString m_factoryDir; QList m_savedExpandedDirs; diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 04f7ff46f..e5168fac8 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -78,31 +78,6 @@ enum TreeWidgetItemTypes } ; - -void FileBrowser::addContentCheckBox() -{ - auto filterWidget = new QWidget(contentParent()); - filterWidget->setFixedHeight(15); - auto filterWidgetLayout = new QHBoxLayout(filterWidget); - filterWidgetLayout->setContentsMargins(0, 0, 0, 0); - filterWidgetLayout->setSpacing(0); - - auto configCheckBox = [this, &filterWidgetLayout](QCheckBox* box) - { - box->setCheckState(Qt::Checked); - connect(box, SIGNAL(stateChanged(int)), this, SLOT(reloadTree())); - filterWidgetLayout->addWidget(box); - }; - - m_showUserContent = new QCheckBox(tr("User content")); - configCheckBox(m_showUserContent); - m_showFactoryContent = new QCheckBox(tr("Factory content")); - configCheckBox(m_showFactoryContent); - - addContentWidget(filterWidget); -}; - - FileBrowser::FileBrowser(const QString & directories, const QString & filter, const QString & title, const QPixmap & pm, QWidget * parent, bool dirs_as_items, @@ -117,10 +92,7 @@ FileBrowser::FileBrowser(const QString & directories, const QString & filter, { setWindowTitle( tr( "Browser" ) ); - if (!userDir.isEmpty() && !factoryDir.isEmpty()) - { - addContentCheckBox(); - } + addContentCheckBox(); auto searchWidget = new QWidget(contentParent()); searchWidget->setFixedHeight( 24 ); @@ -168,6 +140,54 @@ FileBrowser::FileBrowser(const QString & directories, const QString & filter, show(); } +void FileBrowser::addContentCheckBox() +{ + // user dir and factory dir checkboxes will display individually depending on whether they are empty. + const bool user_checkbox = !m_userDir.isEmpty(); + const bool factory = !m_factoryDir.isEmpty(); + + auto filterWidget = new QWidget(contentParent()); + + outerLayout = new QBoxLayout(QBoxLayout::Direction::TopToBottom, filterWidget); + outerLayout->setSpacing(0); + + if (user_checkbox || factory){ + filterWidgetLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight); + filterWidgetLayout->setContentsMargins(0, 0, 0, 0); + filterWidgetLayout->setSpacing(0); + + outerLayout->addLayout(filterWidgetLayout); + } + + hiddenWidgetLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight); + hiddenWidgetLayout->setContentsMargins(0, 0, 0, 0); + hiddenWidgetLayout->setSpacing(0); + + outerLayout->addLayout(hiddenWidgetLayout); + + auto configCheckBox = [this](QBoxLayout* boxLayout, QCheckBox* box, Qt::CheckState checkState) + { + box->setCheckState(checkState); + connect(box, SIGNAL(stateChanged(int)), this, SLOT(reloadTree())); + boxLayout->addWidget(box); + }; + + if (user_checkbox) { + m_showUserContent = new QCheckBox(tr("User content")); + configCheckBox(filterWidgetLayout, m_showUserContent, Qt::Checked); + } + + if (factory) { + m_showFactoryContent = new QCheckBox(tr("Factory content")); + configCheckBox(filterWidgetLayout, m_showFactoryContent, Qt::Checked); + } + + m_showHiddenContent = new QCheckBox(tr("Hidden content")); + configCheckBox(hiddenWidgetLayout, m_showHiddenContent, Qt::Unchecked); + + addContentWidget(filterWidget); +} + void FileBrowser::saveDirectoriesStates() { m_savedExpandedDirs = m_fileBrowserTreeWidget->expandedDirs(); @@ -391,12 +411,15 @@ void FileBrowser::addItems(const QString & path ) QDir cdir(path); if (!cdir.isReadable()) { return; } QFileInfoList entries = cdir.entryInfoList( - m_filter.split(' '), dirFilters(), QDir::LocaleAware | QDir::DirsFirst | QDir::Name | QDir::IgnoreCase); + m_filter.split(' '), + dirFilters(), + QDir::LocaleAware | QDir::DirsFirst | QDir::Name | QDir::IgnoreCase); for (const auto& entry : entries) { if (FileBrowser::excludedPaths().contains(entry.absoluteFilePath())) { continue; } QString fileName = entry.fileName(); + if (entry.isHidden() && m_showHiddenContent && !m_showHiddenContent->isChecked()) continue; if (entry.isDir()) { // Merge dir's together From 0bc911e26676e7e40b19c452922df58e24cb0e46 Mon Sep 17 00:00:00 2001 From: Andrew Wiltshire <62200778+AW1534@users.noreply.github.com> Date: Mon, 1 Jul 2024 15:29:15 +0100 Subject: [PATCH 27/31] Reduce Memory Leaks (#7345) --- src/core/NotePlayHandle.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 4ee30054a..729048c18 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -670,7 +670,9 @@ void NotePlayHandleManager::extend( int c ) void NotePlayHandleManager::free() { + delete s_available[0]; delete[] s_available; + s_available = nullptr; } From 449e6690673e9d83a625d4de9e1e8dc746190811 Mon Sep 17 00:00:00 2001 From: saker Date: Mon, 1 Jul 2024 13:43:05 -0400 Subject: [PATCH 28/31] Revert "Reduce Memory Leaks (#7345)" (#7360) This reverts commit 0bc911e26676e7e40b19c452922df58e24cb0e46. --- src/core/NotePlayHandle.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 729048c18..4ee30054a 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -670,9 +670,7 @@ void NotePlayHandleManager::extend( int c ) void NotePlayHandleManager::free() { - delete s_available[0]; delete[] s_available; - s_available = nullptr; } From 538572a3c53131cb71a95ca0522e56fa8fb77e6a Mon Sep 17 00:00:00 2001 From: saker Date: Tue, 2 Jul 2024 12:02:34 -0400 Subject: [PATCH 29/31] Change `fpp_t` usage in `SampleFrame` to use `size_t` instead (#7362) --- include/SampleFrame.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/SampleFrame.h b/include/SampleFrame.h index 5f02cd352..533c8abf4 100644 --- a/include/SampleFrame.h +++ b/include/SampleFrame.h @@ -29,6 +29,7 @@ #include "lmms_basics.h" #include +#include namespace lmms @@ -186,7 +187,7 @@ private: std::array m_samples; }; -inline void zeroSampleFrames(SampleFrame* buffer, fpp_t frames) +inline void zeroSampleFrames(SampleFrame* buffer, size_t frames) { // The equivalent of the following operation which yields compiler warnings // memset(buffer, 0, sizeof(SampleFrame) * frames); @@ -194,7 +195,7 @@ inline void zeroSampleFrames(SampleFrame* buffer, fpp_t frames) std::fill(buffer, buffer + frames, SampleFrame()); } -inline SampleFrame getAbsPeakValues(SampleFrame* buffer, fpp_t frames) +inline SampleFrame getAbsPeakValues(SampleFrame* buffer, size_t frames) { SampleFrame peaks; @@ -206,18 +207,18 @@ inline SampleFrame getAbsPeakValues(SampleFrame* buffer, fpp_t frames) return peaks; } -inline void copyToSampleFrames(SampleFrame* target, const float* source, fpp_t frames) +inline void copyToSampleFrames(SampleFrame* target, const float* source, size_t frames) { - for (fpp_t i = 0; i < frames; ++i) + for (size_t i = 0; i < frames; ++i) { target[i].setLeft(source[2*i]); target[i].setRight(source[2*i + 1]); } } -inline void copyFromSampleFrames(float* target, const SampleFrame* source, fpp_t frames) +inline void copyFromSampleFrames(float* target, const SampleFrame* source, size_t frames) { - for (fpp_t i = 0; i < frames; ++i) + for (size_t i = 0; i < frames; ++i) { target[2*i] = source[i].left(); target[2*i + 1] = source[i].right(); From 0384813ae40eaa0ee7e8fc7bcf5a2e2573c87265 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 5 Jul 2024 16:47:44 +0200 Subject: [PATCH 30/31] Fix buzz in Monstro's 2nd oscillator (#7334) (#7368) Fix a buzzing sound in Monstro's 2nd oscillator. It was introduced with commit c2f2b7e0d76. The problem was caused by checking if `len_r` is not equal to 0 instead of checking `pd_r`. --- plugins/Monstro/Monstro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Monstro/Monstro.cpp b/plugins/Monstro/Monstro.cpp index c9b715ba7..7063be0e2 100644 --- a/plugins/Monstro/Monstro.cpp +++ b/plugins/Monstro/Monstro.cpp @@ -514,7 +514,7 @@ void MonstroSynth::renderOutput( fpp_t _frames, SampleFrame* _buf ) } sample_t O2R = 0.; - if (len_r != 0.) + if (pd_r != 0.) { len_r = BandLimitedWave::pdToLen(pd_r); if (m_counter2r > 0) From bdd94ec2158fff624a4bd3fe7d01cb621b4ce597 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sat, 6 Jul 2024 14:14:51 +0100 Subject: [PATCH 31/31] Run CMake with -Werror=dev in CI (#7322) --- .github/workflows/build.yml | 3 +++ cmake/modules/FindPulseAudio.cmake | 16 +++++++++------- cmake/modules/FindSndio.cmake | 2 +- cmake/modules/FindSoundIo.cmake | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9a63375c6..14c617b65 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,6 +81,7 @@ jobs: runs-on: ${{ matrix.os }} env: CMAKE_OPTS: >- + -Werror=dev -DUSE_WERROR=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUSE_COMPILE_CACHE=ON @@ -176,6 +177,7 @@ jobs: container: ghcr.io/lmms/linux.mingw:20.04 env: CMAKE_OPTS: >- + -Werror=dev -DUSE_WERROR=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUSE_COMPILE_CACHE=ON @@ -293,6 +295,7 @@ jobs: -B build ` -G Ninja ` --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake ` + -Werror=dev ` -DCMAKE_BUILD_TYPE=RelWithDebInfo ` -DUSE_COMPILE_CACHE=ON ` -DUSE_WERROR=ON ` diff --git a/cmake/modules/FindPulseAudio.cmake b/cmake/modules/FindPulseAudio.cmake index 8ea2616cf..0023d1d63 100644 --- a/cmake/modules/FindPulseAudio.cmake +++ b/cmake/modules/FindPulseAudio.cmake @@ -18,13 +18,15 @@ ENDIF (PULSEAUDIO_INCLUDE_DIR AND PULSEAUDIO_LIBRARIES) IF (NOT WIN32) # use pkg-config to get the directories and then use these values # in the FIND_PATH() and FIND_LIBRARY() calls - INCLUDE(FindPkgConfig) - pkg_check_modules(PA libpulse) - set(_PASIncDir ${PA_INCLUDE_DIRS}) - set(_PASLinkDir ${PA_LIBRARY_DIRS}) - set(_PASLinkFlags ${PA_LDFLAGS}) - set(_PASCflags ${PA_CFLAGS}) - SET(PULSEAUDIO_DEFINITIONS ${_PASCflags}) + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PA libpulse) + set(_PASIncDir ${PA_INCLUDE_DIRS}) + set(_PASLinkDir ${PA_LIBRARY_DIRS}) + set(_PASLinkFlags ${PA_LDFLAGS}) + set(_PASCflags ${PA_CFLAGS}) + set(PULSEAUDIO_DEFINITIONS ${_PASCflags}) + endif() ENDIF (NOT WIN32) FIND_PATH(PULSEAUDIO_INCLUDE_DIR pulse/pulseaudio.h diff --git a/cmake/modules/FindSndio.cmake b/cmake/modules/FindSndio.cmake index e993702c2..a1b24d06c 100644 --- a/cmake/modules/FindSndio.cmake +++ b/cmake/modules/FindSndio.cmake @@ -24,7 +24,7 @@ check_library_exists(sndio sio_open "${SNDIO_LIBRARY_DIR}" HAVE_SIO_OPEN) find_path(SNDIO_INCLUDE_DIR sndio.h) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(SNDIO DEFAULT_MSG SNDIO_LIBRARY SNDIO_INCLUDE_DIR HAVE_SIO_OPEN) +find_package_handle_standard_args(Sndio DEFAULT_MSG SNDIO_LIBRARY SNDIO_INCLUDE_DIR HAVE_SIO_OPEN) if(SNDIO_FOUND) set(SNDIO_INCLUDE_DIRS "${SNDIO_INCLUDE_DIR}") diff --git a/cmake/modules/FindSoundIo.cmake b/cmake/modules/FindSoundIo.cmake index 0d905ecf2..f5948f061 100644 --- a/cmake/modules/FindSoundIo.cmake +++ b/cmake/modules/FindSoundIo.cmake @@ -11,6 +11,6 @@ find_path(SOUNDIO_INCLUDE_DIR NAMES soundio/soundio.h) find_library(SOUNDIO_LIBRARY NAMES soundio) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(SOUNDIO DEFAULT_MSG SOUNDIO_LIBRARY SOUNDIO_INCLUDE_DIR) +find_package_handle_standard_args(SoundIo DEFAULT_MSG SOUNDIO_LIBRARY SOUNDIO_INCLUDE_DIR) mark_as_advanced(SOUNDIO_INCLUDE_DIR SOUNDIO_LIBRARY)