From 86f9a75d98a0389c60975eade7b88944f8e82907 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 7 Nov 2018 13:41:03 +0900 Subject: [PATCH 01/79] Fix song editor visualization after maximizing (#4698) --- include/SongEditor.h | 1 + src/gui/editors/SongEditor.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/include/SongEditor.h b/include/SongEditor.h index db4d7d781..e03c63280 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -155,6 +155,7 @@ public: protected: virtual void resizeEvent( QResizeEvent * event ); + virtual void changeEvent( QEvent * ); protected slots: void play(); diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 5eb7ff6e2..f3b69e47d 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -723,6 +723,16 @@ void SongEditorWindow::resizeEvent(QResizeEvent *event) } +void SongEditorWindow::changeEvent(QEvent *event) +{ + QWidget::changeEvent(event); + if (event->type() == QEvent::WindowStateChange) + { + m_editor->realignTracks(); + } +} + + void SongEditorWindow::play() { emit playTriggered(); From a8828d332c636b2955c54372c593e95dc6513c30 Mon Sep 17 00:00:00 2001 From: Karmo Rosental Date: Fri, 9 Nov 2018 09:20:38 +0200 Subject: [PATCH 02/79] Update TimeLineWidget 60 times per second (#4703) In addition to #4570. --- src/gui/TimeLineWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 47d9db95e..cfb4288c7 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -93,7 +93,7 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, QTimer * updateTimer = new QTimer( this ); connect( updateTimer, SIGNAL( timeout() ), this, SLOT( updatePosition() ) ); - updateTimer->start( 50 ); + updateTimer->start( 1000 / 60 ); // 60 fps connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int,int ) ), this, SLOT( update() ) ); } From 2070ef21f575a4fbc80505ccd0280c756f03c5e8 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Mon, 12 Nov 2018 22:24:08 +0000 Subject: [PATCH 03/79] Handle automation on processing thread (#4692) --- include/Model.h | 17 +++++++++++++++ plugins/VstEffect/VstEffectControls.cpp | 29 ++++++++++++++++--------- plugins/VstEffect/VstEffectControls.h | 4 ++-- plugins/vestige/vestige.cpp | 28 ++++++++++++++++-------- plugins/vestige/vestige.h | 4 ++-- plugins/vst_base/RemoteVstPlugin.cpp | 4 +++- plugins/zynaddsubfx/ZynAddSubFx.cpp | 23 +++++++++++++------- src/core/AutomatableModel.cpp | 6 +++-- src/core/ControllerConnection.cpp | 2 +- src/tracks/InstrumentTrack.cpp | 12 ++++++---- 10 files changed, 90 insertions(+), 39 deletions(-) diff --git a/include/Model.h b/include/Model.h index 55e735a05..7071bb867 100644 --- a/include/Model.h +++ b/include/Model.h @@ -41,6 +41,10 @@ public: m_displayName( _display_name ), m_defaultConstructed( _default_constructed ) { +#if QT_VERSION < 0x050000 + connect( this, SIGNAL( dataChanged() ), this, + SLOT( thisDataChanged() ), Qt::DirectConnection ); +#endif } virtual ~Model() @@ -85,6 +89,19 @@ signals: // emitted if properties of the model (e.g. ranges) have changed void propertiesChanged(); +#if QT_VERSION < 0x050000 + // emitted along with dataChanged(), but with this model as an argument + // workaround for when QObject::sender() and Qt5 are unavailable + void dataChanged( Model * ); + +private slots: + void thisDataChanged() + { + emit dataChanged( this ); + } + +signals: +#endif } ; diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index e5261d625..2d89e20bb 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -90,7 +90,13 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } - connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); +#if QT_VERSION < 0x050000 + connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ), + this, SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( knobFModel[i], &FloatModel::dataChanged, this, + [this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection); +#endif } } @@ -100,10 +106,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) -void VstEffectControls::setParameter( void ) +void VstEffectControls::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_effect->m_plugin != NULL ) { @@ -385,9 +389,16 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls * m_vi->knobFModel[ i ] = new FloatModel( LocaleHelper::toFloat(s_dumpValues.at(2)), 0.0f, 1.0f, 0.01f, _eff, tr( paramStr ) ); } - connect( m_vi->knobFModel[ i ], SIGNAL( dataChanged() ), this, - SLOT( setParameter() ) ); - vstKnobs[ i ] ->setModel( m_vi->knobFModel[ i ] ); + + FloatModel * model = m_vi->knobFModel[i]; +#if QT_VERSION < 0x050000 + connect( model, SIGNAL( dataChanged( Model * ) ), this, + SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( model, &FloatModel::dataChanged, this, + [this, model]() { setParameter( model ); }, Qt::DirectConnection); +#endif + vstKnobs[ i ] ->setModel( model ); } int i = 0; @@ -480,10 +491,8 @@ void manageVSTEffectView::displayAutomatedOnly( void ) -void manageVSTEffectView::setParameter( void ) +void manageVSTEffectView::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_effect->m_plugin != NULL ) { diff --git a/plugins/VstEffect/VstEffectControls.h b/plugins/VstEffect/VstEffectControls.h index e4f099fd1..092669f94 100644 --- a/plugins/VstEffect/VstEffectControls.h +++ b/plugins/VstEffect/VstEffectControls.h @@ -70,7 +70,7 @@ protected slots: void rollPreset( void ); void rolrPreset( void ); void selPreset( void ); - void setParameter( void ); + void setParameter( Model * action ); protected: virtual void paintEvent( QPaintEvent * _pe ); @@ -110,7 +110,7 @@ public: protected slots: void syncPlugin( void ); void displayAutomatedOnly( void ); - void setParameter( void ); + void setParameter( Model * action ); void closeWindow(); private: diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index c31611626..0d985a108 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -209,7 +209,13 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } - connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); +#if QT_VERSION < 0x050000 + connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ), + this, SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( knobFModel[i], &FloatModel::dataChanged, this, + [this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection); +#endif } } m_pluginMutex.unlock(); @@ -218,10 +224,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) -void vestigeInstrument::setParameter( void ) +void vestigeInstrument::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_plugin != NULL ) { @@ -996,8 +1000,16 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume m_vi->knobFModel[ i ] = new FloatModel( LocaleHelper::toFloat(s_dumpValues.at(2)), 0.0f, 1.0f, 0.01f, castModel(), tr( paramStr ) ); } - connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); - vstKnobs[i] ->setModel( m_vi->knobFModel[i] ); + + FloatModel * model = m_vi->knobFModel[i]; +#if QT_VERSION < 0x050000 + connect( model, SIGNAL( dataChanged( Model * ) ), this, + SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( model, &FloatModel::dataChanged, this, + [this, model]() { setParameter( model ); }, Qt::DirectConnection); +#endif + vstKnobs[i] ->setModel( model ); } int i = 0; @@ -1128,10 +1140,8 @@ manageVestigeInstrumentView::~manageVestigeInstrumentView() -void manageVestigeInstrumentView::setParameter( void ) +void manageVestigeInstrumentView::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_vi->m_plugin != NULL ) { diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 2c007efc0..3b92eea8f 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -73,7 +73,7 @@ public: virtual PluginView * instantiateView( QWidget * _parent ); protected slots: - void setParameter( void ); + void setParameter( Model * action ); void handleConfigChange( QString cls, QString attr, QString value ); void reloadPlugin(); @@ -109,7 +109,7 @@ public: protected slots: void syncPlugin( void ); void displayAutomatedOnly( void ); - void setParameter( void ); + void setParameter( Model * action ); void closeWindow(); diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 219a153f5..4a41aea0c 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -1936,7 +1936,9 @@ DWORD WINAPI RemoteVstPlugin::processingThread( LPVOID _param ) RemotePluginClient::message m; while( ( m = _this->receiveMessage() ).id != IdQuit ) { - if( m.id == IdStartProcessing || m.id == IdMidiEvent ) + if( m.id == IdStartProcessing + || m.id == IdMidiEvent + || m.id == IdVstSetParameter ) { _this->processMessage( m ); } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index a0f381971..fff13c62d 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -122,13 +122,20 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument( { initPlugin(); - connect( &m_portamentoModel, SIGNAL( dataChanged() ), this, SLOT( updatePortamento() ) ); - connect( &m_filterFreqModel, SIGNAL( dataChanged() ), this, SLOT( updateFilterFreq() ) ); - connect( &m_filterQModel, SIGNAL( dataChanged() ), this, SLOT( updateFilterQ() ) ); - connect( &m_bandwidthModel, SIGNAL( dataChanged() ), this, SLOT( updateBandwidth() ) ); - connect( &m_fmGainModel, SIGNAL( dataChanged() ), this, SLOT( updateFmGain() ) ); - connect( &m_resCenterFreqModel, SIGNAL( dataChanged() ), this, SLOT( updateResCenterFreq() ) ); - connect( &m_resBandwidthModel, SIGNAL( dataChanged() ), this, SLOT( updateResBandwidth() ) ); + connect( &m_portamentoModel, SIGNAL( dataChanged() ), + this, SLOT( updatePortamento() ), Qt::DirectConnection ); + connect( &m_filterFreqModel, SIGNAL( dataChanged() ), + this, SLOT( updateFilterFreq() ), Qt::DirectConnection ); + connect( &m_filterQModel, SIGNAL( dataChanged() ), + this, SLOT( updateFilterQ() ), Qt::DirectConnection ); + connect( &m_bandwidthModel, SIGNAL( dataChanged() ), + this, SLOT( updateBandwidth() ), Qt::DirectConnection ); + connect( &m_fmGainModel, SIGNAL( dataChanged() ), + this, SLOT( updateFmGain() ), Qt::DirectConnection ); + connect( &m_resCenterFreqModel, SIGNAL( dataChanged() ), + this, SLOT( updateResCenterFreq() ), Qt::DirectConnection ); + connect( &m_resBandwidthModel, SIGNAL( dataChanged() ), + this, SLOT( updateResBandwidth() ), Qt::DirectConnection ); // now we need a play-handle which cares for calling play() InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrumentTrack ); @@ -138,7 +145,7 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument( this, SLOT( reloadPlugin() ) ); connect( instrumentTrack()->pitchRangeModel(), SIGNAL( dataChanged() ), - this, SLOT( updatePitchRange() ) ); + this, SLOT( updatePitchRange() ), Qt::DirectConnection ); } diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index ba81a5893..5a97c3280 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -417,7 +417,8 @@ void AutomatableModel::linkModel( AutomatableModel* model ) if( !model->hasLinkedModels() ) { - QObject::connect( this, SIGNAL( dataChanged() ), model, SIGNAL( dataChanged() ) ); + QObject::connect( this, SIGNAL( dataChanged() ), + model, SIGNAL( dataChanged() ), Qt::DirectConnection ); } } } @@ -476,7 +477,8 @@ void AutomatableModel::setControllerConnection( ControllerConnection* c ) m_controllerConnection = c; if( c ) { - QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), this, SIGNAL( dataChanged() ) ); + QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), + this, SIGNAL( dataChanged() ), Qt::DirectConnection ); QObject::connect( m_controllerConnection, SIGNAL( destroyed() ), this, SLOT( unlinkControllerConnection() ) ); m_valueChanged = true; emit dataChanged(); diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index af398d389..45e36e12f 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -117,7 +117,7 @@ void ControllerConnection::setController( Controller * _controller ) { _controller->addConnection( this ); QObject::connect( _controller, SIGNAL( valueChanged() ), - this, SIGNAL( valueChanged() ) ); + this, SIGNAL( valueChanged() ), Qt::DirectConnection ); } m_ownsController = diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index d5ded0c70..98a691a9a 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -126,10 +126,14 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) : setName( tr( "Default preset" ) ); - connect( &m_baseNoteModel, SIGNAL( dataChanged() ), this, SLOT( updateBaseNote() ) ); - connect( &m_pitchModel, SIGNAL( dataChanged() ), this, SLOT( updatePitch() ) ); - connect( &m_pitchRangeModel, SIGNAL( dataChanged() ), this, SLOT( updatePitchRange() ) ); - connect( &m_effectChannelModel, SIGNAL( dataChanged() ), this, SLOT( updateEffectChannel() ) ); + connect( &m_baseNoteModel, SIGNAL( dataChanged() ), + this, SLOT( updateBaseNote() ), Qt::DirectConnection ); + connect( &m_pitchModel, SIGNAL( dataChanged() ), + this, SLOT( updatePitch() ), Qt::DirectConnection ); + connect( &m_pitchRangeModel, SIGNAL( dataChanged() ), + this, SLOT( updatePitchRange() ), Qt::DirectConnection ); + connect( &m_effectChannelModel, SIGNAL( dataChanged() ), + this, SLOT( updateEffectChannel() ), Qt::DirectConnection ); } From ff060982ac02264f6c8e00315cde914cf7356519 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Wed, 14 Nov 2018 14:01:00 +0100 Subject: [PATCH 04/79] Add initial Debian packaging for stable-1.2 (#4697) * Add initial Debian packaging for stable-1.2 * Drop Debian menu entry --- debian/calf-ladspa.install | 1 + debian/changelog | 382 +++++++++ debian/compat | 1 + debian/control | 118 +++ debian/copyright | 915 ++++++++++++++++++++++ debian/gbp.conf | 2 + debian/lmms-bin.install | 13 + debian/lmms-bin.lintian-overrides | 9 + debian/lmms-common.docs | 1 + debian/lmms-common.install | 20 + debian/lmms-common.links | 1 + debian/lmms-common.maintscript | 1 + debian/lmms-vst-server.install | 1 + debian/lmms.xpm | 252 ++++++ debian/patches/build-amd64-20181013.patch | 46 ++ debian/patches/clang.patch | 601 ++++++++++++++ debian/patches/contributors.patch | 89 +++ debian/patches/series | 3 + debian/rules | 34 + debian/source/format | 1 + debian/watch | 3 + 21 files changed, 2494 insertions(+) create mode 100644 debian/calf-ladspa.install create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/gbp.conf create mode 100644 debian/lmms-bin.install create mode 100644 debian/lmms-bin.lintian-overrides create mode 100644 debian/lmms-common.docs create mode 100644 debian/lmms-common.install create mode 100644 debian/lmms-common.links create mode 100644 debian/lmms-common.maintscript create mode 100644 debian/lmms-vst-server.install create mode 100644 debian/lmms.xpm create mode 100644 debian/patches/build-amd64-20181013.patch create mode 100644 debian/patches/clang.patch create mode 100644 debian/patches/contributors.patch create mode 100644 debian/patches/series create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/watch diff --git a/debian/calf-ladspa.install b/debian/calf-ladspa.install new file mode 100644 index 000000000..c25e49dbc --- /dev/null +++ b/debian/calf-ladspa.install @@ -0,0 +1 @@ +usr/lib/*/lmms/ladspa/calf.so usr/lib/ladspa diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..c44b1790c --- /dev/null +++ b/debian/changelog @@ -0,0 +1,382 @@ +lmms (1.2.0~rc7.1) 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 new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..0997676c9 --- /dev/null +++ b/debian/control @@ -0,0 +1,118 @@ +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, + libmp3lame-dev, + libpulse-dev, + libqt5x11extras5-dev, + libsamplerate0-dev, + libsdl1.2-dev, + libsndfile1-dev, + libsndio-dev, + libsoundio-dev, + libstk0-dev, + libvorbis-dev, + libxcb-keysyms1-dev, + libxcb-util0-dev, + portaudio19-dev, + qtbase5-private-dev, + qttools5-dev, + wine32-tools [i386] +Standards-Version: 4.2.1.4 +Homepage: http://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: calf-ladspa, tap-plugins, caps, + lmms-vst-server:i386 (>= ${source:Version}) +Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm, + ladspa-plugin +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: calf-ladspa, 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: zynaddsubfx-data, ${shlibs:Depends}, ${misc:Depends} +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: i386 +# Order matters to avoid wine64 +Depends: wine32, wine, ${shlibs:Depends}, ${misc:Depends} +Recommends: lmms-bin:any +Description: Linux Multimedia Studio - VST server + This package contains a helper application that loads VST plugins. + +Package: calf-ladspa +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Replaces: calf-plugins (<< 0.0.19) +Provides: ladspa-plugin +Description: Linux Multimedia Studio - Calf LADSPA plugins + Calf is a pack of audio plugins - effects and instruments. The goal is to + create a set of plugins using decent algorithms and parameter settings, + available in a form which is compatible with as many open source applications + as possible. + . + These plugins are distributed as part of Linux Multimedia Studio, but may be + used by other applications. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..0b8729215 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,915 @@ +Format: http://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/CoolSongs/Alf42red-* + data/projects/CoolSongs/CapDan/CapDan-TwilightArea-* +Copyright: + 2010-2011 Armin Heller + 2011 Der Daniel (CapDan) +License: CC-BY-SA-3 + +Files: data/projects/CoolSongs/CapDan/CapDan-ZeroSumGame-* + data/projects/CoolSongs/Impulslogik-* + data/projects/CoolSongs/Momo64-* + data/projects/CoolSongs/Oglsdl-* + data/projects/CoolSongs/Settel-* + data/projects/CoolSongs/Socceroos-* + data/projects/CoolSongs/TameAnderson-* + data/projects/CoolSongs/Zakarra/* + data/projects/Demos/CapDan-* + data/projects/Demos/EsoXLB-* + data/projects/Demos/Oglsdl-* + data/projects/Demos/Thomasso-* + 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 Zakarra + 2011 mauro (momo64) + 2011 tame anderson + 2011 Ümit (oglsdl) + Greshz +License: Artistic-2 + +Files: data/projects/CoolSongs/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/* +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/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/* +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/gsm/* +Copyright: + 1992-1994 Carsten Bormann + 1992-1994 Jutta Degener +License: Bormann-Degener + +Files: plugins/LadspaEffect/swh/util/pitchscale.c +Copyright: + 1999 Stephan M. Sprenger +License: WOL + +Files: plugins/LadspaEffect/swh/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/opl2/fmopl.* + plugins/opl2/mididata.h + plugins/opl2/opl.h + plugins/opl2/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: 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 http://www.dspguru.com/wol.htm for more information. diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 000000000..cec628c74 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,2 @@ +[DEFAULT] +pristine-tar = True diff --git a/debian/lmms-bin.install b/debian/lmms-bin.install new file mode 100644 index 000000000..58b8e9ecc --- /dev/null +++ b/debian/lmms-bin.install @@ -0,0 +1,13 @@ +usr/bin/lmms +usr/lib/*/lmms/ladspa/[a-b]* +usr/lib/*/lmms/ladspa/caps.so +usr/lib/*/lmms/ladspa/c[b-z]* +usr/lib/*/lmms/ladspa/[d-z]* +usr/lib/*/lmms/lib* +usr/lib/*/lmms/RemoteZynAddSubFx +usr/share/man/* +usr/share/applications/* +data/application-x-lmms-project.svg usr/share/icons/hicolor/64x64/mimetypes + +data/lmms.png usr/share/icons/hicolor/512x512/apps +data/lmms.png usr/share/pixmaps diff --git a/debian/lmms-bin.lintian-overrides b/debian/lmms-bin.lintian-overrides new file mode 100644 index 000000000..45e07c39d --- /dev/null +++ b/debian/lmms-bin.lintian-overrides @@ -0,0 +1,9 @@ +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 new file mode 100644 index 000000000..a7b624a0a --- /dev/null +++ b/debian/lmms-common.docs @@ -0,0 +1 @@ +plugins/LadspaEffect/caps/caps.html diff --git a/debian/lmms-common.install b/debian/lmms-common.install new file mode 100644 index 000000000..f2b7139a7 --- /dev/null +++ b/debian/lmms-common.install @@ -0,0 +1,20 @@ +usr/share/lmms/[a-o]* +usr/share/lmms/presets/[A-Y]* +usr/share/lmms/projects/CoolSongs/[A-C]* +usr/share/lmms/projects/CoolSongs/[I-M]* +usr/share/lmms/projects/CoolSongs/O* +usr/share/lmms/projects/CoolSongs/S[a-e]* +usr/share/lmms/projects/CoolSongs/So* +usr/share/lmms/projects/CoolSongs/Ta* +usr/share/lmms/projects/CoolSongs/To* +usr/share/lmms/projects/CoolSongs/Z* +usr/share/lmms/projects/Demos/An* +usr/share/lmms/projects/Demos/C* +usr/share/lmms/projects/Demos/[E-O]* +usr/share/lmms/projects/Demos/T* +usr/share/lmms/projects/Shorties/G* +usr/share/lmms/projects/Shorties/Su* +usr/share/lmms/projects/[a-z]* +usr/share/lmms/[q-z]* +usr/share/mime/* +debian/lmms.xpm usr/share/pixmaps/ diff --git a/debian/lmms-common.links b/debian/lmms-common.links new file mode 100644 index 000000000..75596233c --- /dev/null +++ b/debian/lmms-common.links @@ -0,0 +1 @@ +usr/share/zynaddsubfx/banks usr/share/lmms/presets/ZynAddSubFX diff --git a/debian/lmms-common.maintscript b/debian/lmms-common.maintscript new file mode 100644 index 000000000..15d673556 --- /dev/null +++ b/debian/lmms-common.maintscript @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..1b520479d --- /dev/null +++ b/debian/lmms-vst-server.install @@ -0,0 +1 @@ +usr/lib/*/lmms/RemoteVstPlugin* diff --git a/debian/lmms.xpm b/debian/lmms.xpm new file mode 100644 index 000000000..33e056eab --- /dev/null +++ b/debian/lmms.xpm @@ -0,0 +1,252 @@ +/* XPM */ +static char *lmms[] = { +/* columns rows colors chars-per-pixel */ +"24 24 222 2 ", +" c #061811", +". c #071B13", +"X c #062F1D", +"o c #072F1E", +"O c #0C2A1D", +"+ c #06301C", +"@ c #06301D", +"# c #07301D", +"$ c #07301E", +"% c #07311E", +"& c #07311F", +"* c #09301F", +"= c #0D2E20", +"- c #083320", +"; c #0B3623", +": c #093825", +"> c #093A25", +", c #0C3C26", +"< c #084C2D", +"1 c #14432D", +"2 c #054D31", +"3 c #0D4E31", +"4 c #075434", +"5 c #075535", +"6 c #095034", +"7 c #0A5E34", +"8 c #0C5839", +"9 c #0E5E3B", +"0 c #125937", +"q c #13533B", +"w c #17593D", +"e c #1C5B3E", +"r c #0C603F", +"t c #0B673F", +"y c #0C683B", +"u c #0B6642", +"i c #0B6940", +"p c #0C6941", +"a c #1A6144", +"s c #1C6445", +"d c #116D44", +"f c #1B6949", +"g c #137446", +"h c #147645", +"j c #137A4A", +"k c #157F4D", +"l c #207450", +"z c #2A7A51", +"x c #2A7F54", +"c c #0F804B", +"v c #128041", +"b c #148448", +"n c #13824F", +"m c #17884D", +"M c #139446", +"N c #16984F", +"B c #178851", +"V c #158C53", +"C c #168A55", +"Z c #198851", +"A c #1A9C5A", +"S c #1E9F59", +"D c #2E8D5F", +"F c #2C905E", +"G c #18AB4E", +"H c #1CB24B", +"J c #1DB54B", +"K c #1DB44D", +"L c #1DB74D", +"P c #1DB54E", +"I c #1DB64F", +"U c #1DB849", +"Y c #1EBA48", +"T c #1EBA4B", +"R c #1FBC4B", +"E c #1BAD54", +"W c #1CB150", +"Q c #1EB551", +"! c #1EB751", +"~ c #1EB652", +"^ c #1EB654", +"/ c #1EB950", +"( c #1FBB52", +") c #1FB854", +"_ c #1FB158", +"` c #1FB659", +"' c #20BC4D", +"] c #20BD4D", +"[ c #20BC4E", +"{ c #20A35C", +"} c #20BC51", +"| c #21BF51", +" . c #21BD52", +".. c #22BF52", +"X. c #20BA55", +"o. c #20B957", +"O. c #20BC55", +"+. c #21BE54", +"@. c #21BC56", +"#. c #20B75C", +"$. c #20B858", +"%. c #23BF5C", +"&. c #23BD5E", +"*. c #2E8E60", +"=. c #2E9161", +"-. c #299562", +";. c #319463", +":. c #349966", +">. c #369C67", +",. c #379C67", +"<. c #309B69", +"1. c #1FAD64", +"2. c #20A861", +"3. c #21AE62", +"4. c #2BAF64", +"5. c #34A06C", +"6. c #39A069", +"7. c #3AA169", +"8. c #3AA16A", +"9. c #3DA46B", +"0. c #3DA56B", +"q. c #23BD61", +"w. c #24BF64", +"e. c #45B877", +"r. c #40BA7B", +"t. c #42BC7C", +"y. c #23C059", +"u. c #24C358", +"i. c #24C35B", +"p. c #24C15E", +"a. c #25C45E", +"s. c #25C360", +"d. c #25C361", +"f. c #27C563", +"g. c #25C164", +"h. c #25C165", +"j. c #26C167", +"k. c #27C467", +"l. c #28C863", +"z. c #2DCC62", +"x. c #28C965", +"c. c #29CA67", +"v. c #26C368", +"b. c #27C369", +"n. c #27C36A", +"m. c #28C668", +"M. c #29C76A", +"N. c #29C66D", +"B. c #2AC86B", +"V. c #2BCD68", +"C. c #2BCD69", +"Z. c #2BCC6A", +"A. c #2CCD6B", +"S. c #2DCF6A", +"D. c #2BC96C", +"F. c #2DCD6E", +"G. c #2ECE6F", +"H. c #31C563", +"J. c #38C76E", +"K. c #2DD06B", +"L. c #2ED06D", +"P. c #2FD36E", +"I. c #32D46A", +"U. c #33D76A", +"Y. c #30D66F", +"T. c #2BC970", +"R. c #2FCF70", +"E. c #2FD271", +"W. c #32D771", +"Q. c #31D572", +"!. c #32D772", +"~. c #32D871", +"^. c #34DB73", +"/. c #38DC7C", +"(. c #3FEA7B", +"). c #3FE97E", +"_. c #47C27F", +"`. c #48C380", +"'. c #48CB86", +"]. c #4BCE87", +"[. c #51CF85", +"{. c #51D68B", +"}. c #43EE81", +"|. c #55E68D", +" X c #57E98E", +".X c #44F383", +"XX c #46F482", +"oX c #46F683", +"OX c #47F783", +"+X c #4AFD85", +"@X c #58E392", +"#X c #5AE392", +"$X c #5AE593", +"%X c #5DE693", +"&X c #5EED91", +"*X c #5CE995", +"=X c #5EE894", +"-X c #60ED97", +";X c #61ED97", +":X c #63EF97", +">X c #63EF98", +",X c #63F098", +"X9XeX2Xe.1 pXpXpXpXpXpXpXpXpXpXg j.m.x.j.w.- ", +"0.iX9X{.e pXpXpXpXpXpXpXpXpXpXpXpXpX: V d.l.d.o ", +"0.iX2Xr.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXu q.a.a.o ", +",.>XtX`.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXp a.p.` X ", +",.2XiX`.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXi i.%.` X ", +"0.eX2Xt.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXt ` @.+.$ ", +"0.tXtX'.q pXpXpXpXpXpXpXpXpXpXpXpXpXpXk @.u.} $ ", +"0.2X2XwX*X5.pXpXpXpXpXpXpXpXpXpXpXy E @.L J J $ ", +"F tXiXwX8XiX@Xf pXpXpXpXpXpXpXpXN +. .~ ] R W $ ", +"v H.&XeX8X8X>X6.pXpXpXpXpXpXpX5 ^ ~ .J T z.).; ", +"b u. .J.@XwXiX7.pXpXpXpXpXpXpX4 / ] J _ (.+X.X; ", +"m x.&.o.:X>XtX7.pXpXpXpXpXpXpX4 L J H I.}..X.X; ", +"k M.V.f.8XiX:X=.pXpXpXpXpXpXpX2 G U Y U.+XOX/.* ", +"pXg n.Z.9X-Xx . pXpXpXpXpXpXpXpX< M T U..X4., pX", +"pXpX: Z :.= pXpXpXpXpXpXpXpXpXpXpXpX7 { 0 pXpXpX", +"pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpX" +}; diff --git a/debian/patches/build-amd64-20181013.patch b/debian/patches/build-amd64-20181013.patch new file mode 100644 index 000000000..9f8182903 --- /dev/null +++ b/debian/patches/build-amd64-20181013.patch @@ -0,0 +1,46 @@ +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 new file mode 100644 index 000000000..2e2a0a2f1 --- /dev/null +++ b/debian/patches/clang.patch @@ -0,0 +1,601 @@ +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/src/calf/metadata.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/metadata.h 2017-01-03 17:41:17.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/modules.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules.h 2017-01-03 19:02:59.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/modules_comp.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules_comp.h 2017-01-03 19:35:53.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/modules_limit.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules_limit.h 2017-01-03 19:39:00.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/modules_mod.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules_mod.h 2017-01-03 19:41:55.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/organ.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/organ.h 2017-01-03 19:43:08.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/preset.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/preset.h 2017-01-03 19:57:02.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/calf/primitives.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/primitives.h 2017-01-03 17:36:12.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/metadata.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/metadata.cpp 2017-01-03 17:52:03.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/src/modules.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/modules.cpp 2017-01-03 19:32:38.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/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/flanger_1191.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/flanger_1191.c 2017-01-03 15:44:13.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/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/gsm/short_term.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/gsm/short_term.c 2017-01-03 15:35:13.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/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/multivoice_chorus_1201.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/multivoice_chorus_1201.c 2017-01-03 15:47:51.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/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/retro_flange_1208.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/retro_flange_1208.c 2017-01-03 15:46:35.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/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/vynil_1905.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/vynil_1905.c 2017-01-03 15:51:56.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/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/opl2/fmopl.c +=================================================================== +--- lmms-1.1.3.orig/plugins/opl2/fmopl.c 2017-01-03 20:11:03.000000000 +0100 ++++ lmms-1.1.3/plugins/opl2/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< + +Index: lmms-1.1.3/doc/CONTRIBUTORS +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ lmms-1.1.3/doc/CONTRIBUTORS 2016-07-12 00:41:47.000000000 +0200 +@@ -0,0 +1,77 @@ ++Tobias Doerffel ++Vesa ++Javier Serrano Polo ++Paul Giblock ++Tres Finocchiaro ++Lukas W ++Raine M. Ekman ++Wong Cho Ching ++Hannu Haahti ++Danny McRae ++Dave French ++Daniel Winzen ++Andreas Brandmaier ++Andrew Kelley ++Oskar Wallgren ++Mike Choi ++Alexandre Almeida ++NoiseByNorthwest ++Johannes Lorenz ++Stian Jørgensrud ++falkTX ++Csaba Hruska ++StakeoutPunch ++ma2moto ++mikobuntu ++8tab <8tab@wp.pl> ++Matthew Krafczyk ++Spekular ++Umcaruje ++DeRobyJ ++Jonathan Aquilina ++ra ++wongcc966422 ++Gurjot Singh ++Janne Sinisalo ++Krzysztof Foltman ++Lou Herard ++Paul Wayper ++Rüdiger Ranft ++Yann Collette ++grindhold ++midi-pascal ++unfa ++Ian Sannar ++Jaroslav Petrnoušek ++LYF610400210 ++Rafael Ruggiero ++psyomn ++quadro ++sarahkeefe ++Achim Settelmeier ++André Hentschel ++Armin Kazmi ++Attila Herman ++Christopher A. Oliver ++Devin Venable ++Fastigium ++Frank Mather ++Frederik ++Hexasoft ++Jens Lang ++Jesse Dubay ++Joel Muzzerall ++Kristi ++Markus Elfring ++Nikos Chantziaras ++Paul Nasca ++Peter Nelson ++Ra ++Steffen Baranowsky ++Thorsten Müller ++TonyChyi ++devin ++dnl-music ++fundamental ++groboclown ++zm1990s diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 000000000..aba1af044 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,3 @@ +contributors.patch +clang.patch +build-amd64-20181013.patch diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..6a78a51ba --- /dev/null +++ b/debian/rules @@ -0,0 +1,34 @@ +#!/usr/bin/make -f + +#Rodney Dawes Version simplifies things :) + +DH_CMAKE_BUILD_DIR=obj -${DEB_BUILD_GNU_TYPE} +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) + +CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DWANT_QT5=1 +ifneq ($(DEB_HOST_ARCH_OS),linux) +CMAKE_OPTS+= -DWANT_ALSA=0 +endif + +ifeq ($(DEB_HOST_ARCH),i386) +export PATH := $(PATH):/usr/lib/wine +WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine +CMAKE_OPTS+= -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH) +else +CMAKE_OPTS+= -DWANT_VST_NOWINE=1 \ + -DREMOTE_VST_PLUGIN_FILEPATH=../../i386-linux-gnu/lmms/RemoteVstPlugin +endif + +# Define NDEBUG. This helps with reproducible builds. +# Add -Wno-error=format-truncation because truncation is expected in snprintf. +export CFLAGS ?= $(shell dpkg-buildflags --get CFLAGS) -DNDEBUG +export CXXFLAGS ?= $(shell dpkg-buildflags --get CXXFLAGS) -DNDEBUG \ + -Wno-error=format-truncation + +%: + dh $@ --buildsystem cmake + +override_dh_auto_configure: + dh_auto_configure -- -DCMAKE_INSTALL_LIBDIR=lib/$(DEB_HOST_MULTIARCH) $(CMAKE_OPTS) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/watch b/debian/watch new file mode 100644 index 000000000..be099ee74 --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=3 +opts="filenamemangle=s/(?:.*\/)?v?(\d[\d\.]*)\.tar\.gz/lmms_$1.tar.gz/" \ +https://github.com/LMMS/lmms/tags (?:.*/)?v?(\d[\d\.]*)\.tar\.gz From c3b07a509250c5ae5bf67ac287b055083ba17edb Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Fri, 16 Nov 2018 21:45:19 +0100 Subject: [PATCH 05/79] New pixmap as per #4519 (#4708) --- debian/lmms.xpm | 353 ++++++++++++++---------------------------------- 1 file changed, 102 insertions(+), 251 deletions(-) diff --git a/debian/lmms.xpm b/debian/lmms.xpm index 33e056eab..425e3156d 100644 --- a/debian/lmms.xpm +++ b/debian/lmms.xpm @@ -1,252 +1,103 @@ /* XPM */ -static char *lmms[] = { -/* columns rows colors chars-per-pixel */ -"24 24 222 2 ", -" c #061811", -". c #071B13", -"X c #062F1D", -"o c #072F1E", -"O c #0C2A1D", -"+ c #06301C", -"@ c #06301D", -"# c #07301D", -"$ c #07301E", -"% c #07311E", -"& c #07311F", -"* c #09301F", -"= c #0D2E20", -"- c #083320", -"; c #0B3623", -": c #093825", -"> c #093A25", -", c #0C3C26", -"< c #084C2D", -"1 c #14432D", -"2 c #054D31", -"3 c #0D4E31", -"4 c #075434", -"5 c #075535", -"6 c #095034", -"7 c #0A5E34", -"8 c #0C5839", -"9 c #0E5E3B", -"0 c #125937", -"q c #13533B", -"w c #17593D", -"e c #1C5B3E", -"r c #0C603F", -"t c #0B673F", -"y c #0C683B", -"u c #0B6642", -"i c #0B6940", -"p c #0C6941", -"a c #1A6144", -"s c #1C6445", -"d c #116D44", -"f c #1B6949", -"g c #137446", -"h c #147645", -"j c #137A4A", -"k c #157F4D", -"l c #207450", -"z c #2A7A51", -"x c #2A7F54", -"c c #0F804B", -"v c #128041", -"b c #148448", -"n c #13824F", -"m c #17884D", -"M c #139446", -"N c #16984F", -"B c #178851", -"V c #158C53", -"C c #168A55", -"Z c #198851", -"A c #1A9C5A", -"S c #1E9F59", -"D c #2E8D5F", -"F c #2C905E", -"G c #18AB4E", -"H c #1CB24B", -"J c #1DB54B", -"K c #1DB44D", -"L c #1DB74D", -"P c #1DB54E", -"I c #1DB64F", -"U c #1DB849", -"Y c #1EBA48", -"T c #1EBA4B", -"R c #1FBC4B", -"E c #1BAD54", -"W c #1CB150", -"Q c #1EB551", -"! c #1EB751", -"~ c #1EB652", -"^ c #1EB654", -"/ c #1EB950", -"( c #1FBB52", -") c #1FB854", -"_ c #1FB158", -"` c #1FB659", -"' c #20BC4D", -"] c #20BD4D", -"[ c #20BC4E", -"{ c #20A35C", -"} c #20BC51", -"| c #21BF51", -" . c #21BD52", -".. c #22BF52", -"X. c #20BA55", -"o. c #20B957", -"O. c #20BC55", -"+. c #21BE54", -"@. c #21BC56", -"#. c #20B75C", -"$. c #20B858", -"%. c #23BF5C", -"&. c #23BD5E", -"*. c #2E8E60", -"=. c #2E9161", -"-. c #299562", -";. c #319463", -":. c #349966", -">. c #369C67", -",. c #379C67", -"<. c #309B69", -"1. c #1FAD64", -"2. c #20A861", -"3. c #21AE62", -"4. c #2BAF64", -"5. c #34A06C", -"6. c #39A069", -"7. c #3AA169", -"8. c #3AA16A", -"9. c #3DA46B", -"0. c #3DA56B", -"q. c #23BD61", -"w. c #24BF64", -"e. c #45B877", -"r. c #40BA7B", -"t. c #42BC7C", -"y. c #23C059", -"u. c #24C358", -"i. c #24C35B", -"p. c #24C15E", -"a. c #25C45E", -"s. c #25C360", -"d. c #25C361", -"f. c #27C563", -"g. c #25C164", -"h. c #25C165", -"j. c #26C167", -"k. c #27C467", -"l. c #28C863", -"z. c #2DCC62", -"x. c #28C965", -"c. c #29CA67", -"v. c #26C368", -"b. c #27C369", -"n. c #27C36A", -"m. c #28C668", -"M. c #29C76A", -"N. c #29C66D", -"B. c #2AC86B", -"V. c #2BCD68", -"C. c #2BCD69", -"Z. c #2BCC6A", -"A. c #2CCD6B", -"S. c #2DCF6A", -"D. c #2BC96C", -"F. c #2DCD6E", -"G. c #2ECE6F", -"H. c #31C563", -"J. c #38C76E", -"K. c #2DD06B", -"L. c #2ED06D", -"P. c #2FD36E", -"I. c #32D46A", -"U. c #33D76A", -"Y. c #30D66F", -"T. c #2BC970", -"R. c #2FCF70", -"E. c #2FD271", -"W. c #32D771", -"Q. c #31D572", -"!. c #32D772", -"~. c #32D871", -"^. c #34DB73", -"/. c #38DC7C", -"(. c #3FEA7B", -"). c #3FE97E", -"_. c #47C27F", -"`. c #48C380", -"'. c #48CB86", -"]. c #4BCE87", -"[. c #51CF85", -"{. c #51D68B", -"}. c #43EE81", -"|. c #55E68D", -" X c #57E98E", -".X c #44F383", -"XX c #46F482", -"oX c #46F683", -"OX c #47F783", -"+X c #4AFD85", -"@X c #58E392", -"#X c #5AE392", -"$X c #5AE593", -"%X c #5DE693", -"&X c #5EED91", -"*X c #5CE995", -"=X c #5EE894", -"-X c #60ED97", -";X c #61ED97", -":X c #63EF97", -">X c #63EF98", -",X c #63F098", -"X9XeX2Xe.1 pXpXpXpXpXpXpXpXpXpXg j.m.x.j.w.- ", -"0.iX9X{.e pXpXpXpXpXpXpXpXpXpXpXpXpX: V d.l.d.o ", -"0.iX2Xr.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXu q.a.a.o ", -",.>XtX`.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXp a.p.` X ", -",.2XiX`.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXi i.%.` X ", -"0.eX2Xt.pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXt ` @.+.$ ", -"0.tXtX'.q pXpXpXpXpXpXpXpXpXpXpXpXpXpXk @.u.} $ ", -"0.2X2XwX*X5.pXpXpXpXpXpXpXpXpXpXpXy E @.L J J $ ", -"F tXiXwX8XiX@Xf pXpXpXpXpXpXpXpXN +. .~ ] R W $ ", -"v H.&XeX8X8X>X6.pXpXpXpXpXpXpX5 ^ ~ .J T z.).; ", -"b u. .J.@XwXiX7.pXpXpXpXpXpXpX4 / ] J _ (.+X.X; ", -"m x.&.o.:X>XtX7.pXpXpXpXpXpXpX4 L J H I.}..X.X; ", -"k M.V.f.8XiX:X=.pXpXpXpXpXpXpX2 G U Y U.+XOX/.* ", -"pXg n.Z.9X-Xx . pXpXpXpXpXpXpXpX< M T U..X4., pX", -"pXpX: Z :.= pXpXpXpXpXpXpXpXpXpXpXpX7 { 0 pXpXpX", -"pXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpXpX" -}; +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 ", +" "}; From 277e8b64443001d0adca0afa379f1fd6ba8c55cc Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 25 Nov 2018 15:42:14 +0000 Subject: [PATCH 06/79] Don't create MDI subwindow for VSTi without GUI --- plugins/vestige/vestige.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 0d985a108..0cfa31d21 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -109,6 +109,9 @@ public: void createUI( QWidget *parent ) override { Q_UNUSED(parent); + if ( !hasEditor() ) { + return; + } if ( embedMethod() != "none" ) { m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() )); VstPlugin::createUI( m_pluginSubWindow.get() ); From 3a94ed3f3fecbd23227401212d112b4cff773d31 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 25 Nov 2018 15:55:38 +0000 Subject: [PATCH 07/79] Fix occasional Sinnah hang --- include/InstrumentPlayHandle.h | 9 +-------- plugins/vst_base/RemoteVstPlugin.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h index 726859237..02d6fc69c 100644 --- a/include/InstrumentPlayHandle.h +++ b/include/InstrumentPlayHandle.h @@ -42,14 +42,7 @@ public: virtual void play( sampleFrame * _working_buffer ) { - // if the instrument is midi-based, we can safely render right away - if( m_instrument->flags() & Instrument::IsMidiBased ) - { - m_instrument->play( _working_buffer ); - return; - } - - // if not, we need to ensure that all our nph's have been processed first + // ensure that all our nph's have been processed first ConstNotePlayHandleList nphv = NotePlayHandle::nphsOfInstrumentTrack( m_instrument->instrumentTrack(), true ); bool nphsLeft; diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 4a41aea0c..e0fcb3ba6 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -63,6 +63,7 @@ #define USE_WS_PREFIX #include +#include #include #include #include @@ -900,6 +901,14 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out ) static char eventsBuffer[sizeof( VstEvents ) + sizeof( VstMidiEvent * ) * MIDI_EVENT_BUFFER_COUNT]; static VstMidiEvent vme[MIDI_EVENT_BUFFER_COUNT]; + // first sort events chronologically, since some plugins + // (e.g. Sinnah) can hang if they're out of order + std::stable_sort( m_midiEvents.begin(), m_midiEvents.end(), + []( const VstMidiEvent &a, const VstMidiEvent &b ) + { + return a.deltaFrames < b.deltaFrames; + } ); + VstEvents* events = (VstEvents *) eventsBuffer; events->reserved = 0; events->numEvents = m_midiEvents.size(); From 614bca7f04ce1ea35a50b0ac823b784907e4046a Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 25 Nov 2018 17:09:08 +0000 Subject: [PATCH 08/79] Make ppqPos in VST sync sample accurate --- include/VstSyncController.h | 4 ++-- include/VstSyncData.h | 2 +- plugins/vst_base/RemoteVstPlugin.cpp | 22 ++++++++++++++++------ src/core/Song.cpp | 21 ++++++++++++++------- src/core/VstSyncController.cpp | 6 +++--- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/include/VstSyncController.h b/include/VstSyncController.h index e858f5545..682291b9e 100644 --- a/include/VstSyncController.h +++ b/include/VstSyncController.h @@ -39,7 +39,7 @@ public: VstSyncController(); ~VstSyncController(); - void setAbsolutePosition( int ticks ); + void setAbsolutePosition( double ticks ); void setPlaybackState( bool enabled ) { @@ -77,7 +77,7 @@ private: struct VstSyncData { bool isPlaying; - float ppqPos; + double ppqPos; int timeSigNumer; int timeSigDenom; bool isCycle; diff --git a/include/VstSyncData.h b/include/VstSyncData.h index d8694f1b2..f9696252a 100644 --- a/include/VstSyncData.h +++ b/include/VstSyncData.h @@ -42,7 +42,7 @@ struct VstSyncData { bool isPlaying; - float ppqPos; + double ppqPos; int timeSigNumer; int timeSigDenom; bool isCycle; diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index e0fcb3ba6..fbffe4b34 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -395,8 +395,8 @@ private: // host to plugin synchronisation data structure struct in { - float lastppqPos; - float m_Timestamp; + double lastppqPos; + double m_Timestamp; int32_t m_lastFlags; } ; @@ -1605,10 +1605,20 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, } else if( __plugin->m_vstSyncData->isPlaying ) { - __plugin->m_in->lastppqPos += ( - __plugin->m_vstSyncData->hasSHM ? - __plugin->m_vstSyncData->m_bpm : - __plugin->m_bpm ) / (float)10340; + if( __plugin->m_vstSyncData->hasSHM ) + { + __plugin->m_in->lastppqPos += + __plugin->m_vstSyncData->m_bpm / 60.0 + * __plugin->m_vstSyncData->m_bufferSize + / __plugin->m_vstSyncData->m_sampleRate; + } + else + { + __plugin->m_in->lastppqPos += + __plugin->m_bpm / 60.0 + * __plugin->bufferSize() + / __plugin->sampleRate(); + } _timeInfo.ppqPos = __plugin->m_in->lastppqPos; } // _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos; diff --git a/src/core/Song.cpp b/src/core/Song.cpp index f715c8319..ba2659a6c 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -265,8 +265,6 @@ void Song::processNextBuffer() m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); - m_vstSyncController.setAbsolutePosition( - tl->loopBegin().getTicks() ); m_vstSyncController.setPlaybackJumped( true ); emit updateSampleTracks(); @@ -293,8 +291,6 @@ void Song::processNextBuffer() int ticks = m_playPos[m_playMode].getTicks() + ( int )( currentFrame / framesPerTick ); - m_vstSyncController.setAbsolutePosition( ticks ); - // did we play a whole tact? if( ticks >= MidiTime::ticksPerTact() ) { @@ -332,7 +328,6 @@ void Song::processNextBuffer() m_elapsedMilliSeconds = ( ticks * 60 * 1000 / 48 ) / getTempo(); - m_vstSyncController.setAbsolutePosition( ticks ); m_vstSyncController.setPlaybackJumped( true ); } } @@ -354,7 +349,6 @@ void Song::processNextBuffer() m_elapsedMilliSeconds = ( ticks * 60 * 1000 / 48 ) / getTempo(); - m_vstSyncController.setAbsolutePosition( ticks ); m_vstSyncController.setPlaybackJumped( true ); emit updateSampleTracks(); @@ -369,6 +363,16 @@ void Song::processNextBuffer() m_playPos[m_playMode].setCurrentFrame( currentFrame ); } + if( framesPlayed == 0 ) + { + // update VST sync position after we've corrected frame/ + // tick count but before actually playing any frames + m_vstSyncController.setAbsolutePosition( + m_playPos[m_playMode].getTicks() + + m_playPos[m_playMode].currentFrame() + / (double) framesPerTick ); + } + f_cnt_t framesToPlay = Engine::mixer()->framesPerPeriod() - framesPlayed; @@ -716,7 +720,10 @@ void Song::stop() m_playPos[m_playMode].setCurrentFrame( 0 ); m_vstSyncController.setPlaybackState( m_exporting ); - m_vstSyncController.setAbsolutePosition( m_playPos[m_playMode].getTicks() ); + m_vstSyncController.setAbsolutePosition( + m_playPos[m_playMode].getTicks() + + m_playPos[m_playMode].currentFrame() + / (double) Engine::framesPerTick() ); // remove all note-play-handles that are active Engine::mixer()->clear(); diff --git a/src/core/VstSyncController.cpp b/src/core/VstSyncController.cpp index b441d0507..dd9660cb5 100644 --- a/src/core/VstSyncController.cpp +++ b/src/core/VstSyncController.cpp @@ -136,12 +136,12 @@ VstSyncController::~VstSyncController() -void VstSyncController::setAbsolutePosition( int ticks ) +void VstSyncController::setAbsolutePosition( double ticks ) { #ifdef VST_SNC_LATENCY - m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ) - m_syncData->m_latency; + m_syncData->ppqPos = ( ( ticks + 0 ) / 48.0 ) - m_syncData->m_latency; #else - m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ); + m_syncData->ppqPos = ( ( ticks + 0 ) / 48.0 ); #endif } From 9c9290eeeba73ed4e8ad7ec56411056dde56fb33 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 2 Dec 2018 12:47:05 +0000 Subject: [PATCH 09/79] Support more than 62 simultaneous VST plugins for Qt<5.10 --- include/RemotePlugin.h | 11 ++++++++++- src/core/RemotePlugin.cpp | 25 +++++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 811827730..185e52840 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -755,9 +755,15 @@ public: } - void quit() + void stop() { m_quit = true; + quit(); + } + + void reset() + { + m_quit = false; } private: @@ -864,6 +870,9 @@ private: QProcess m_process; ProcessWatcher m_watcher; + QString m_exec; + QStringList m_args; + QMutex m_commMutex; bool m_splitChannels; #ifdef USE_QT_SHMEM diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index d0eafbfa3..d82bc61af 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -54,7 +54,10 @@ ProcessWatcher::ProcessWatcher( RemotePlugin * _p ) : void ProcessWatcher::run() { - while( !m_quit && m_plugin->isRunning() ) + m_plugin->m_process.start( m_plugin->m_exec, m_plugin->m_args ); + exec(); + m_plugin->m_process.moveToThread( m_plugin->thread() ); + while( !m_quit && m_plugin->messagesLeft() ) { msleep( 200 ); } @@ -120,6 +123,11 @@ RemotePlugin::RemotePlugin() : qWarning( "Unable to start the server." ); } #endif + connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), + this, SLOT( processFinished( int, QProcess::ExitStatus ) ), + Qt::DirectConnection ); + connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), + &m_watcher, SLOT( quit() ), Qt::DirectConnection ); } @@ -127,7 +135,7 @@ RemotePlugin::RemotePlugin() : RemotePlugin::~RemotePlugin() { - m_watcher.quit(); + m_watcher.stop(); m_watcher.wait(); if( m_failed == false ) @@ -200,6 +208,11 @@ bool RemotePlugin::init(const QString &pluginExecutable, return failed(); } + // ensure the watcher is ready in case we're running again + // (e.g. 32-bit VST plugins on Windows) + m_watcher.wait(); + m_watcher.reset(); + QStringList args; #ifdef SYNC_WITH_SHM_FIFO // swap in and out for bidirectional communication @@ -212,15 +225,15 @@ bool RemotePlugin::init(const QString &pluginExecutable, #ifndef DEBUG_REMOTE_PLUGIN m_process.setProcessChannelMode( QProcess::ForwardedChannels ); m_process.setWorkingDirectory( QCoreApplication::applicationDirPath() ); - m_process.start( exec, args ); + m_exec = exec; + m_args = args; + // we start the process on the watcher thread to work around QTBUG-8819 + m_process.moveToThread( &m_watcher ); m_watcher.start( QThread::LowestPriority ); #else qDebug() << exec << args; #endif - connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), - this, SLOT( processFinished( int, QProcess::ExitStatus ) ) ); - #ifndef SYNC_WITH_SHM_FIFO struct pollfd pollin; pollin.fd = m_server; From 698c39d38525c45d47c4b5a708747b7ff0a007cb Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Sun, 9 Dec 2018 11:19:15 +0100 Subject: [PATCH 10/79] Add Debian sid build pass (#4707) * Add Debian sid build pass * Update file locations and copyright * Use ccache * Redirect within sudo * Work around a pbuilder bug which breaks ccache * Debian: enable parallel builds * Travis: Debian: fix caching * Fix shellcheck warnings --- .travis.yml | 8 +- .travis/debian_pkgs.sha256 | 2 + .travis/linux..script.sh | 7 + .travis/linux.debian-sid.before_install.sh | 2 + .travis/linux.debian-sid.install.sh | 16 + .travis/linux.debian-sid.script.sh | 30 ++ .travis/linux.win32.script.sh | 4 + .travis/linux.win64.script.sh | 4 + .travis/osx..script.sh | 6 + cmake/modules/BashCompletion.cmake | 3 +- debian/copyright | 492 ++++++++++++++++++++- debian/lmms-bin.install | 6 - debian/lmms-common.install | 37 +- debian/rules | 2 +- 14 files changed, 574 insertions(+), 45 deletions(-) create mode 100644 .travis/debian_pkgs.sha256 create mode 100755 .travis/linux.debian-sid.before_install.sh create mode 100755 .travis/linux.debian-sid.install.sh create mode 100755 .travis/linux.debian-sid.script.sh diff --git a/.travis.yml b/.travis.yml index fa331f581..45fde455d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ cache: directories: - apt_mingw_cache - $HOME/.ccache + - $HOME/pbuilder-bases matrix: include: - env: TARGET_OS=win32 @@ -19,21 +20,20 @@ matrix: - os: osx osx_image: xcode8.2 env: QT5=True + - env: TARGET_OS=debian-sid before_install: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install.sh install: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.install.sh before_script: - - mkdir build && cd build - export CMAKE_FLAGS="-DWANT_QT5=$QT5 -DUSE_WERROR=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo" - if [ -z "$TRAVIS_TAG" ]; then export CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_CCACHE=ON"; fi script: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.script.sh - - make -j4 - - if [[ $TARGET_OS != win* ]]; then make tests && ./tests/tests; fi; after_script: - ccache -s -before_deploy: make package +before_deploy: + - if [ "$TRAVIS_OS" != debian-sid ]; then make package; fi deploy: provider: releases api_key: diff --git a/.travis/debian_pkgs.sha256 b/.travis/debian_pkgs.sha256 new file mode 100644 index 000000000..96a4bd8aa --- /dev/null +++ b/.travis/debian_pkgs.sha256 @@ -0,0 +1,2 @@ +314ef4af137903dfb13e8c3ef1e6ea56cfdb23808d52ec4f5f50e288c73610c5 pbuilder_0.229.1_all.deb +fa82aa8ed3055c6f6330104deedf080b26778295e589426d4c4dd0f2c2a5defa debootstrap_1.0.95_all.deb diff --git a/.travis/linux..script.sh b/.travis/linux..script.sh index d23c66ef9..a68620483 100644 --- a/.travis/linux..script.sh +++ b/.travis/linux..script.sh @@ -1,7 +1,14 @@ #!/usr/bin/env bash +mkdir build +cd build + if [ $QT5 ]; then unset QTDIR QT_PLUGIN_PATH LD_LIBRARY_PATH source /opt/qt59/bin/qt59-env.sh fi cmake -DUSE_WERROR=ON $CMAKE_FLAGS .. + +make -j4 +make tests +./tests/tests diff --git a/.travis/linux.debian-sid.before_install.sh b/.travis/linux.debian-sid.before_install.sh new file mode 100755 index 000000000..89ee51523 --- /dev/null +++ b/.travis/linux.debian-sid.before_install.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sudo apt-get update -qq diff --git a/.travis/linux.debian-sid.install.sh b/.travis/linux.debian-sid.install.sh new file mode 100755 index 000000000..ecdcf6d91 --- /dev/null +++ b/.travis/linux.debian-sid.install.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +sudo apt-get install -y \ + debian-archive-keyring \ + dpkg \ + pbuilder + +# work around a pbuilder bug which breaks ccache +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666525 +cd /tmp +wget http://archive.ubuntu.com/ubuntu/pool/main/p/pbuilder/pbuilder_0.229.1_all.deb +wget http://archive.ubuntu.com/ubuntu/pool/main/d/debootstrap/debootstrap_1.0.95_all.deb +sha256sum -c "$TRAVIS_BUILD_DIR/.travis/debian_pkgs.sha256" +sudo dpkg -i pbuilder_0.229.1_all.deb debootstrap_1.0.95_all.deb +cd "$OLDPWD" diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh new file mode 100755 index 000000000..54b47906b --- /dev/null +++ b/.travis/linux.debian-sid.script.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -e + +BASETGZ="$HOME/pbuilder-bases/debian-sid-amd64.tgz" +MIRROR=http://cdn-fastly.deb.debian.org/debian +KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg + +if [ -z "$TRAVIS_TAG" ] +then + sudo \ + sh -c "echo CCACHEDIR=$HOME/.ccache >> /etc/pbuilderrc" +fi + +if [ ! -e "$BASETGZ.stamp" ] +then + mkdir -p "$HOME/pbuilder-bases" + sudo pbuilder --create --basetgz "$BASETGZ" --mirror $MIRROR \ + --distribution sid --architecture amd64 \ + --debootstrapopts --variant=buildd \ + --debootstrapopts --keyring=$KEYRING \ + --debootstrapopts --include=perl + touch "$BASETGZ.stamp" +else + sudo pbuilder --update --basetgz "$BASETGZ" +fi + +DIR="$PWD" +cd .. +dpkg-source -b "$DIR" +env -i sudo pbuilder --build --debbuildopts "--jobs=auto" --basetgz "$BASETGZ" ./*.dsc diff --git a/.travis/linux.win32.script.sh b/.travis/linux.win32.script.sh index a8dcee77c..eb7cb9f7a 100644 --- a/.travis/linux.win32.script.sh +++ b/.travis/linux.win32.script.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash +mkdir build +cd build export CMAKE_OPTS="$CMAKE_FLAGS -DUSE_WERROR=ON" ../cmake/build_mingw32.sh + +make -j4 diff --git a/.travis/linux.win64.script.sh b/.travis/linux.win64.script.sh index 13339c830..fb62cb5b3 100644 --- a/.travis/linux.win64.script.sh +++ b/.travis/linux.win64.script.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash +mkdir build +cd build export CMAKE_OPTS="$CMAKE_FLAGS -DUSE_WERROR=ON" ../cmake/build_mingw64.sh + +make -j4 diff --git a/.travis/osx..script.sh b/.travis/osx..script.sh index 176bc2ffa..fb1473f79 100644 --- a/.travis/osx..script.sh +++ b/.travis/osx..script.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +mkdir build +cd build if [ $QT5 ]; then # Workaround; No FindQt5.cmake module exists @@ -6,3 +8,7 @@ if [ $QT5 ]; then fi cmake $CMAKE_FLAGS -DUSE_WERROR=OFF .. + +make -j4 +make tests +./tests/tests diff --git a/cmake/modules/BashCompletion.cmake b/cmake/modules/BashCompletion.cmake index 0dc016178..c3916f201 100644 --- a/cmake/modules/BashCompletion.cmake +++ b/cmake/modules/BashCompletion.cmake @@ -73,9 +73,10 @@ ELSE() FILE(WRITE ${BASHCOMP_SCRIPT} "\ #!${BASH}\n\ set -e\n\ -BASHCOMP_PKG_PATH=\"${BASHCOMP_USER_PATH}\"\n\ if [ -w \"${BASHCOMP_PKG_PATH}\" ]; then\n\ BASHCOMP_PKG_PATH=\"${BASHCOMP_PKG_PATH}\"\n\ +else \n\ + BASHCOMP_PKG_PATH=\"\$DESTDIR${BASHCOMP_USER_PATH}\"\n\ fi\n\ echo -e \"\\nInstalling bash completion...\\n\"\n\ mkdir -p \"\$BASHCOMP_PKG_PATH\"\n\ diff --git a/debian/copyright b/debian/copyright index 0b8729215..3fbf0917e 100644 --- a/debian/copyright +++ b/debian/copyright @@ -48,27 +48,49 @@ Copyright: Uroš Maravić License: GPL-2+ -Files: data/projects/CoolSongs/Alf42red-* - data/projects/CoolSongs/CapDan/CapDan-TwilightArea-* +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/CoolSongs/CapDan/CapDan-ZeroSumGame-* - data/projects/CoolSongs/Impulslogik-* - data/projects/CoolSongs/Momo64-* - data/projects/CoolSongs/Oglsdl-* - data/projects/CoolSongs/Settel-* - data/projects/CoolSongs/Socceroos-* - data/projects/CoolSongs/TameAnderson-* - data/projects/CoolSongs/Zakarra/* - data/projects/Demos/CapDan-* - data/projects/Demos/EsoXLB-* - data/projects/Demos/Oglsdl-* - data/projects/Demos/Thomasso-* - data/projects/Shorties/Greshz-* - data/projects/Shorties/Surrender-* +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) @@ -77,13 +99,17 @@ Copyright: 2010 Impulslogik 2011 Der Daniel (CapDan) 2011 Sam (socceroos) - 2011 Zakarra 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/CoolSongs/Saber-* Copyright: Saber Rastikerdar @@ -833,6 +859,435 @@ License: CC-BY-SA-3 . 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 @@ -913,3 +1368,6 @@ License: WOL 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 http://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/lmms-bin.install b/debian/lmms-bin.install index 58b8e9ecc..5d19a3103 100644 --- a/debian/lmms-bin.install +++ b/debian/lmms-bin.install @@ -5,9 +5,3 @@ usr/lib/*/lmms/ladspa/c[b-z]* usr/lib/*/lmms/ladspa/[d-z]* usr/lib/*/lmms/lib* usr/lib/*/lmms/RemoteZynAddSubFx -usr/share/man/* -usr/share/applications/* -data/application-x-lmms-project.svg usr/share/icons/hicolor/64x64/mimetypes - -data/lmms.png usr/share/icons/hicolor/512x512/apps -data/lmms.png usr/share/pixmaps diff --git a/debian/lmms-common.install b/debian/lmms-common.install index f2b7139a7..467ee8798 100644 --- a/debian/lmms-common.install +++ b/debian/lmms-common.install @@ -1,20 +1,25 @@ +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/CoolSongs/[A-C]* -usr/share/lmms/projects/CoolSongs/[I-M]* -usr/share/lmms/projects/CoolSongs/O* -usr/share/lmms/projects/CoolSongs/S[a-e]* -usr/share/lmms/projects/CoolSongs/So* -usr/share/lmms/projects/CoolSongs/Ta* -usr/share/lmms/projects/CoolSongs/To* -usr/share/lmms/projects/CoolSongs/Z* -usr/share/lmms/projects/Demos/An* -usr/share/lmms/projects/Demos/C* -usr/share/lmms/projects/Demos/[E-O]* -usr/share/lmms/projects/Demos/T* -usr/share/lmms/projects/Shorties/G* -usr/share/lmms/projects/Shorties/Su* -usr/share/lmms/projects/[a-z]* +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/mime/* +usr/share/man +usr/share/mime debian/lmms.xpm usr/share/pixmaps/ diff --git a/debian/rules b/debian/rules index 6a78a51ba..8413c88fc 100755 --- a/debian/rules +++ b/debian/rules @@ -28,7 +28,7 @@ export CXXFLAGS ?= $(shell dpkg-buildflags --get CXXFLAGS) -DNDEBUG \ -Wno-error=format-truncation %: - dh $@ --buildsystem cmake + dh $@ --buildsystem cmake --parallel override_dh_auto_configure: dh_auto_configure -- -DCMAKE_INSTALL_LIBDIR=lib/$(DEB_HOST_MULTIARCH) $(CMAKE_OPTS) From 642b5e7d0484f1b67e5310518afd92774dd54e4e Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Wed, 19 Dec 2018 12:45:33 +0100 Subject: [PATCH 11/79] Add Debian sid i386 build pass (#4727) --- .travis.yml | 1 + .travis/linux.debian-sid.script.sh | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45fde455d..bc1796f4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ matrix: osx_image: xcode8.2 env: QT5=True - env: TARGET_OS=debian-sid + - env: TARGET_OS=debian-sid TARGET_ARCH=i386 before_install: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install.sh install: diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh index 54b47906b..91e6d729a 100755 --- a/.travis/linux.debian-sid.script.sh +++ b/.travis/linux.debian-sid.script.sh @@ -1,7 +1,9 @@ #!/bin/sh set -e -BASETGZ="$HOME/pbuilder-bases/debian-sid-amd64.tgz" +: ${TARGET_ARCH:=amd64} + +BASETGZ="$HOME/pbuilder-bases/debian-sid-$TARGET_ARCH.tgz" MIRROR=http://cdn-fastly.deb.debian.org/debian KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg @@ -15,7 +17,7 @@ if [ ! -e "$BASETGZ.stamp" ] then mkdir -p "$HOME/pbuilder-bases" sudo pbuilder --create --basetgz "$BASETGZ" --mirror $MIRROR \ - --distribution sid --architecture amd64 \ + --distribution sid --architecture $TARGET_ARCH \ --debootstrapopts --variant=buildd \ --debootstrapopts --keyring=$KEYRING \ --debootstrapopts --include=perl From e1d9d899fdc06c24c3470600d361a137099df21a Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 22 Dec 2018 11:37:34 +0900 Subject: [PATCH 12/79] Fix lost control links in copied automation patterns (#4723) This hack should be removed once the automation system gets fixed. --- include/ProjectJournal.h | 1 + src/core/AutomationPattern.cpp | 10 ++++++++++ src/core/ProjectJournal.cpp | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h index a89c9725a..e0e738b70 100644 --- a/include/ProjectJournal.h +++ b/include/ProjectJournal.h @@ -77,6 +77,7 @@ public: } static jo_id_t idToSave( jo_id_t id ); + static jo_id_t idFromSave( jo_id_t id ); void clearJournal(); void stopAllJournalling(); diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 25da6defb..2ee41b5f2 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -787,6 +787,16 @@ void AutomationPattern::resolveAllIDs() { a->addObject( dynamic_cast( o ), false ); } + else + { + // FIXME: Remove this block once the automation system gets fixed + // This is a temporary fix for https://github.com/LMMS/lmms/issues/3781 + o = Engine::projectJournal()->journallingObject(ProjectJournal::idFromSave(*k)); + if( o && dynamic_cast( o ) ) + { + a->addObject( dynamic_cast( o ), false ); + } + } } a->m_idsToResolve.clear(); a->dataChanged(); diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp index 57646aeaa..ce811dbc5 100644 --- a/src/core/ProjectJournal.cpp +++ b/src/core/ProjectJournal.cpp @@ -164,6 +164,11 @@ jo_id_t ProjectJournal::idToSave( jo_id_t id ) return id & ~EO_ID_MSB; } +jo_id_t ProjectJournal::idFromSave( jo_id_t id ) +{ + return id | EO_ID_MSB; +} + From dd6d4a552b3e1c51fc39db7c0cfc19d3f33908ef Mon Sep 17 00:00:00 2001 From: xy124 Date: Fri, 21 Dec 2018 18:45:25 +0100 Subject: [PATCH 13/79] Fix broken FxLine tool tips (#3321) --- src/gui/FxMixerView.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index edeaceb54..5a26372f9 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -73,7 +73,7 @@ FxMixerView::FxMixerView() : // Set margins ml->setContentsMargins( 0, 4, 0, 0 ); - + // Channel area m_channelAreaWidget = new QWidget; chLayout = new QHBoxLayout( m_channelAreaWidget ); @@ -138,9 +138,9 @@ FxMixerView::FxMixerView() : ml->addWidget( newChannelBtn, 0, Qt::AlignTop ); - // add the stacked layout for the effect racks of fx channels + // add the stacked layout for the effect racks of fx channels ml->addWidget( m_racksWidget, 0, Qt::AlignTop | Qt::AlignRight ); - + setCurrentFxLine( m_fxChannelViews[0]->m_fxLine ); setLayout( ml ); @@ -219,10 +219,10 @@ void FxMixerView::refreshDisplay() chLayout->addWidget(m_fxChannelViews[i]->m_fxLine); m_racksLayout->addWidget( m_fxChannelViews[i]->m_rackView ); } - + // set selected fx line to 0 setCurrentFxLine( 0 ); - + // update all fx lines for( int i = 0; i < m_fxChannelViews.size(); ++i ) { @@ -308,7 +308,7 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, connect(&fxChannel->m_soloModel, SIGNAL( dataChanged() ), _mv, SLOT ( toggledSolo() ) ); ToolTip::add( m_soloBtn, tr( "Solo FX channel" ) ); - + // Create EffectRack for the channel m_rackView = new EffectRackView( &fxChannel->m_fxChain, _mv->m_racksWidget ); m_rackView->setFixedSize( 245, FxLine::FxLineHeight ); @@ -354,6 +354,8 @@ void FxMixerView::updateFxLine(int index) // does current channel send to this channel? int selIndex = m_currentFxLine->channelIndex(); FxLine * thisLine = m_fxChannelViews[index]->m_fxLine; + thisLine->setToolTip( Engine::fxMixer()->effectChannel( index )->m_name ); + FloatModel * sendModel = mix->channelSendModel(selIndex, index); if( sendModel == NULL ) { From 4d2e89bee2b9268b5fdec9e98e75695292d2391e Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Thu, 27 Dec 2018 20:15:42 +0100 Subject: [PATCH 14/79] Add Debian sid Clang build pass (#4735) --- .travis.yml | 2 ++ .travis/linux.debian-sid.script.sh | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bc1796f4a..28a49845f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ matrix: env: QT5=True - env: TARGET_OS=debian-sid - env: TARGET_OS=debian-sid TARGET_ARCH=i386 + - compiler: clang + env: TARGET_OS=debian-sid before_install: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install.sh install: diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh index 91e6d729a..7318ae5ac 100755 --- a/.travis/linux.debian-sid.script.sh +++ b/.travis/linux.debian-sid.script.sh @@ -13,6 +13,11 @@ then sh -c "echo CCACHEDIR=$HOME/.ccache >> /etc/pbuilderrc" fi +if [ "$CC" = clang ] +then + sudo sh -c "echo EXTRAPACKAGES=clang >> /etc/pbuilderrc" +fi + if [ ! -e "$BASETGZ.stamp" ] then mkdir -p "$HOME/pbuilder-bases" @@ -29,4 +34,5 @@ fi DIR="$PWD" cd .. dpkg-source -b "$DIR" -env -i sudo pbuilder --build --debbuildopts "--jobs=auto" --basetgz "$BASETGZ" ./*.dsc +env -i CC="$CC" CXX="$CXX" sudo pbuilder --build --debbuildopts "--jobs=auto" \ + --basetgz "$BASETGZ" ./*.dsc From aa0ce7fc545bbf2f63cb4df8853c1de474faba0d Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 28 Dec 2018 16:02:40 +0100 Subject: [PATCH 15/79] Improve CALF's CMakelists Let CALF's CMakelists apply the name filter only on the basenames of the files, but not on their directories. This prevents errors if the LMMS folder is under a directory which contains, e.g., "lv2". --- plugins/LadspaEffect/calf/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 776752bc5..4924169e4 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -16,8 +16,9 @@ LIST(SORT SOURCES) # Skip files matching pattern SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;preset;lv2;benchmark;win;plugin.cpp") FOREACH(_item ${SOURCES}) + GET_FILENAME_COMPONENT(m_basename ${_item} NAME) FOREACH(_pattern ${FILE_PATTERNS}) - IF(${_item} MATCHES ${_pattern}) + IF(${m_basename} MATCHES ${_pattern}) LIST(REMOVE_ITEM SOURCES ${_item}) ENDIF() ENDFOREACH() From a3ede058cdabb9254f50e69e5133fe5807036f39 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Mon, 31 Dec 2018 15:50:11 +0100 Subject: [PATCH 16/79] FX autoquit disabled by default (#4378) Really short notes doesn't work well with delay based effects with the default decay settings of the FX autoquit system where the effect can cut out. Set autoquit as disabled by default. Decay and Gate knobs are now also disabled when autoquit is disabled. --- src/gui/SetupDialog.cpp | 2 +- src/gui/widgets/EffectView.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 23266f153..f508da878 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -135,7 +135,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : m_displayWaveform(ConfigManager::inst()->value( "ui", "displaywaveform").toInt() ), m_disableAutoQuit(ConfigManager::inst()->value( "ui", - "disableautoquit").toInt() ), + "disableautoquit", "1" ).toInt() ), m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ) { setWindowIcon( embed::getIconPixmap( "setup_general" ) ); diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp index 6c74a459c..8258d6e16 100644 --- a/src/gui/widgets/EffectView.cpp +++ b/src/gui/widgets/EffectView.cpp @@ -75,7 +75,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : m_autoQuit = new TempoSyncKnob( knobBright_26, this ); m_autoQuit->setLabel( tr( "DECAY" ) ); m_autoQuit->move( 60, 5 ); - m_autoQuit->setEnabled( isEnabled ); + m_autoQuit->setEnabled( isEnabled && !effect()->m_autoQuitDisabled ); m_autoQuit->setHintText( tr( "Time:" ), "ms" ); m_autoQuit->setWhatsThis( tr( "The Decay knob controls how many buffers of silence must pass before the " @@ -86,7 +86,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : m_gate = new Knob( knobBright_26, this ); m_gate->setLabel( tr( "GATE" ) ); m_gate->move( 93, 5 ); - m_gate->setEnabled( isEnabled ); + m_gate->setEnabled( isEnabled && !effect()->m_autoQuitDisabled ); m_gate->setHintText( tr( "Gate:" ), "" ); m_gate->setWhatsThis( tr( "The Gate knob controls the signal level that is considered to be 'silence' " From 4c7ca3972cc4af975d1458224fdd9d8a9a6c5e1f Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Mon, 31 Dec 2018 15:50:57 +0100 Subject: [PATCH 17/79] Don't render Automation tracks in the Beat/Bassline (#4747) --- src/core/RenderManager.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/RenderManager.cpp b/src/core/RenderManager.cpp index e2058a136..478aa46e7 100644 --- a/src/core/RenderManager.cpp +++ b/src/core/RenderManager.cpp @@ -130,7 +130,7 @@ void RenderManager::renderTracks() Track* tk = (*it); Track::TrackTypes type = tk->type(); - // Don't mute automation tracks + // Don't render automation tracks if ( tk->isMuted() == false && ( type == Track::InstrumentTrack || type == Track::SampleTrack ) ) { @@ -142,7 +142,11 @@ void RenderManager::renderTracks() for( auto it = t2.begin(); it != t2.end(); ++it ) { Track* tk = (*it); - if ( tk->isMuted() == false ) + Track::TrackTypes type = tk->type(); + + // Don't render automation tracks + if ( tk->isMuted() == false && + ( type == Track::InstrumentTrack || type == Track::SampleTrack ) ) { m_unmuted.push_back(tk); } From ee05523319dbc137c1e39cae484590fd832ecc69 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Tue, 1 Jan 2019 20:58:16 +0100 Subject: [PATCH 18/79] Extend quoting for AutomatableModels This now also quotes, if required: - non automated models - models controlled by controller --- include/AutomatableModel.h | 2 ++ src/core/AutomatableModel.cpp | 44 +++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 8dbe80efd..78f4882b4 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -283,6 +283,8 @@ protected: private: + static bool mustQuoteName(const QString &name); + virtual void saveSettings( QDomDocument& doc, QDomElement& element ) { saveSettings( doc, element, "value" ); diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index cb8aa7046..62b783da4 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -89,16 +89,23 @@ bool AutomatableModel::isAutomated() const } + +bool AutomatableModel::mustQuoteName(const QString& name) +{ + QRegExp reg("^[A-Za-z0-9._-]+$"); + return !reg.exactMatch(name); +} + void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, const QString& name ) { + bool mustQuote = mustQuoteName(name); + if( isAutomated() || m_scaleType != Linear ) { // automation needs tuple of data (name, id, value) // scale type also needs an extra value // => it must be appended as a node - QRegExp reg("^[A-Za-z0-9._-]+$"); - bool mustQuote = !reg.exactMatch(name); QDomElement me = doc.createElement( mustQuote ? QString("automatablemodel") : name ); me.setAttribute( "id", ProjectJournal::idToSave( id() ) ); me.setAttribute( "value", m_value ); @@ -110,8 +117,18 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co } else { - // non automation, linear scale (default), can be saved as attribute - element.setAttribute( name, m_value ); + if(mustQuote) + { + QDomElement me = doc.createElement( "automatablemodel" ); + me.setAttribute( "nodename", name ); + me.setAttribute( "value", m_value ); + element.appendChild( me ); + } + else + { + // non automation, linear scale (default), can be saved as attribute + element.setAttribute( name, m_value ); + } } if( m_controllerConnection && m_controllerConnection->getController()->type() @@ -131,7 +148,13 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co element.appendChild( controllerElement ); } - QDomElement element = doc.createElement( name ); + bool mustQuote = mustQuoteName(name); + QString elementName = mustQuote ? "controllerconnection" + : name; + + QDomElement element = doc.createElement( elementName ); + if(mustQuote) + element.setAttribute( "nodename", name ); m_controllerConnection->saveSettings( doc, element ); controllerElement.appendChild( element ); @@ -170,6 +193,17 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString& if( connectionNode.isElement() ) { QDomNode thisConnection = connectionNode.toElement().namedItem( name ); + if( !thisConnection.isElement() ) + { + thisConnection = connectionNode.toElement().namedItem( "controllerconnection" ); + QDomElement tcElement = thisConnection.toElement(); + // sanity check + if( tcElement.isNull() || tcElement.attribute( "nodename" ) != name ) + { + // no, that wasn't it, act as if we never found one + thisConnection.clear(); + } + } if( thisConnection.isElement() ) { setControllerConnection( new ControllerConnection( (Controller*)NULL ) ); From 7f0593c601a7f48fda193139f2d6bb3d76f10384 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Thu, 3 Jan 2019 21:44:49 +0100 Subject: [PATCH 19/79] Add source build artifact (#4744) --- .travis.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 28a49845f..4ba2d59aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,12 +15,12 @@ matrix: osx_image: xcode8.2 - env: QT5= - env: QT5=True - - env: QT5=True TARGET_OS=win32 - - env: QT5=True TARGET_OS=win64 + - env: QT5=True TARGET_OS=win32 TARGET_DEPLOY=True + - env: QT5=True TARGET_OS=win64 TARGET_DEPLOY=True - os: osx osx_image: xcode8.2 env: QT5=True - - env: TARGET_OS=debian-sid + - env: TARGET_OS=debian-sid TARGET_DEPLOY=True - env: TARGET_OS=debian-sid TARGET_ARCH=i386 - compiler: clang env: TARGET_OS=debian-sid @@ -41,12 +41,15 @@ deploy: provider: releases api_key: secure: d4a+x4Gugpss7JK2DcHjyBZDmEFFh4iVfKDfITSD50T6Mc6At4LMgojvEu+6qT6IyOY2vm3UVT6fhyeuWDTRDwW9tfFlaHVA0h8aTRD+eAXOA7pQ8rEMwQO3+WCKuKTfEqUkpL4wxhww8dpkv54tqeIs0S4TBqz9tk8UhzU7XbE= - file: lmms-${TRAVIS_TAG:1}-$TARGET_OS.exe + file_glob: true + file: + - lmms-${TRAVIS_TAG:1}-$TARGET_OS.exe + - /var/cache/pbuilder/result/lmms_*.tar.xz skip_cleanup: true on: tags: true all_branches: true - condition: '("$TARGET_OS" = win??) && "$QT5"' + condition: '"$TARGET_DEPLOY" = True' repo: LMMS/lmms notifications: webhooks: From 2ee02d97cba4ce9275ff0e830236ea7f3d68fbf3 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 6 Jan 2019 19:21:35 +0900 Subject: [PATCH 20/79] Keep off-grid position of TCOs on group moving (#4262) --- src/core/Track.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index bf10a10a0..b300d94a3 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -865,10 +865,18 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) else if( m_action == MoveSelection ) { const int dx = me->x() - m_initialMousePos.x(); + const bool snap = !(me->modifiers() & Qt::AltModifier) && + me->button() == Qt::NoButton; QVector so = m_trackView->trackContainerView()->selectedObjects(); QVector tcos; - MidiTime smallest_pos, t; + int smallestPos = 0; + MidiTime dtick = MidiTime( static_cast( dx * + MidiTime::ticksPerTact() / ppt ) ); + if( snap ) + { + dtick = dtick.toNearestTact(); + } // find out smallest position of all selected objects for not // moving an object before zero for( QVector::iterator it = so.begin(); @@ -882,23 +890,18 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) } TrackContentObject * tco = tcov->m_tco; tcos.push_back( tco ); - smallest_pos = qMin( smallest_pos, - (int)tco->startPosition() + - static_cast( dx * - MidiTime::ticksPerTact() / ppt ) ); + smallestPos = qMin( smallestPos, + (int)tco->startPosition() + dtick ); + } + dtick -= smallestPos; + if( snap ) + { + dtick = dtick.toAbsoluteTact(); // round toward 0 } for( QVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { - t = ( *it )->startPosition() + - static_cast( dx *MidiTime::ticksPerTact() / - ppt )-smallest_pos; - if( ! ( me->modifiers() & Qt::AltModifier ) - && me->button() == Qt::NoButton ) - { - t = t.toNearestTact(); - } - ( *it )->movePosition( t ); + ( *it )->movePosition( ( *it )->startPosition() + dtick ); } } else if( m_action == Resize ) From a0ace860f4c7feee08607e52bc8f0b48df09dcd5 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 7 Jan 2019 01:27:58 +0100 Subject: [PATCH 21/79] MSVC: Fix SID (#4505) Use the provided working buffer instead of a local one to avoid use of VLA --- plugins/CMakeLists.txt | 2 -- plugins/sid/sid_instrument.cpp | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b4a1081f6..4f139f8b3 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -91,8 +91,6 @@ ENDIF("${PLUGIN_LIST}" STREQUAL "") IF(MSVC) SET(MSVC_INCOMPATIBLE_PLUGINS LadspaEffect - sid - #VstEffect zynaddsubfx ) message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}") diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index 2eb46be56..e671d4f05 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -324,7 +324,8 @@ void sidInstrument::playNote( NotePlayHandle * _n, cSID *sid = static_cast( _n->m_pluginData ); int delta_t = clockrate * frames / samplerate + 4; - short buf[frames]; + // avoid variable length array for msvc compat + short* buf = reinterpret_cast(_working_buffer + offset); unsigned char sidreg[NUMSIDREGS]; for (int c = 0; c < NUMSIDREGS; c++) @@ -429,7 +430,8 @@ void sidInstrument::playNote( NotePlayHandle * _n, if(num!=frames) printf("!!!Not enough samples\n"); - for( fpp_t frame = 0; frame < frames; ++frame ) + // loop backwards to avoid overwriting data in the short-to-float conversion + for( fpp_t frame = frames - 1; frame >= 0; frame-- ) { sample_t s = float(buf[frame])/32768.0; for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) From c467f5b08a01fa5b070fe93c61f5ae66e05e1d1d Mon Sep 17 00:00:00 2001 From: Pavel Shlyak Date: Mon, 7 Jan 2019 06:30:27 +0400 Subject: [PATCH 22/79] Corrected assignment (#4757) There is no need in conversion from float to integer --- src/gui/editors/PianoRoll.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index e5f6458b5..954dde5b0 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3269,7 +3269,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) } if( nv.size() > 0 ) { - const int step = we->delta() > 0 ? 1.0 : -1.0; + const int step = we->delta() > 0 ? 1 : -1; if( m_noteEditMode == NoteEditVolume ) { for ( Note * n : nv ) From e116cc07015d12972ce3f41db26d4fe18dab4e55 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 10 Jan 2019 15:13:30 +0900 Subject: [PATCH 23/79] Allow console output on Windows if available (#4719) --- src/core/main.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/core/main.cpp b/src/core/main.cpp index 0289f0c53..c51be6f97 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -105,6 +105,21 @@ static inline QString baseName( const QString & file ) } +#ifdef LMMS_BUILD_WIN32 +// Workaround for old MinGW +#ifdef __MINGW32__ +extern "C" _CRTIMP errno_t __cdecl freopen_s(FILE** _File, + const char *_Filename, const char *_Mode, FILE *_Stream); +#endif + +// For qInstallMessageHandler +void consoleMessageHandler(QtMsgType type, + const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + fprintf(stderr, "%s\n", localMsg.constData()); +} +#endif inline void loadTranslation( const QString & tname, @@ -243,6 +258,33 @@ int main( int argc, char * * argv ) signal(SIGFPE, signalHandler); #endif +#ifdef LMMS_BUILD_WIN32 + // Don't touch redirected streams here + // GetStdHandle should be called before AttachConsole + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE); + FILE *fIn, *fOut, *fErr; + // Enable console output if available + if (AttachConsole(ATTACH_PARENT_PROCESS)) + { + if (!hStdIn) + { + freopen_s(&fIn, "CONIN$", "r", stdin); + } + if (!hStdOut) + { + freopen_s(&fOut, "CONOUT$", "w", stdout); + } + if (!hStdErr) + { + freopen_s(&fErr, "CONOUT$", "w", stderr); + } + } + // Make Qt's debug message handlers work + qInstallMessageHandler(consoleMessageHandler); +#endif + // initialize memory managers NotePlayHandleManager::init(); @@ -930,5 +972,15 @@ int main( int argc, char * * argv ) printf( "\n" ); } +#ifdef LMMS_BUILD_WIN32 + // Cleanup console + HWND hConsole = GetConsoleWindow(); + if (hConsole) + { + SendMessage(hConsole, WM_CHAR, (WPARAM)VK_RETURN, (LPARAM)0); + FreeConsole(); + } +#endif + return ret; } From e2de0ece8c5784cfdf9b99e6583ca85a2730407a Mon Sep 17 00:00:00 2001 From: T0NIT0 RMX Date: Thu, 10 Jan 2019 20:00:40 +0100 Subject: [PATCH 24/79] Fix infinite MIDI note with VST made in Cabbage (LMMS#4380) (#4766) --- src/core/NotePlayHandle.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 9dd29fe32..596e17a71 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -180,11 +180,6 @@ void NotePlayHandle::setVolume( volume_t _volume ) void NotePlayHandle::setPanning( panning_t panning ) { Note::setPanning( panning ); - - MidiEvent event( MidiMetaEvent, midiChannel(), midiKey(), panningToMidi( panning ) ); - event.setMetaEvent( MidiNotePanning ); - - m_instrumentTrack->processOutEvent( event ); } From f382e5e36f6e8c1c55bed9f3d6957141250a7ee0 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Thu, 10 Jan 2019 23:43:00 -0500 Subject: [PATCH 25/79] Fix builds on macOS Mojave 10.14 (#4767) --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e42c48456..a563d05a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,8 @@ OPTION(WANT_QT5 "Build with Qt5" OFF) IF(LMMS_BUILD_APPLE) + # Fix linking on 10.14+. See issue #4762 on github + LINK_DIRECTORIES(/usr/local/lib) SET(WANT_ALSA OFF) SET(WANT_PULSEAUDIO OFF) SET(WANT_VST OFF) From d9f5e8a6df1c396b6f5391ebd285b15b12f3e1e8 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 7 Jan 2019 13:09:11 -0500 Subject: [PATCH 26/79] Fix left 1px lfo graph Closes #4597, supersedes #4613 --- src/gui/widgets/EnvelopeAndLfoView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/EnvelopeAndLfoView.cpp b/src/gui/widgets/EnvelopeAndLfoView.cpp index 4131a956e..ce23947dc 100644 --- a/src/gui/widgets/EnvelopeAndLfoView.cpp +++ b/src/gui/widgets/EnvelopeAndLfoView.cpp @@ -491,9 +491,9 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) p.fillRect( x5, y_base - 1, 2, 2, end_points_color ); - int LFO_GRAPH_W = s_lfoGraph->width() - 6; // substract border + int LFO_GRAPH_W = s_lfoGraph->width() - 3; // substract border int LFO_GRAPH_H = s_lfoGraph->height() - 6; // substract border - int graph_x_base = LFO_GRAPH_X + 3; + int graph_x_base = LFO_GRAPH_X + 2; int graph_y_base = LFO_GRAPH_Y + 3 + LFO_GRAPH_H / 2; const float frames_for_graph = SECS_PER_LFO_OSCILLATION * From 68cefc15c40d2e896759a7aab630c6afaabf60e2 Mon Sep 17 00:00:00 2001 From: bth Date: Sun, 13 Jan 2019 10:31:39 +0100 Subject: [PATCH 27/79] Set 32 for buffersize min value in gui (#4336) This is a bit too low resolution as some values cannot be reached by dragging the slider so we also reduce the maximum buffer size to 4096. --- src/gui/SetupDialog.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 678f5bff9..5f7971251 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -66,6 +66,8 @@ #include "MidiApple.h" #include "MidiDummy.h" +constexpr int BUFFERSIZE_RESOLUTION = 32; + inline void labelWidget( QWidget * _w, const QString & _txt ) { QLabel * title = new QLabel( _txt, _w ); @@ -176,12 +178,12 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : bufsize_tw->setFixedHeight( 80 ); m_bufSizeSlider = new QSlider( Qt::Horizontal, bufsize_tw ); - m_bufSizeSlider->setRange( 1, 256 ); + m_bufSizeSlider->setRange( 1, 128 ); m_bufSizeSlider->setTickPosition( QSlider::TicksBelow ); m_bufSizeSlider->setPageStep( 8 ); m_bufSizeSlider->setTickInterval( 8 ); m_bufSizeSlider->setGeometry( 10, 16, 340, 18 ); - m_bufSizeSlider->setValue( m_bufferSize / 64 ); + m_bufSizeSlider->setValue( m_bufferSize / BUFFERSIZE_RESOLUTION ); connect( m_bufSizeSlider, SIGNAL( valueChanged( int ) ), this, SLOT( setBufferSize( int ) ) ); @@ -877,7 +879,7 @@ void SetupDialog::accept() void SetupDialog::setBufferSize( int _value ) { - const int step = DEFAULT_BUFFER_SIZE / 64; + const int step = DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION; if( _value > step && _value % step ) { int mod_value = _value % step; @@ -897,7 +899,7 @@ void SetupDialog::setBufferSize( int _value ) m_bufSizeSlider->setValue( _value ); } - m_bufferSize = _value * 64; + m_bufferSize = _value * BUFFERSIZE_RESOLUTION; m_bufSizeLbl->setText( tr( "Frames: %1\nLatency: %2 ms" ).arg( m_bufferSize ).arg( 1000.0f * m_bufferSize / @@ -910,7 +912,7 @@ void SetupDialog::setBufferSize( int _value ) void SetupDialog::resetBufSize() { - setBufferSize( DEFAULT_BUFFER_SIZE / 64 ); + setBufferSize( DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION ); } From e074841d44b7520cfebdf7b42fd41bdbda071bb1 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Mon, 14 Jan 2019 09:47:34 +0100 Subject: [PATCH 28/79] Fix before_deploy (#4764) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4ba2d59aa..c48186fa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ script: after_script: - ccache -s before_deploy: - - if [ "$TRAVIS_OS" != debian-sid ]; then make package; fi + - if [ "$TARGET_OS" != debian-sid ]; then make package; fi deploy: provider: releases api_key: From 8dea34e1b8e7861b72db81f8f06f782792f65fd8 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Wed, 16 Jan 2019 03:08:14 +0100 Subject: [PATCH 29/79] Do not depend on Git history, use data from 2019-01-07 (#4763) --- CMakeLists.txt | 2 +- debian/rules | 3 +- doc/CONTRIBUTORS | 185 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 doc/CONTRIBUTORS diff --git a/CMakeLists.txt b/CMakeLists.txt index a563d05a1..c25e0aec8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ INCLUDE(FindPkgConfig) STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE) -SET(PROJECT_YEAR 2018) +SET(PROJECT_YEAR 2019) SET(PROJECT_AUTHOR "LMMS Developers") SET(PROJECT_URL "https://lmms.io") diff --git a/debian/rules b/debian/rules index 8413c88fc..5e8345845 100755 --- a/debian/rules +++ b/debian/rules @@ -7,7 +7,8 @@ DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) -CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DWANT_QT5=1 +CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DFORCE_VERSION=internal \ + -DWANT_QT5=1 ifneq ($(DEB_HOST_ARCH_OS),linux) CMAKE_OPTS+= -DWANT_ALSA=0 endif diff --git a/doc/CONTRIBUTORS b/doc/CONTRIBUTORS new file mode 100644 index 000000000..4a791028f --- /dev/null +++ b/doc/CONTRIBUTORS @@ -0,0 +1,185 @@ +Tobias Junghans +Vesa +Tres Finocchiaro +Lukas W +Javier Serrano Polo +Paul Giblock +Dave French +Colin Wallace +Oskar Wallgren +Raine M. Ekman +Umcaruje +Michael Gregorius +Javier Serrano Polo +grejppi +Javier Serrano Polo +Hyunjin Song +Wong Cho Ching +Alexandre Almeida +Daniel Winzen +LMMS Service Account +Steffen Baranowsky +Danny McRae +Garrett +Hyunin Song +liushuyu +Andrew Kelley +Andreas Brandmaier +Fastigium +Spekular +Amadeus Folego +Jonas Trappenberg +M374LX +DomClark +grindhold +Mike Choi +Karmo Rosental +Christopher L. Simons +Dominic Clark +NoiseByNorthwest +falkTX +Johannes Lorenz +Rebecca DeField +Stian Jørgensrud +Ryan Roden-Corrent +midi-pascal +Augustin Cavalier +BaraMGB +Csaba Hruska +David Carlier +DeRobyJ +Hussam Eddin Alhomsi +Rüdiger Ranft +StakeoutPunch +ma2moto +mikobuntu +8tab <8tab@wp.pl> +Andrés +Matthew Krafczyk +mohamed +Alexandre +RebeccaDeField +Yann Collette +Aya Morisawa +Ben Bryan +Jonathan Aquilina +Mohammad Amin Sameti +ra +wongcc966422 +David CARLIER +Gurjot Singh +Janne Sinisalo +Krzysztof Foltman +Lou Herard +Paul Batchelor +Paul Wayper +Petter Reinholdtsen +TonyChyi +dnl-music +follower +midi-pascal +unfa +Andres +Arnout Engelen +Chris Aiken +Cyrille Bollu +Dan Williams +Ian Sannar +Jaroslav Petrnoušek +Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> +Johannes Lorenz +Kenneth Perry (thothonegan) +LYF610400210 +Lukas W +Mark-Agent003 +NeiroNext +Orbital Ink <31394502+Anonymouqs@users.noreply.github.com> +P THE AWESOME +Ra +Rafael Ruggiero +Rebecca LaVie +Roberto Giaconia +SecondFlight +Steffen Baranowsky +TheTravelingSpaceman +Thomas Clark +gnudles +liushuyu +miketurn +psyomn +quadro +sarahkeefe +Achim Settelmeier +André Hentschel +Armin Kazmi +Attila Herman +Bastian Kummer +Christopher A. Oliver +Devin Venable +Diego Ramos Ruggeri +Douglas <34612565+DouglasDGI@users.noreply.github.com> +DragonEagle +Filip Hron +Frank Mather +Frederik +Greg Simpson +Hexasoft +IvanMaldonado +Ivo Wetzel +Jens Lang +Jesse Dubay +Joel Muzzerall +Joshua Wade +Jousboxx +Jérôme Duval +Karmo Rosental +Kristi +Lee Avital +LocoMatt +Léo Andrès +Markus Elfring +Maurizio Lo Bosco +Mehdi +Mikobuntu +Mingcong Bai +Nikos Chantziaras +Noah Brecht +Ododo +Olivier Humbert +Paul Nasca +Peter Nelson +Ra +Ryan Schmidt +Shane Ambler +Simon Jackson (Netbook) +Simon van der Veldt +Stephen Seo +Steve Leonard +The Gitter Badger +Thorsten Müller +Tobias Junghans +Tobias Kortkamp +Tyler Ganter +Uroš Šišović +Wiley Yu +anonymous +devin +fholmer +flynn16 +follower +fundamental +gandalf3 +groboclown +irrenhaus3 +jasp00 +justnope +kamnxt +lmmsservice +m-xbutterfly +noahb01 +projectpitchin +rgwan +xhe +xy124 +z-up +zm1990s From 1404b723b59f3b19772c437fc222f5d1bd497b37 Mon Sep 17 00:00:00 2001 From: Douglas <34612565+DouglasDGI@users.noreply.github.com> Date: Wed, 16 Jan 2019 12:59:40 -0700 Subject: [PATCH 30/79] Initialize peak controller last sample with base value fix (Stable 1.2) (#4699) --- plugins/peak_controller_effect/peak_controller_effect.cpp | 2 +- .../peak_controller_effect/peak_controller_effect_controls.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index 87f6cc600..d4d81b137 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect.cpp @@ -64,7 +64,7 @@ PeakControllerEffect::PeakControllerEffect( Effect( &peakcontrollereffect_plugin_descriptor, _parent, _key ), m_effectId( rand() ), m_peakControls( this ), - m_lastSample( m_peakControls.m_baseModel.value() ), //sets the value to the Peak Controller's Base value (rather than 0 like in previous versions) + m_lastSample( 0 ), m_autoController( NULL ) { m_autoController = new PeakController( Engine::getSong(), this ); diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp index 3508f869a..056066113 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp @@ -53,6 +53,7 @@ PeakControllerEffectControls( PeakControllerEffect * _eff ) : void PeakControllerEffectControls::loadSettings( const QDomElement & _this ) { m_baseModel.loadSettings( _this, "base" ); + m_effect->m_lastSample = m_baseModel.value(); //Set initial Peak Controller output to Base m_amountModel.loadSettings( _this, "amount" ); m_muteModel.loadSettings( _this, "mute" ); From 5126070bb1494d81f9efc9188594a80b6574a466 Mon Sep 17 00:00:00 2001 From: "https://gitlab.com/users/CYBERDEViLNL" <1148379+CYBERDEViLNL@users.noreply.github.com> Date: Thu, 17 Jan 2019 19:07:52 +0100 Subject: [PATCH 31/79] Add basic ghost notes feature. (#4575) Lets you set a melody pattern as visible in the background of the Piano Roll as support when building a new pattern. The pattern is visible throughout the session or until cleared via the provided button. --- data/themes/classic/clear_ghost_note.png | Bin 0 -> 1088 bytes data/themes/classic/ghost_note.png | Bin 0 -> 452 bytes data/themes/classic/style.css | 4 + data/themes/default/clear_ghost_note.png | Bin 0 -> 1088 bytes data/themes/default/ghost_note.png | Bin 0 -> 3915 bytes data/themes/default/style.css | 4 + include/Pattern.h | 1 + include/PianoRoll.h | 26 ++++- src/gui/editors/PianoRoll.cpp | 121 ++++++++++++++++++++++- src/tracks/Pattern.cpp | 29 +++++- 10 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 data/themes/classic/clear_ghost_note.png create mode 100644 data/themes/classic/ghost_note.png create mode 100644 data/themes/default/clear_ghost_note.png create mode 100644 data/themes/default/ghost_note.png diff --git a/data/themes/classic/clear_ghost_note.png b/data/themes/classic/clear_ghost_note.png new file mode 100644 index 0000000000000000000000000000000000000000..c9f85a2b4ab54a5b206823b56116d87a6936d8d7 GIT binary patch literal 1088 zcmV-G1i$-3$EDcV9eqd5WEs3QhATg7e zc0n;HX;{@=1r}{+L!Gjz57bm5h1jGiNt+Ud5H`>zf+kvH7h)rADUueNG8qs=s1}@z z<1o(0J6$l7j8nn(zqz^Zob!9YD9yShY&g@3_2!J@-Ye@#xta)ToBu83ra zNVAAU5?FUd%TV9sqDJi1ESZpjBfEPY^Zujoja(3;Cy{la*^_5b}tCZ>hdgJ=| zP$`uIqyc}dx?FUZln@C90ZM@;0Mn#V0 z%Bsr+z_Ud~f8U#)7Qm@Pw-$sNz*baSI~@noMZ^psA~xW?=yOd(>e^r*FtO@#Rj8yS z_8mJ${lvsL@Ht=uYD@yvz*>HJ`JFg$KHwFRWgr(Y#R4-IF7%0}C1Dt9OF;pL`ufP< zyB9!!e&9IpmImwuelc0C;e_KS19>s15e_rl*hqg>l}QXk71!0#FfkE>t{-!KgiF9q zQ?#RTHj#I6k)Fy*JhQW;q^I*nM+bY39N8%SRtzi~5=EHo>*L$QhXL4DT1styKUsx^ zoAm)8rfBO0z-)XZ=<_jf-~h8%uc9=Kilawyw6&onCqE6k4Y*?heg_h0wPhvR8L^mS++Fr+Cs57_2MN9_`caH+YOugl5^`Te|d@F0yh zZ~iA}R5gH7a9%}!5ciAw_eVT#clLd^n`En%H#U}@>>_fF@-$===^U(hxNG85){u z=mSVweSwCCYH)6}1`!(q8;aJ#QCu8)(UKxauHGdwqG zfCaq7CVrG}6ECpP_SeQqymdO(aiuj+V`l(!A3M0-H;>@U5avEU<9zU-5IsD^n4@vt zG=@)D#bL$W58jtzr5Wo24vO}y;uoucjbN`7&zpb_z7=i0(S8tMPxpU;%&rHDGy|fbI#} zyCiF;_&)~UF@@b``)=a~ewTWy(zeT3$EDcV9eqd5WEs3QhATg7e zc0n;HX;{@=1r}{+L!Gjz57bm5h1jGiNt+Ud5H`>zf+kvH7h)rADUueNG8qs=s1}@z z<1o(0J6$l7j8nn(zqz^Zob!9YD9yShY&g@3_2!J@-Ye@#xta)ToBu83ra zNVAAU5?FUd%TV9sqDJi1ESZpjBfEPY^Zujoja(3;Cy{la*^_5b}tCZ>hdgJ=| zP$`uIqyc}dx?FUZln@C90ZM@;0Mn#V0 z%Bsr+z_Ud~f8U#)7Qm@Pw-$sNz*baSI~@noMZ^psA~xW?=yOd(>e^r*FtO@#Rj8yS z_8mJ${lvsL@Ht=uYD@yvz*>HJ`JFg$KHwFRWgr(Y#R4-IF7%0}C1Dt9OF;pL`ufP< zyB9!!e&9IpmImwuelc0C;e_KS19>s15e_rl*hqg>l}QXk71!0#FfkE>t{-!KgiF9q zQ?#RTHj#I6k)Fy*JhQW;q^I*nM+bY39N8%SRtzi~5=EHo>*L$QhXL4DT1styKUsx^ zoAm)8rfBO0z-)XZ=<_jf-~h8%uc9=Kilawyw6&onCqE6k4Y*?heg_h0wPhvR8L^mS++Fr+Cs57_2MN9_`caH+YOugl5^`Te|d@F0yh zZ~iA}R5gH7a9%}!5ciAw_eVT#clLd^n`En%H#U}@>>_fF@-$===^U zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=QFawI#lME|jhSprl*EC9zkhG@FMeVv#YD*^)s!qhvBv5fUy8kcuA{T@{Js83_cizN zym`CeITbjD>)*8Q`y1!w{ec|s^Zny_lgB+yxd*y0JO&Ipv**iwU%3Yg{yOjO|4qH0 zYw>A2kKb_?ud`o2pZ<>-Fs3kG@W!v;g5_`0Spq8vB{Yup{0({&pT>FNZ`AuB|QaN57E#hrQUnQyql%+qnFcMRr^9Y1}{tCRnq z&)YzIkAtu+Z&S)u?FmeBxW;V0TI@@v!Dy_I=rIlA%b+rxGcGz*tPCM_i>uzsWyRG`sYVMQe zes48*TTLw%&wcsbYMjpbF@#e&5w#f>^U-1PtQLUKUTtQJi_xp))MmDNoI*TSbE3wX zPA!H7<8ofMd$ZlU<$h~7Bk@Oe^IuucsOkP2mNRO)+j76!?S<85J3$~E1F07(rZ#MZ zjT=^JzBG+VzaIN6VYq+?Ac|OETXwdvB2U`tR4mt&Wl~-&WQ3K{oE@{|xpuHAhn~X> zeG(JPo=(9ZLN^=9r={p`8+o^u*=72$|->M}CKjP{^> zpgJ&rhQk~@+}9u~)>a1?jJpWt0R_6&IS%+a`Iqb{%d zl9vP1ZreQ2t}>-5X%}*^UCEdl$H5xQ0yXqxzSZD-M4wHrz(4#Xyn_1zf4r-e4MRY5 zyUNyb2&3T4aYI;J!Y(ss7e&)7xsOIZo%r4{AC9}c2JR?~EC!FpV~fB@v_gEYu6swU z!S)?6)Wv)*gDejS`?m-JH>5E1k~E2CN#N7T3zr1zqWW?N81AJ zCC!Aiif_)b^PDxwSu&8R*mlh7A`8gyhsdp{p2VIfQ5D@>1E~w_j4^8SzUhvL=tKeJ zc9ad>4{;Ji-qnC^Q`A^Yyd0Ao5Rjjm(tO9(RaTp-Qs4*MddRaibi2VlBq{goypa(L z@o8$ZGuDto5K@z~J}kRK*`(}=)Cb|URa!X^t@NbhX25#va?G;*=mNO`nk zBCrLE+>*+aYo7|#FTN&=b@d3F59f|im32<722yXV`whd*gW~^`;pQ>f4;Y>+gAw-6 z+G1#Dl?D>Cff|wB?JcA}gE|0(7k25@bj5qznn*ax2m9j$`$R@_?f4FjB6nyclZ3in zBZ8XQU+8T+b*;YXZ1HmZc(2pEFF2?fugwuZ4kC;^4+!afTv&XK>ih+_Z<+|QBAgSC zjAy0Dc8P1_4pE~lNpL2WVCbAkZCjC!QG>=~giAwHS=3)-0?w=o%P+g+EAvsh5>fV( zcdHp-YwutmP>|3^%nhcuo@&r6rkL(xU65uv*+QII$R)+i^V%KOekE)xHa=DK=1vGYl#m9ske>wp*$!1 z)3%Fdf5l{3>kyFKb-`KEH~39TN91c%Qv+5q-k8Mv#+J!iU}mq3v;4`Q!)olu9NZoF zjZ3(qgZUWyEPGyZ*8rNF_O}jW@E8(lE(MLwP;eD5YL3gh`z81|r_)?@25KL7asbqh z@|Axg*>w_QXCGxc=o`Do{XO-iJ!y+N4FTY@Fx@VBJG(mNaY^&RC-FY#SM4G7upFUf zM;s=RBIQnIKt4$JUr)oLl0FvovMb+khA=iYjC~KKjDNuhlz)XrU4`EbmO7?2B-NG4 zt~}FKnQ^p6?yr&BIat-F`^H4wXn>cKL}B$n(%56s91^~OT(ezkQ4-vUVx$@ga538v zi7^RrwiLz+T$f}12W2&A-;})x%e6R(uw|+{)QYa(S-GQ{C$Qy2oQlZ@@*|`nF2_89 z4QhEHpIr7^x?uhk)4r<<=4)a2nJyUnr`f)FG(W}SD=5rQvG@uK^HVIov$dZdKR{uA z9xq-)VSXMjUPEDiip4*{=&y_Xb&Z5$XZ;Asrb>f?(e0# z6c~Y&MZBgg)sj)Vbu#lM*9@A5PB$M}3pI0Rc~`kkGKl#rRd*uglS=8`$+lB%OG+d= zBaf#l-{kPCkyy^QM#ZB$#sSfXI~EUnR>sT@n@u-b$JmT}1P$z4+%YmW(NV zg|#0I!)-bVaDfhQ9mCjjWl<&F9mA$Chx{Y;mc_^)c)eh3D9)tPRY&ay+R>~_HX|8>GN%va?ec^rHD@+&7 zWU+ss;r;wq?g4^-HrIN5R)d0zVhF*HYAq$bf8M%4|M zS3Kf5Z2(WINvf9iTnEB~-o_xc77B*ZVs^S(-JwqGxIveSdjQH@^J9d=d{frs|}a$ef+ zW6&)_#ov{?FcHbxqJajDa?7>rEX4pTnT>ye3EhNyey>T*xBVJp*G`?ad^VIlmZDbU zMwsI_z4V0#dg{uF=GDz+rFIHl%G)*lYUmM;7pIMda$T50+uq5YW?E$Vvi*3qm8YFp zrKvfMo|4}hJ#C&w&rEIQ)%498qSEv|LP58**`BM6u9Z+3QYn?Hey;}Z;Fi!Ze`r*` zJR)^YyS%JT7kRi%6$wkiHuyCB+qf0Jmsu{ffe)j3zvf6I?X^-4$e2u_2YU=aU zv1#vFP8-n>F17jobOpiJYg|xY|NZ0dPn&=C`1{l5*T;c%_M0UsC`;CSBZ=YwGu}xu z_@gW{hb8(}H)(XuH%or^G7TG4R`4Iibv7{tq+x#m000JJOGiWiCjc-23ppEfa{vGU z32;bRa{vGi{Qv+C{Q{Of>5cc?Q*If2>-2U$&+~qId+R($iUcSEo4^(DWX~0_0Th)rKp${OdJcfzMy10* zg~n3>hSH>Mz$Mvp0kp=%C2On$3qankWiJq&17+advH6(z#F};j-VVH3ZO!o+Cq9me z@2qJ(;0bVVwTYniY`hi|*R81v^gBN1PPXKD!QYQ}C85}{M@eN#U6LjpuS?pNbSr6A zQpcApNs>mynd8MRYEu5ie@Fb$Eb-QFh^ybQBT4%yuCv%D{QwLCwP2b}0i(dHyUp; ZA)oDt9LV^L_F(`3002ovPDHLkV1h83oofI9 literal 0 HcmV?d00001 diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 625d8657a..5d889295c 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -146,6 +146,10 @@ PianoRoll { qproperty-noteOpacity: 165; qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: #064d79; + qproperty-ghostNoteColor: #000000; + qproperty-ghostNoteTextColor: #ffffff; + qproperty-ghostNoteOpacity: 50; + qproperty-ghostNoteBorders: false; qproperty-barColor: #078f3a; qproperty-markedSemitoneColor: rgba(255, 255, 255, 30); /* Grid colors */ diff --git a/include/Pattern.h b/include/Pattern.h index eddbed313..3a1cc941c 100644 --- a/include/Pattern.h +++ b/include/Pattern.h @@ -187,6 +187,7 @@ public slots: protected slots: void openInPianoRoll(); + void setGhostInPianoRoll(); void resetName(); void changeName(); diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 8b0f1babf..168036245 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -59,7 +59,9 @@ class PianoRoll : public QWidget Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor ) Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor ) Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor ) + Q_PROPERTY( QColor ghostNoteColor READ ghostNoteColor WRITE setGhostNoteColor ) Q_PROPERTY( QColor noteTextColor READ noteTextColor WRITE setNoteTextColor ) + Q_PROPERTY( QColor ghostNoteTextColor READ ghostNoteTextColor WRITE setGhostNoteTextColor ) Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor ) Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor ) Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor ) @@ -68,6 +70,8 @@ class PianoRoll : public QWidget Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor ) Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity ) Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders ) + Q_PROPERTY( int ghostNoteOpacity READ ghostNoteOpacity WRITE setGhostNoteOpacity ) + Q_PROPERTY( bool ghostNoteBorders READ ghostNoteBorders WRITE setGhostNoteBorders ) Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade ) public: enum EditModes @@ -87,6 +91,7 @@ public: void showPanTextFloat(panning_t pan, const QPoint &pos, int timeout=-1); void setCurrentPattern( Pattern* newPattern ); + void setGhostPattern( Pattern* newPattern ); inline void stopRecording() { @@ -141,6 +146,14 @@ public: void setNoteOpacity( const int i ); bool noteBorders() const; void setNoteBorders( const bool b ); + QColor ghostNoteColor() const; + void setGhostNoteColor( const QColor & c ); + QColor ghostNoteTextColor() const; + void setGhostNoteTextColor( const QColor & c ); + int ghostNoteOpacity() const; + void setGhostNoteOpacity( const int i ); + bool ghostNoteBorders() const; + void setGhostNoteBorders( const bool b ); QColor backgroundShade() const; void setBackgroundShade( const QColor & c ); @@ -206,9 +219,12 @@ protected slots: void selectRegionFromPixels( int xStart, int xEnd ); + void clearGhostPattern(); + signals: void currentPatternChanged(); + void ghostPatternSet(bool); void semiToneMarkerMenuScaleSetEnabled(bool); void semiToneMarkerMenuChordSetEnabled(bool); @@ -309,6 +325,7 @@ private: static const QVector m_zoomLevels; Pattern* m_pattern; + Pattern* m_ghostPattern; QScrollBar * m_leftRightScroll; QScrollBar * m_topBottomScroll; @@ -388,6 +405,8 @@ private: QColor m_noteModeColor; QColor m_noteColor; QColor m_noteTextColor; + QColor m_ghostNoteColor; + QColor m_ghostNoteTextColor; QColor m_barColor; QColor m_selectedNoteColor; QColor m_textColor; @@ -395,7 +414,9 @@ private: QColor m_textShadow; QColor m_markedSemitoneColor; int m_noteOpacity; + int m_ghostNoteOpacity; bool m_noteBorders; + bool m_ghostNoteBorders; QColor m_backgroundShade; signals: @@ -412,7 +433,8 @@ public: PianoRollWindow(); const Pattern* currentPattern() const; - void setCurrentPattern(Pattern* pattern); + void setCurrentPattern( Pattern* pattern ); + void setGhostPattern( Pattern* pattern ); int quantization() const; @@ -445,6 +467,7 @@ signals: private slots: void patternRenamed(); + void ghostPatternSet( bool state ); private: void focusInEvent(QFocusEvent * event); @@ -456,6 +479,7 @@ private: ComboBox * m_noteLenComboBox; ComboBox * m_scaleComboBox; ComboBox * m_chordComboBox; + QPushButton * m_clearGhostButton; }; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 954dde5b0..07309ec1c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -182,6 +182,8 @@ PianoRoll::PianoRoll() : m_lineColor( 0, 0, 0 ), m_noteModeColor( 0, 0, 0 ), m_noteColor( 0, 0, 0 ), + m_ghostNoteColor( 0, 0, 0 ), + m_ghostNoteTextColor( 0, 0, 0 ), m_barColor( 0, 0, 0 ), m_selectedNoteColor( 0, 0, 0 ), m_textColor( 0, 0, 0 ), @@ -189,7 +191,9 @@ PianoRoll::PianoRoll() : m_textShadow( 0, 0, 0 ), m_markedSemitoneColor( 0, 0, 0 ), m_noteOpacity( 255 ), + m_ghostNoteOpacity( 255 ), m_noteBorders( true ), + m_ghostNoteBorders( true ), m_backgroundShade( 0, 0, 0 ) { // gui names of edit modes @@ -599,6 +603,26 @@ PianoRoll::~PianoRoll() } +void PianoRoll::setGhostPattern( Pattern* newPattern ) +{ + m_ghostPattern = newPattern; + if( newPattern != nullptr ) + { + // make sure to always get informed about the pattern being destroyed + connect( m_ghostPattern, SIGNAL( destroyedPattern( Pattern* ) ), this, SLOT( clearGhostPattern() ) ); + emit ghostPatternSet( true ); + } +} + + +void PianoRoll::clearGhostPattern() +{ + setGhostPattern( nullptr ); + emit ghostPatternSet( false ); + update(); +} + + void PianoRoll::setCurrentPattern( Pattern* newPattern ) { if( hasValidPattern() ) @@ -801,6 +825,30 @@ bool PianoRoll::noteBorders() const void PianoRoll::setNoteBorders( const bool b ) { m_noteBorders = b; } +QColor PianoRoll::ghostNoteColor() const +{ return m_ghostNoteColor; } + +void PianoRoll::setGhostNoteColor( const QColor & c ) +{ m_ghostNoteColor = c; } + +QColor PianoRoll::ghostNoteTextColor() const +{ return m_ghostNoteTextColor; } + +void PianoRoll::setGhostNoteTextColor( const QColor & c ) +{ m_ghostNoteTextColor = c; } + +int PianoRoll::ghostNoteOpacity() const +{ return m_ghostNoteOpacity; } + +void PianoRoll::setGhostNoteOpacity( const int i ) +{ m_ghostNoteOpacity = i; } + +bool PianoRoll::ghostNoteBorders() const +{ return m_ghostNoteBorders; } + +void PianoRoll::setGhostNoteBorders( const bool b ) +{ m_ghostNoteBorders = b; } + QColor PianoRoll::backgroundShade() const { return m_backgroundShade; } @@ -810,7 +858,6 @@ void PianoRoll::setBackgroundShade( const QColor & c ) - void PianoRoll::drawNoteRect( QPainter & p, int x, int y, int width, const Note * n, const QColor & noteCol, const QColor & noteTextColor, const QColor & selCol, const int noteOpc, const bool borders, bool drawNoteName ) @@ -3024,6 +3071,50 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) QPolygonF editHandles; + // -- Begin ghost pattern + if( m_ghostPattern != nullptr && m_ghostPattern != m_pattern ) + { + for( const Note *note : m_ghostPattern->notes() ) + { + int len_ticks = note->length(); + + if( len_ticks == 0 ) + { + continue; + } + else if( len_ticks < 0 ) + { + len_ticks = 4; + } + const int key = note->key() - m_startKey + 1; + + int pos_ticks = note->pos(); + + int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + const int x = ( pos_ticks - m_currentPosition ) * + m_ppt / MidiTime::ticksPerTact(); + // skip this note if not in visible area at all + if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) + { + continue; + } + + // is the note in visible area? + if( key > 0 && key <= visible_keys ) + { + + // we've done and checked all, let's draw the + // note + drawNoteRect( p, x + WHITE_KEY_WIDTH, + y_base - key * KEY_LINE_HEIGHT, + note_width, note, ghostNoteColor(), ghostNoteTextColor(), selectedNoteColor(), + ghostNoteOpacity(), ghostNoteBorders(), drawNoteNames ); + } + + } + } + // -- End ghost pattern + for( const Note *note : m_pattern->notes() ) { int len_ticks = note->length(); @@ -4221,8 +4312,15 @@ PianoRollWindow::PianoRollWindow() : m_chordComboBox = new ComboBox( m_toolBar ); m_chordComboBox->setModel( &m_editor->m_chordModel ); m_chordComboBox->setFixedSize( 105, 22 ); - m_chordComboBox->setToolTip( tr( "Chord") ); + m_chordComboBox->setToolTip( tr( "Chord" ) ); + // -- Clear ghost pattern button + m_clearGhostButton = new QPushButton( m_toolBar ); + m_clearGhostButton->setIcon( embed::getIconPixmap( "clear_ghost_note" ) ); + m_clearGhostButton->setToolTip( tr( "Clear ghost notes" ) ); + m_clearGhostButton->setEnabled( false ); + connect( m_clearGhostButton, SIGNAL( clicked() ), m_editor, SLOT( clearGhostPattern() ) ); + connect( m_editor, SIGNAL( ghostPatternSet( bool ) ), this, SLOT( ghostPatternSet( bool ) ) ); zoomAndNotesToolBar->addWidget( zoom_lbl ); zoomAndNotesToolBar->addWidget( m_zoomingComboBox ); @@ -4243,6 +4341,9 @@ PianoRollWindow::PianoRollWindow() : zoomAndNotesToolBar->addWidget( chord_lbl ); zoomAndNotesToolBar->addWidget( m_chordComboBox ); + zoomAndNotesToolBar->addSeparator(); + zoomAndNotesToolBar->addWidget( m_clearGhostButton ); + // setup our actual window setFocusPolicy( Qt::StrongFocus ); setFocus(); @@ -4265,6 +4366,14 @@ const Pattern* PianoRollWindow::currentPattern() const +void PianoRollWindow::setGhostPattern( Pattern* pattern ) +{ + m_editor->setGhostPattern( pattern ); +} + + + + void PianoRollWindow::setCurrentPattern( Pattern* pattern ) { m_editor->setCurrentPattern( pattern ); @@ -4387,6 +4496,14 @@ void PianoRollWindow::patternRenamed() +void PianoRollWindow::ghostPatternSet( bool state ) +{ + m_clearGhostButton->setEnabled( state ); +} + + + + void PianoRollWindow::focusInEvent( QFocusEvent * event ) { // when the window is given focus, also give focus to the actual piano roll diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index 05d316f00..d5da06df7 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -637,6 +637,18 @@ void PatternView::openInPianoRoll() + +void PatternView::setGhostInPianoRoll() +{ + gui->pianoRoll()->setGhostPattern( m_pat ); + gui->pianoRoll()->parentWidget()->show(); + gui->pianoRoll()->show(); + gui->pianoRoll()->setFocus(); +} + + + + void PatternView::resetName() { m_pat->setName( m_pat->m_instrumentTrack->name() ); @@ -663,7 +675,22 @@ void PatternView::constructContextMenu( QMenu * _cm ) _cm->insertAction( _cm->actions()[0], a ); connect( a, SIGNAL( triggered( bool ) ), this, SLOT( openInPianoRoll() ) ); - _cm->insertSeparator( _cm->actions()[1] ); + + if( gui->pianoRoll()->currentPattern() && + gui->pianoRoll()->currentPattern() != m_pat && + not m_pat->empty() ) + { + QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ), + tr( "Set as ghost in piano-roll" ), _cm ); + _cm->insertAction( _cm->actions()[1], b ); + connect( b, SIGNAL( triggered( bool ) ), + this, SLOT( setGhostInPianoRoll() ) ); + _cm->insertSeparator( _cm->actions()[2] ); + } + else + { + _cm->insertSeparator( _cm->actions()[1] ); + } _cm->addSeparator(); From 69a51eb28bf1d7d73594e380d9995ebb2d7b2b19 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Mon, 14 Jan 2019 22:05:42 +0000 Subject: [PATCH 32/79] Enable VST sync by default --- src/gui/SetupDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index f508da878..1e5c7aa5f 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -127,7 +127,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : m_compactTrackButtons( ConfigManager::inst()->value( "ui", "compacttrackbuttons" ).toInt() ), m_syncVSTPlugins( ConfigManager::inst()->value( "ui", - "syncvstplugins" ).toInt() ), + "syncvstplugins", "1" ).toInt() ), m_animateAFP(ConfigManager::inst()->value( "ui", "animateafp", "1" ).toInt() ), m_printNoteLabels(ConfigManager::inst()->value( "ui", From 79374b3a0f3e56f873b85020c47d1adcce44f2de Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Mon, 14 Jan 2019 22:06:20 +0000 Subject: [PATCH 33/79] Link RemoteZynAddSubFx with -mwindows --- plugins/zynaddsubfx/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index 541b8cf2a..9d90c5e38 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -166,6 +166,10 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp "${WINRC}") INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION "${PLUGIN_DIR}") +IF(LMMS_BUILD_WIN32) + SET_TARGET_PROPERTIES(RemoteZynAddSubFx PROPERTIES LINK_FLAGS "${LINK_FLAGS} -mwindows") +ENDIF(LMMS_BUILD_WIN32) + # Remove useless dependencies from FLTK. Use fltk-config to avoid static library # in older environments SET(FLTK_FILTERED_LDFLAGS ${FLTK_LIBRARIES}) From 227e88a347476e70d8a1c43660334d6229a4c1e1 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Mon, 14 Jan 2019 22:10:29 +0000 Subject: [PATCH 34/79] Fix file extension list in translations --- data/locale/ru.ts | 2 +- data/locale/uk.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/locale/ru.ts b/data/locale/ru.ts index b26a4e82f..37a19db0d 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -7203,7 +7203,7 @@ Please make sure you have read-permission to the file and the directory containi Vst Plugin Preset (*.fxp *.fxb) - Предустановка VST плагина (*.fxp, *.fxb) + Предустановка VST плагина (*.fxp *.fxb) : default diff --git a/data/locale/uk.ts b/data/locale/uk.ts index 88d92b82b..2af7e6738 100644 --- a/data/locale/uk.ts +++ b/data/locale/uk.ts @@ -7199,7 +7199,7 @@ Please make sure you have read-permission to the file and the directory containi Vst Plugin Preset (*.fxp *.fxb) - Передустановка VST плагіна (*.fxp, *.fxb) + Передустановка VST плагіна (*.fxp *.fxb) : default From 1faaf008c8c32ce0b77c8e48808c0e321943aa40 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sat, 19 Jan 2019 15:57:57 +0000 Subject: [PATCH 35/79] Don't memcpy null pointer --- plugins/MidiImport/portsmf/allegro.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/MidiImport/portsmf/allegro.cpp b/plugins/MidiImport/portsmf/allegro.cpp index 653ff4c07..3f7b84073 100644 --- a/plugins/MidiImport/portsmf/allegro.cpp +++ b/plugins/MidiImport/portsmf/allegro.cpp @@ -54,8 +54,10 @@ void Alg_atoms::expand() maxlen += (maxlen >> 2); // add 25% char **new_atoms = new Alg_attribute[maxlen]; // now do copy - memcpy(new_atoms, atoms, len * sizeof(Alg_attribute)); - if (atoms) delete[] atoms; + if (atoms) { + memcpy(new_atoms, atoms, len * sizeof(Alg_attribute)); + delete[] atoms; + } atoms = new_atoms; } From dd99f3a7c466e86e02a8a8811e4b41f471a8b15d Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sun, 20 Jan 2019 11:47:22 +0100 Subject: [PATCH 36/79] Improve handling of nan/inf (#4743) * If we find NaN/inf, we declare the whole buffer bad and set it to 0.0f. This is because the noise leading up to, or coming from, an infinite or NaN value is often very large and will create problems later in the sound chain. Especially if it hits a delay based fx with feedback. * We bump the clipping level to +/-10.0f. --- src/core/MixHelpers.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index 60fa778af..a1fcd155d 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -79,12 +79,23 @@ bool sanitize( sampleFrame * src, int frames ) { if( isinff( src[f][c] ) || isnanf( src[f][c] ) ) { - src[f][c] = 0.0f; + #ifdef LMMS_DEBUG + 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] = qBound( -4.0f, src[f][c], 4.0f ); + src[f][c] = qBound( -10.0f, src[f][c], 10.0f ); } } } From 6df6f12a3d54bfaa61beff7865a2f0c02adc3071 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sun, 20 Jan 2019 14:32:44 +0100 Subject: [PATCH 37/79] Pianoroll - Add checkpoint before moving notes --- src/gui/editors/PianoRoll.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 6950c0005..7bdf9dc07 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -952,6 +952,7 @@ void PianoRoll::shiftSemiTone( int amount ) // shift notes by amount semitones { if (!hasValidPattern()) {return;} + m_pattern->addJournalCheckPoint(); bool useAllNotes = ! isSelection(); for( Note *note : m_pattern->notes() ) { @@ -978,6 +979,7 @@ void PianoRoll::shiftPos( int amount ) //shift notes pos by amount { if (!hasValidPattern()) {return;} + m_pattern->addJournalCheckPoint(); bool useAllNotes = ! isSelection(); bool first = true; From c1ae1ed5f4246de40c3cfe5327d7dfbd5cd4470b Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 22 Jan 2019 02:49:25 +0900 Subject: [PATCH 38/79] MIDI import/export: map note volume and MIDI velocity with their full range (#4785) * MIDI export: map volume to MIDI velocity correctly * MIDI import: map MIDI velocity to note volume with full range --- plugins/MidiExport/MidiExport.cpp | 3 ++- plugins/MidiImport/MidiImport.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/MidiExport/MidiExport.cpp b/plugins/MidiExport/MidiExport.cpp index 65eaf4613..20bda52b3 100644 --- a/plugins/MidiExport/MidiExport.cpp +++ b/plugins/MidiExport/MidiExport.cpp @@ -274,7 +274,8 @@ void MidiExport::writePattern(MidiNoteVector &pat, QDomNode n, // TODO interpret pan="0" fxch="0" pitchrange="1" MidiNote mnote; mnote.pitch = qMax(0, qMin(127, note.attribute("key", "0").toInt() + base_pitch)); - mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100"))), 127); + // Map from LMMS volume to MIDI velocity + mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100")) * (127.0 / 200.0)), 127); mnote.time = base_time + note.attribute("pos", "0").toInt(); mnote.duration = note.attribute("len", "0").toInt(); pat.push_back(mnote); diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 5fde7acc7..e83ef8c27 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -426,7 +426,7 @@ bool MidiImport::readSMF( TrackContainer* tc ) Note n( (ticks < 1 ? 1 : ticks ), noteEvt->get_start_time() * ticksPerBeat, noteEvt->get_identifier() - 12, - noteEvt->get_loud()); + noteEvt->get_loud() * (200.f / 127.f)); // Map from MIDI velocity to LMMS volume ch->addNote( n ); } From b68c5ee5b56c7f0194a21458f879e78fd9dd4225 Mon Sep 17 00:00:00 2001 From: Steven Christy Date: Sun, 27 Jan 2019 03:22:47 -0600 Subject: [PATCH 39/79] Rendering looped sections multiple times on export (#4624) (#4639) --- include/Song.h | 27 +++++++++-- src/core/ProjectRenderer.cpp | 14 ++---- src/core/Song.cpp | 74 ++++++++++++++++++++++++------- src/gui/ExportProjectDialog.cpp | 2 + src/gui/dialogs/export_project.ui | 47 ++++++++++++++++++-- 5 files changed, 130 insertions(+), 34 deletions(-) diff --git a/include/Song.h b/include/Song.h index 7ab1f54f6..d88a59e2b 100644 --- a/include/Song.h +++ b/include/Song.h @@ -103,8 +103,6 @@ public: } ; - - void processNextBuffer(); inline int getLoadingTrackCount() const @@ -203,9 +201,23 @@ public: { return m_recording; } + + inline void setLoopRenderCount(int count) + { + if (count < 1) + m_loopRenderCount = 1; + else + m_loopRenderCount = count; + m_loopRenderRemaining = m_loopRenderCount; + } + + inline int getLoopRenderCount() const + { + return m_loopRenderCount; + } bool isExportDone() const; - std::pair getExportEndpoints() const; + int getExportProgress() const; inline void setRenderBetweenMarkers( bool renderBetweenMarkers ) { @@ -424,7 +436,14 @@ private: tact_t m_elapsedTacts; VstSyncController m_vstSyncController; - + + int m_loopRenderCount; + int m_loopRenderRemaining; + MidiTime m_exportSongBegin; + MidiTime m_exportLoopBegin; + MidiTime m_exportLoopEnd; + MidiTime m_exportSongEnd; + MidiTime m_exportEffectiveLength; friend class LmmsCore; friend class SongEditor; diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp index 57975356e..71a5aaff8 100644 --- a/src/core/ProjectRenderer.cpp +++ b/src/core/ProjectRenderer.cpp @@ -185,25 +185,17 @@ void ProjectRenderer::run() // Skip first empty buffer. Engine::mixer()->nextBuffer(); - const Song::PlayPos & exportPos = Engine::getSong()->getPlayPos( - Song::Mode_PlaySong ); m_progress = 0; - std::pair exportEndpoints = Engine::getSong()->getExportEndpoints(); - tick_t startTick = exportEndpoints.first.getTicks(); - tick_t endTick = exportEndpoints.second.getTicks(); - tick_t lengthTicks = endTick - startTick; // Now start processing Engine::mixer()->startProcessing(false); // Continually track and emit progress percentage to listeners. - while( exportPos.getTicks() < endTick && - Engine::getSong()->isExporting() == true - && !m_abort ) + while (!Engine::getSong()->isExportDone() && !m_abort) { m_fileDev->processNextBuffer(); - const int nprog = lengthTicks == 0 ? 100 : (exportPos.getTicks()-startTick) * 100 / lengthTicks; - if( m_progress != nprog ) + const int nprog = Engine::getSong()->getExportProgress(); + if (m_progress != nprog) { m_progress = nprog; emit progressChanged( m_progress ); diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 6f060664e..a80b0d8c7 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -86,7 +86,9 @@ Song::Song() : m_patternToPlay( NULL ), m_loopPattern( false ), m_elapsedTicks( 0 ), - m_elapsedTacts( 0 ) + m_elapsedTacts( 0 ), + m_loopRenderCount(1), + m_loopRenderRemaining(1) { for(int i = 0; i < Mode_Count; ++i) m_elapsedMilliSeconds[i] = 0; connect( &m_tempoModel, SIGNAL( dataChanged() ), @@ -330,7 +332,7 @@ void Song::processNextBuffer() } m_playPos[m_playMode].setTicks( ticks ); - if( checkLoop ) + if (checkLoop || m_loopRenderRemaining > 1) { m_vstSyncController.startCycle( tl->loopBegin().getTicks(), tl->loopEnd().getTicks() ); @@ -340,6 +342,8 @@ void Song::processNextBuffer() // beginning of the range if( m_playPos[m_playMode] >= tl->loopEnd() ) { + if (m_loopRenderRemaining > 1) + m_loopRenderRemaining--; ticks = tl->loopBegin().getTicks(); m_playPos[m_playMode].setTicks( ticks ); setToTime(tl->loopBegin()); @@ -476,29 +480,41 @@ void Song::setModified(bool value) } } -std::pair Song::getExportEndpoints() const +bool Song::isExportDone() const { - if ( m_renderBetweenMarkers ) + return !isExporting() || m_playPos[m_playMode] >= m_exportSongEnd; +} + +int Song::getExportProgress() const +{ + MidiTime pos = m_playPos[m_playMode]; + + if (pos >= m_exportSongEnd) { - return std::pair( - m_playPos[Mode_PlaySong].m_timeLine->loopBegin(), - m_playPos[Mode_PlaySong].m_timeLine->loopEnd() - ); + return 100; } - else if ( m_exportLoop ) + else if (pos <= m_exportSongBegin) { - return std::pair( MidiTime(0, 0), MidiTime(m_length, 0) ); + return 0; + } + else if (pos >= m_exportLoopEnd) + { + pos = (m_exportLoopBegin-m_exportSongBegin) + (m_exportLoopEnd - m_exportLoopBegin) * + m_loopRenderCount + (pos - m_exportLoopEnd); + } + else if ( pos >= m_exportLoopBegin ) + { + pos = (m_exportLoopBegin-m_exportSongBegin) + ((m_exportLoopEnd - m_exportLoopBegin) * + (m_loopRenderCount - m_loopRenderRemaining)) + (pos - m_exportLoopBegin); } else { - // if not exporting as a loop, we leave one bar of padding at the end of the song to accomodate reverb, etc. - return std::pair( MidiTime(0, 0), MidiTime(m_length+1, 0) ); + pos = (pos - m_exportSongBegin); } + + return (float)pos/(float)m_exportEffectiveLength*100.0f; } - - - void Song::playSong() { m_recording = false; @@ -719,15 +735,41 @@ void Song::stop() void Song::startExport() { stop(); - if(m_renderBetweenMarkers) + if (m_renderBetweenMarkers) { + m_exportSongBegin = m_exportLoopBegin = m_playPos[Mode_PlaySong].m_timeLine->loopBegin(); + m_exportSongEnd = m_exportLoopEnd = m_playPos[Mode_PlaySong].m_timeLine->loopEnd(); + m_playPos[Mode_PlaySong].setTicks( m_playPos[Mode_PlaySong].m_timeLine->loopBegin().getTicks() ); } else { + m_exportSongEnd = MidiTime(m_length, 0); + + // Handle potentially ridiculous loop points gracefully. + if (m_loopRenderCount > 1 && m_playPos[Mode_PlaySong].m_timeLine->loopEnd() > m_exportSongEnd) + { + m_exportSongEnd = m_playPos[Mode_PlaySong].m_timeLine->loopEnd(); + } + + if (!m_exportLoop) + m_exportSongEnd += MidiTime(1,0); + + m_exportSongBegin = MidiTime(0,0); + m_exportLoopBegin = m_playPos[Mode_PlaySong].m_timeLine->loopBegin() < m_exportSongEnd && + m_playPos[Mode_PlaySong].m_timeLine->loopEnd() <= m_exportSongEnd ? + m_playPos[Mode_PlaySong].m_timeLine->loopBegin() : MidiTime(0,0); + m_exportLoopEnd = m_playPos[Mode_PlaySong].m_timeLine->loopBegin() < m_exportSongEnd && + m_playPos[Mode_PlaySong].m_timeLine->loopEnd() <= m_exportSongEnd ? + m_playPos[Mode_PlaySong].m_timeLine->loopEnd() : MidiTime(0,0); + m_playPos[Mode_PlaySong].setTicks( 0 ); } + m_exportEffectiveLength = (m_exportLoopBegin - m_exportSongBegin) + (m_exportLoopEnd - m_exportLoopBegin) + * m_loopRenderCount + (m_exportSongEnd - m_exportLoopEnd); + m_loopRenderRemaining = m_loopRenderCount; + playSong(); m_exporting = true; diff --git a/src/gui/ExportProjectDialog.cpp b/src/gui/ExportProjectDialog.cpp index b50c9941b..f3b432f99 100644 --- a/src/gui/ExportProjectDialog.cpp +++ b/src/gui/ExportProjectDialog.cpp @@ -128,6 +128,7 @@ void ExportProjectDialog::accept() void ExportProjectDialog::closeEvent( QCloseEvent * _ce ) { + Engine::getSong()->setLoopRenderCount(1); if( m_renderManager ) { m_renderManager->abortProcessing(); } @@ -187,6 +188,7 @@ void ExportProjectDialog::startExport() Engine::getSong()->setExportLoop( exportLoopCB->isChecked() ); Engine::getSong()->setRenderBetweenMarkers( renderMarkersCB->isChecked() ); + Engine::getSong()->setLoopRenderCount(loopCountSB->value()); connect( m_renderManager.get(), SIGNAL( progressChanged( int ) ), progressBar, SLOT( setValue( int ) ) ); diff --git a/src/gui/dialogs/export_project.ui b/src/gui/dialogs/export_project.ui index 1ec4fe123..6b175de78 100644 --- a/src/gui/dialogs/export_project.ui +++ b/src/gui/dialogs/export_project.ui @@ -7,19 +7,19 @@ 0 0 379 - 374 + 400 379 - 374 + 400 379 - 374 + 400 @@ -40,6 +40,47 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Render Looped Section: + + + + + + + time(s) + + + 1 + + + 99 + + + 1 + + + + + + From 8618ab5d8f885e4fdf0183259df4ae36771ff692 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Mon, 28 Jan 2019 19:10:40 +0100 Subject: [PATCH 40/79] Increase forced clipping level --- src/core/MixHelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index a1fcd155d..3a8e4c1a7 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -95,7 +95,7 @@ bool sanitize( sampleFrame * src, int frames ) } else { - src[f][c] = qBound( -10.0f, src[f][c], 10.0f ); + src[f][c] = qBound( -1000.0f, src[f][c], 1000.0f ); } } } From fdccb389890a6e41503e121a4dc926f0415d06d6 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Wed, 30 Jan 2019 21:56:10 +0100 Subject: [PATCH 41/79] Fixes #4778: Update mailmap [ci skip] --- .mailmap | 3 +++ doc/AUTHORS | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 7628795f9..71b6697c8 100644 --- a/.mailmap +++ b/.mailmap @@ -26,3 +26,6 @@ Thomas Clark Thomas Clark anonymous Locale updater <> grejppi +Johannes Lorenz +Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> +Noah Brecht diff --git a/doc/AUTHORS b/doc/AUTHORS index 8dc5a3039..6cc8a57a7 100644 --- a/doc/AUTHORS +++ b/doc/AUTHORS @@ -67,7 +67,7 @@ Tobiasz Karoń (unfa) UI Developer Johannes Lorenz - + Developer Rubén Ibarra Pastor From 42df251c66b45f6f00a0ad46205a21d27dabfc37 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Wed, 30 Jan 2019 22:18:15 +0100 Subject: [PATCH 42/79] Fix address in doc/AUTHORS [ci skip] --- doc/AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/AUTHORS b/doc/AUTHORS index 6cc8a57a7..9244d1198 100644 --- a/doc/AUTHORS +++ b/doc/AUTHORS @@ -67,7 +67,7 @@ Tobiasz Karoń (unfa) UI Developer Johannes Lorenz - + Developer Rubén Ibarra Pastor From 0a47b0c8cd8e5464c9ddf17ce4dd5e1aa2754b75 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Wed, 30 Jan 2019 22:39:23 +0100 Subject: [PATCH 43/79] Fixes #4752: Update rpmalloc --- src/3rdparty/rpmalloc/rpmalloc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/rpmalloc/rpmalloc b/src/3rdparty/rpmalloc/rpmalloc index 36b1942fb..6b424e62e 160000 --- a/src/3rdparty/rpmalloc/rpmalloc +++ b/src/3rdparty/rpmalloc/rpmalloc @@ -1 +1 @@ -Subproject commit 36b1942fbc309b139e56a03166ba19a87f28f26c +Subproject commit 6b424e62e49cdfd92422e5fd85a5972323cf2ac5 From b28d4052404099817abbd080ffc2baa686ee17b4 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Thu, 31 Jan 2019 23:12:45 +0100 Subject: [PATCH 44/79] Disable built-in NaN handler through hidden setting (#4787) * Disable built-in NaN handler through hidden setting * Reuse code --- include/MixHelpers.h | 4 ++++ include/SetupDialog.h | 1 + src/core/MixHelpers.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/core/main.cpp | 5 +++++ src/gui/SetupDialog.cpp | 13 +++++++++++++ 5 files changed, 60 insertions(+) diff --git a/include/MixHelpers.h b/include/MixHelpers.h index 7f919aba1..872319f82 100644 --- a/include/MixHelpers.h +++ b/include/MixHelpers.h @@ -33,6 +33,10 @@ namespace MixHelpers bool isSilent( const sampleFrame* src, int frames ); +bool useNaNHandler(); + +void setNaNHandler( bool use ); + bool sanitize( sampleFrame * src, int frames ); /*! \brief Add samples from src to dst */ diff --git a/include/SetupDialog.h b/include/SetupDialog.h index ebaa90f01..338ea93dd 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -142,6 +142,7 @@ private: bool m_MMPZ; bool m_disableBackup; bool m_openLastProject; + bool m_NaNHandler; bool m_hqAudioDev; QString m_lang; QStringList m_languages; diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index 3a8e4c1a7..d70b47e07 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -27,6 +27,9 @@ #include "ValueBuffer.h" +static bool s_NaNHandler; + + namespace MixHelpers { @@ -68,10 +71,24 @@ bool isSilent( const sampleFrame* src, int frames ) return true; } +bool useNaNHandler() +{ + return s_NaNHandler; +} + +void setNaNHandler( bool use ) +{ + s_NaNHandler = use; +} /*! \brief Function for sanitizing a buffer of infs/nans - returns true if those are found */ bool sanitize( sampleFrame * src, int frames ) { + if( !useNaNHandler() ) + { + return false; + } + bool found = false; for( int f = 0; f < frames; ++f ) { @@ -179,6 +196,13 @@ void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuff void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) { + if ( !useNaNHandler() ) + { + addMultipliedByBuffer( dst, src, coeffSrc, coeffSrcBuf, + frames ); + return; + } + for( int f = 0; f < frames; ++f ) { dst[f][0] += ( isinff( src[f][0] ) || isnanf( src[f][0] ) ) ? 0.0f : src[f][0] * coeffSrc * coeffSrcBuf->values()[f]; @@ -188,6 +212,13 @@ void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, f void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) { + if ( !useNaNHandler() ) + { + addMultipliedByBuffers( dst, src, coeffSrcBuf1, coeffSrcBuf2, + frames ); + return; + } + for( int f = 0; f < frames; ++f ) { dst[f][0] += ( isinff( src[f][0] ) || isnanf( src[f][0] ) ) @@ -216,6 +247,12 @@ struct AddSanitizedMultipliedOp void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) { + if ( !useNaNHandler() ) + { + addMultiplied( dst, src, coeffSrc, frames ); + return; + } + run<>( dst, src, frames, AddSanitizedMultipliedOp(coeffSrc) ); } diff --git a/src/core/main.cpp b/src/core/main.cpp index 4a6654a5d..45f2bb66b 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -64,6 +64,7 @@ #include "GuiApplication.h" #include "ImportFilter.h" #include "MainWindow.h" +#include "MixHelpers.h" #include "OutputSettings.h" #include "ProjectRenderer.h" #include "RenderManager.h" @@ -633,6 +634,10 @@ int main( int argc, char * * argv ) ConfigManager::inst()->loadConfigFile(configFile); + // Hidden settings + MixHelpers::setNaNHandler( ConfigManager::inst()->value( "app", + "nanhandler", "1" ).toInt() ); + // set language QString pos = ConfigManager::inst()->value( "app", "language" ); if( pos.isEmpty() ) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 1e5c7aa5f..4c261f581 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -99,6 +99,8 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : "disablebackup" ).toInt() ), m_openLastProject( ConfigManager::inst()->value( "app", "openlastproject" ).toInt() ), + m_NaNHandler( ConfigManager::inst()->value( "app", + "nanhandler", "1" ).toInt() ), m_hqAudioDev( ConfigManager::inst()->value( "mixer", "hqaudio" ).toInt() ), m_lang( ConfigManager::inst()->value( "app", @@ -334,6 +336,15 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : misc_tw->setFixedHeight( YDelta*labelNumber + HeaderSize ); + // Advanced setting, hidden for now + if( false ) + { + LedCheckBox * useNaNHandler = new LedCheckBox( + tr( "Use built-in NaN handler" ), + misc_tw ); + useNaNHandler->setChecked( m_NaNHandler ); + } + TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general); embed_tw->setFixedHeight( 48 ); m_vstEmbedComboBox = new QComboBox( embed_tw ); @@ -1055,6 +1066,8 @@ void SetupDialog::accept() QString::number( !m_disableBackup ) ); ConfigManager::inst()->setValue( "app", "openlastproject", QString::number( m_openLastProject ) ); + ConfigManager::inst()->setValue( "app", "nanhandler", + QString::number( m_NaNHandler ) ); ConfigManager::inst()->setValue( "mixer", "hqaudio", QString::number( m_hqAudioDev ) ); ConfigManager::inst()->setValue( "ui", "smoothscroll", From d9b5ee03fea807e70e74c5962b3f903ea598ed1c Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 2 Feb 2019 11:09:16 +0100 Subject: [PATCH 45/79] Fix CI by reverting rpmalloc --- src/3rdparty/rpmalloc/rpmalloc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/rpmalloc/rpmalloc b/src/3rdparty/rpmalloc/rpmalloc index 6b424e62e..b5bdc1805 160000 --- a/src/3rdparty/rpmalloc/rpmalloc +++ b/src/3rdparty/rpmalloc/rpmalloc @@ -1 +1 @@ -Subproject commit 6b424e62e49cdfd92422e5fd85a5972323cf2ac5 +Subproject commit b5bdc18051bb74a22f0bde4bcc90b01cf590b496 From e6bcf13cd34d27394ed6d007fb1e6825dcc84b99 Mon Sep 17 00:00:00 2001 From: justnope Date: Mon, 4 Feb 2019 09:07:03 +0100 Subject: [PATCH 46/79] replaced alternative token "not" with "!" --- src/tracks/Pattern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index d5da06df7..a296a8821 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -678,7 +678,7 @@ void PatternView::constructContextMenu( QMenu * _cm ) if( gui->pianoRoll()->currentPattern() && gui->pianoRoll()->currentPattern() != m_pat && - not m_pat->empty() ) + !m_pat->empty() ) { QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ), tr( "Set as ghost in piano-roll" ), _cm ); From c907fcdca5bd0b5e948a98e2158910d32f0f6154 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Wed, 6 Feb 2019 18:25:11 +0000 Subject: [PATCH 47/79] Don't let silent instruments wake up sleeping effects (#4792) --- src/core/audio/AudioPort.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/audio/AudioPort.cpp b/src/core/audio/AudioPort.cpp index 868f9f64f..5b2ff7f95 100644 --- a/src/core/audio/AudioPort.cpp +++ b/src/core/audio/AudioPort.cpp @@ -119,7 +119,9 @@ void AudioPort::doProcessing() { if( ph->buffer() ) { - if( ph->usesBuffer() ) + if( ph->usesBuffer() + && ( ph->type() == PlayHandle::TypeNotePlayHandle + || !MixHelpers::isSilent( ph->buffer(), fpp ) ) ) { m_bufferUsage = true; MixHelpers::add( m_portBuffer, ph->buffer(), fpp ); From 3c88541345a046ab8e063b7d9474529dd9fe52cb Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Thu, 7 Feb 2019 19:02:34 +0100 Subject: [PATCH 48/79] Follow instructions from cartr/homebrew-qt4 (#4815) --- .travis/osx..install.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis/osx..install.sh b/.travis/osx..install.sh index dfe1df4d1..3e49695f4 100644 --- a/.travis/osx..install.sh +++ b/.travis/osx..install.sh @@ -4,10 +4,14 @@ PACKAGES="cmake pkgconfig fftw libogg libvorbis lame libsndfile libsamplerate ja if [ $QT5 ]; then PACKAGES="$PACKAGES qt5" -else - PACKAGES="$PACKAGES cartr/qt4/qt" fi brew install $PACKAGES ccache +if [ -z "$QT5" ]; then + brew tap cartr/qt4 + brew tap-pin cartr/qt4 + brew install qt@4 +fi + sudo npm install -g appdmg From 7a0b874d1729977a83b31c0cece1edcb39a1f41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Andr=C3=A8s?= Date: Thu, 7 Feb 2019 20:52:12 +0100 Subject: [PATCH 49/79] shellcheck maxdepth 3 shellcheck against all project files, maxdepth of 3 directories --- .travis/script.sh | 3 ++- doc/bash-completion/lmms | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis/script.sh b/.travis/script.sh index 27e9ec7fb..ee901eb26 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -8,7 +8,8 @@ if [ "$TYPE" = 'style' ]; then # once it's fixed, it should be enabled again # shellcheck disable=SC2185 # shellcheck disable=SC2046 - shellcheck $(find -O3 "$TRAVIS_BUILD_DIR/.travis/" "$TRAVIS_BUILD_DIR/cmake/" -type f -name '*.sh' -o -name "*.sh.in") + shellcheck $(find -O3 . -maxdepth 3 -type f -name '*.sh' -o -name "*.sh.in") + shellcheck doc/bash-completion/lmms else diff --git a/doc/bash-completion/lmms b/doc/bash-completion/lmms index 19fbf4723..ccff8f249 100644 --- a/doc/bash-completion/lmms +++ b/doc/bash-completion/lmms @@ -1,3 +1,4 @@ +#!/usr/bin/env bash # lmms(1) completion -*- shell-script -*- # use shellcheck: "shellcheck -e bash " From 9981b760e48cea2d20c324b94601a9d8ea4d9361 Mon Sep 17 00:00:00 2001 From: CYBERDEViLNL Date: Tue, 5 Feb 2019 15:47:41 +0100 Subject: [PATCH 50/79] =?UTF-8?q?Ghost=20notes=20improvements.=20*=20Make?= =?UTF-8?q?=20a=20copy=20of=20a=20pattern=20it=E2=80=99s=20notes=20instead?= =?UTF-8?q?=20of=20pointing=20to=20a=20pattern.=20*=20Save/load=20the=20gh?= =?UTF-8?q?ost=20notes=20in/from=20the=20DOM=20document.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/PianoRoll.h | 9 ++++++- src/gui/editors/PianoRoll.cpp | 50 +++++++++++++++++++++++++++++++---- src/tracks/Pattern.cpp | 4 +-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 168036245..914d3c623 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -92,6 +92,7 @@ public: void setCurrentPattern( Pattern* newPattern ); void setGhostPattern( Pattern* newPattern ); + void loadGhostNotes( const QDomElement & de ); inline void stopRecording() { @@ -325,7 +326,13 @@ private: static const QVector m_zoomLevels; Pattern* m_pattern; - Pattern* m_ghostPattern; + NoteVector m_ghostNotes; + + inline const NoteVector & ghostNotes() const + { + return m_ghostNotes; + } + QScrollBar * m_leftRightScroll; QScrollBar * m_topBottomScroll; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 07309ec1c..b773724ea 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -452,6 +452,7 @@ void PianoRoll::reset() { m_lastNoteVolume = DefaultVolume; m_lastNotePanning = DefaultPanning; + clearGhostPattern(); } void PianoRoll::showTextFloat(const QString &text, const QPoint &pos, int timeout) @@ -605,11 +606,33 @@ PianoRoll::~PianoRoll() void PianoRoll::setGhostPattern( Pattern* newPattern ) { - m_ghostPattern = newPattern; + // Expects a pointer to a pattern or nullptr. + m_ghostNotes.clear(); if( newPattern != nullptr ) { - // make sure to always get informed about the pattern being destroyed - connect( m_ghostPattern, SIGNAL( destroyedPattern( Pattern* ) ), this, SLOT( clearGhostPattern() ) ); + for( Note *note : newPattern->notes() ) + { + Note * new_note = new Note( note->length(), note->pos(), note->key() ); + m_ghostNotes.push_back( new_note ); + } + emit ghostPatternSet( true ); + } +} + + +void PianoRoll::loadGhostNotes( const QDomElement & de ) +{ + // Load ghost notes from DOM element. + if( de.isElement() ) + { + QDomNode node = de.firstChild(); + while( !node.isNull() ) + { + Note * n = new Note; + n->restoreState( node.toElement() ); + m_ghostNotes.push_back( n ); + node = node.nextSibling(); + } emit ghostPatternSet( true ); } } @@ -3072,9 +3095,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) QPolygonF editHandles; // -- Begin ghost pattern - if( m_ghostPattern != nullptr && m_ghostPattern != m_pattern ) + if( !m_ghostNotes.empty() ) { - for( const Note *note : m_ghostPattern->notes() ) + for( const Note *note : m_ghostNotes ) { int len_ticks = note->length(); @@ -4459,6 +4482,21 @@ void PianoRollWindow::reset() void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de ) { + if( !m_editor->ghostNotes().empty() ) + { + QDomElement ghostNotesRoot = doc.createElement( "ghostnotes" ); + for( Note *note : m_editor->ghostNotes() ) + { + QDomElement ghostNoteNode = doc.createElement( "ghostnote" ); + ghostNoteNode.setAttribute( "len", note->length() ); + ghostNoteNode.setAttribute( "key", note->key() ); + ghostNoteNode.setAttribute( "pos", note->pos() ); + + ghostNotesRoot.appendChild(ghostNoteNode); + } + de.appendChild( ghostNotesRoot ); + } + MainWindow::saveWidgetState( this, de ); } @@ -4467,6 +4505,8 @@ void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de ) void PianoRollWindow::loadSettings( const QDomElement & de ) { + m_editor->loadGhostNotes( de.firstChildElement("ghostnotes") ); + MainWindow::restoreWidgetState( this, de ); } diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index a296a8821..33044cf3b 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -676,9 +676,7 @@ void PatternView::constructContextMenu( QMenu * _cm ) connect( a, SIGNAL( triggered( bool ) ), this, SLOT( openInPianoRoll() ) ); - if( gui->pianoRoll()->currentPattern() && - gui->pianoRoll()->currentPattern() != m_pat && - !m_pat->empty() ) + if( gui->pianoRoll()->currentPattern() && !m_pat->empty() ) { QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ), tr( "Set as ghost in piano-roll" ), _cm ); From 3d17200925275629363861018dbb1980eddfc4f4 Mon Sep 17 00:00:00 2001 From: CYBERDEViLNL Date: Wed, 6 Feb 2019 16:00:33 +0100 Subject: [PATCH 51/79] Better ghost notes context menu handling. --- src/tracks/Pattern.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index 33044cf3b..32baf0b14 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -676,20 +676,13 @@ void PatternView::constructContextMenu( QMenu * _cm ) connect( a, SIGNAL( triggered( bool ) ), this, SLOT( openInPianoRoll() ) ); - if( gui->pianoRoll()->currentPattern() && !m_pat->empty() ) - { - QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ), + QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ), tr( "Set as ghost in piano-roll" ), _cm ); - _cm->insertAction( _cm->actions()[1], b ); - connect( b, SIGNAL( triggered( bool ) ), - this, SLOT( setGhostInPianoRoll() ) ); - _cm->insertSeparator( _cm->actions()[2] ); - } - else - { - _cm->insertSeparator( _cm->actions()[1] ); - } - + if( m_pat->empty() ) { b->setEnabled( false ); } + _cm->insertAction( _cm->actions()[1], b ); + connect( b, SIGNAL( triggered( bool ) ), + this, SLOT( setGhostInPianoRoll() ) ); + _cm->insertSeparator( _cm->actions()[2] ); _cm->addSeparator(); _cm->addAction( embed::getIconPixmap( "edit_erase" ), From bbedfa9ec5c6643c9ef9ffb36d08518e5f5f3d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Fri, 8 Feb 2019 23:41:24 -0500 Subject: [PATCH 52/79] Fix Linux HiDPI handling Fix HiDPI order of operations, remove shortcut technique --- cmake/linux/lmms.desktop | 2 +- src/core/main.cpp | 4 +++- src/gui/GuiApplication.cpp | 5 ----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cmake/linux/lmms.desktop b/cmake/linux/lmms.desktop index 67e9c2f11..4f8000d29 100644 --- a/cmake/linux/lmms.desktop +++ b/cmake/linux/lmms.desktop @@ -8,7 +8,7 @@ Comment=Music sequencer and synthesizer Comment[ca]=Producció fàcil de música per a tothom! Comment[fr]=Production facile de musique pour tout le monde ! Icon=lmms -Exec=env QT_X11_NO_NATIVE_MENUBAR=1 QT_AUTO_SCREEN_SCALE_FACTOR=1 lmms %f +Exec=env QT_X11_NO_NATIVE_MENUBAR=1 lmms %f Terminal=false Type=Application Categories=Qt;AudioVideo;Audio;Midi; diff --git a/src/core/main.cpp b/src/core/main.cpp index 45f2bb66b..a71461799 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -252,7 +252,9 @@ int main( int argc, char * * argv ) return EXIT_FAILURE; } #endif - +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif QCoreApplication * app = coreOnly ? new QCoreApplication( argc, argv ) : new MainApplication( argc, argv ); diff --git a/src/gui/GuiApplication.cpp b/src/gui/GuiApplication.cpp index 2c577868c..c33fbf0a2 100644 --- a/src/gui/GuiApplication.cpp +++ b/src/gui/GuiApplication.cpp @@ -54,11 +54,6 @@ GuiApplication* GuiApplication::instance() GuiApplication::GuiApplication() { - // enable HiDPI scaling before showing anything (Qt 5.6+ only) - #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); - #endif - // prompt the user to create the LMMS working directory (e.g. ~/Documents/lmms) if it doesn't exist if ( !ConfigManager::inst()->hasWorkingDir() && QMessageBox::question( NULL, From 29c210128a18fc48fe9771ae3b33b1eab7b0f92a Mon Sep 17 00:00:00 2001 From: Mister-Lemon Date: Sat, 9 Feb 2019 23:45:27 +0200 Subject: [PATCH 53/79] Step Recording feature (#4544) (Addresses #1421) **Behaviour description:** * Toggle step-recording mode using the dedicated icon. * This mode is mutually exclusive with other recoding modes (record/record accompany). * Step-Recording while song is playing is allowed (and fun! :) ). * When start recording, the start recording-position will be set where the timeline curser points (quantized backwards using PianoRoll's current quantization). If step-recording is started while the pattern is playing the start recording-position is set to the beginning of the pattern. * Step length is determined by the Piano Roll's current note-length (can be changed dynamically during step-recording). * The record-position can be moved forward/backward using the right/left keys. * When notes are pressed on keyboard/midi-device, they will be added temporarily ("recorded") with a length of a step. while still pressed, user can adjust the length by steps resolution using the arrow keys (e.g. moving right once will make the note's length 2-steps, another right press will make the length 3-steps etc.). * When all pressed-keys are released, the actual recording happen and the notes are added. * If the user press multiple notes, and release some of them for some time which indicates it is intentional i.e. he didn't want to do a full release to record the step but rather just change what will be recorded (I set the "intentional release threshold" to 70 milliseconds) - these note will be removed from current step-recording. e.g. * Added notes are not quantized, making the addition simpler and WYSIWYG * Similiarly to adding notes using mouse clicks, an undo-checkpoint is added per added step and not for the whole recording as in other record modes. --- data/themes/classic/record_step_off.png | Bin 0 -> 443 bytes data/themes/classic/record_step_on.png | Bin 0 -> 596 bytes data/themes/default/record_step_off.png | Bin 0 -> 443 bytes data/themes/default/record_step_on.png | Bin 0 -> 596 bytes include/Editor.h | 4 +- include/PianoRoll.h | 19 +- include/StepRecorder.h | 143 +++++++++ include/StepRecorderWidget.h | 92 ++++++ src/core/CMakeLists.txt | 1 + src/core/StepRecorder.cpp | 366 ++++++++++++++++++++++++ src/gui/CMakeLists.txt | 1 + src/gui/editors/Editor.cpp | 9 +- src/gui/editors/PianoRoll.cpp | 235 ++++++++++++--- src/gui/editors/SongEditor.cpp | 2 +- src/gui/widgets/StepRecorderWidget.cpp | 155 ++++++++++ 15 files changed, 987 insertions(+), 40 deletions(-) create mode 100644 data/themes/classic/record_step_off.png create mode 100644 data/themes/classic/record_step_on.png create mode 100644 data/themes/default/record_step_off.png create mode 100644 data/themes/default/record_step_on.png create mode 100644 include/StepRecorder.h create mode 100644 include/StepRecorderWidget.h create mode 100644 src/core/StepRecorder.cpp create mode 100644 src/gui/widgets/StepRecorderWidget.cpp diff --git a/data/themes/classic/record_step_off.png b/data/themes/classic/record_step_off.png new file mode 100644 index 0000000000000000000000000000000000000000..8da17a91009f9ee65a28f29d4e8d2ce3ea073eb0 GIT binary patch literal 443 zcmV;s0Yv_ZP)!40j=$PgAl~tMmtNfu&@zHqfcQ9pFjkQ zAVLZWOd!b2d^QtVH$S_DN-iu6?7ionyZ76X<~_``7uMQpsZ=^N#?*~5+mZx40-fP- zcvCKy-*b0y&NaOEJ*I^BzUQ24;reBq^VA= zwbj&^%~{Qp<6CR1liamZ6IEj21JDOPffwKk*h(fk=UOA3;`h3Zsi%4@N$N{_i|2x* z&G;PsKxMpE3L$h;4zGbibXfs*fn(q)y_^t2H;*8|GjIy*0V`4502i5p-ure2B>}jN zqN^!<+9REX#MU~g9yLjql3pb_NrU(;70;ScJC02TG6$L1OaS{nLc9hPfn}fuoB$u0 lVE@Ul_ZyeP|6E^l6<_1QUov$MTMqyL002ovPDHLkV1mZ_vFiW; literal 0 HcmV?d00001 diff --git a/data/themes/classic/record_step_on.png b/data/themes/classic/record_step_on.png new file mode 100644 index 0000000000000000000000000000000000000000..700ba97f3056a189e4b3667da25885dfcf6e2034 GIT binary patch literal 596 zcmV-a0;~OrP))TL%$N3 zqw6pG0bKyr^%tI$ZNt!grP4v3Z&U18><>25UfMXbG zf2s7TXU|+TS5_W-G5MGNSw63|?+4nOplRj?YPGRW#^mH107)cvWq7zQfk0E@@t?A^ z^jbDH?sWiawXvXS=Gtd}hkK{YNekKs8V%rfcE6&Nu1NQcwP_N(iH1>6U iy=xy1|7U#NsQ3$`99L@!40j=$PgAl~tMmtNfu&@zHqfcQ9pFjkQ zAVLZWOd!b2d^QtVH$S_DN-iu6?7ionyZ76X<~_``7uMQpsZ=^N#?*~5+mZx40-fP- zcvCKy-*b0y&NaOEJ*I^BzUQ24;reBq^VA= zwbj&^%~{Qp<6CR1liamZ6IEj21JDOPffwKk*h(fk=UOA3;`h3Zsi%4@N$N{_i|2x* z&G;PsKxMpE3L$h;4zGbibXfs*fn(q)y_^t2H;*8|GjIy*0V`4502i5p-ure2B>}jN zqN^!<+9REX#MU~g9yLjql3pb_NrU(;70;ScJC02TG6$L1OaS{nLc9hPfn}fuoB$u0 lVE@Ul_ZyeP|6E^l6<_1QUov$MTMqyL002ovPDHLkV1mZ_vFiW; literal 0 HcmV?d00001 diff --git a/data/themes/default/record_step_on.png b/data/themes/default/record_step_on.png new file mode 100644 index 0000000000000000000000000000000000000000..700ba97f3056a189e4b3667da25885dfcf6e2034 GIT binary patch literal 596 zcmV-a0;~OrP))TL%$N3 zqw6pG0bKyr^%tI$ZNt!grP4v3Z&U18><>25UfMXbG zf2s7TXU|+TS5_W-G5MGNSw63|?+4nOplRj?YPGRW#^mH107)cvWq7zQfk0E@@t?A^ z^jbDH?sWiawXvXS=Gtd}hkK{YNekKs8V%rfcE6&Nu1NQcwP_N(iH1>6U iy=xy1|7U#NsQ3$`99L@ +#include +#include +#include + +#include "Note.h" +#include "lmms_basics.h" +#include "Pattern.h" + +class PianoRoll; +class StepRecorderWidget; + +class StepRecorder : public QObject +{ + Q_OBJECT + + public: + StepRecorder(PianoRoll& pianoRoll, StepRecorderWidget& stepRecorderWidget); + + void initialize(); + void start(const MidiTime& currentPosition,const MidiTime& stepLength); + void stop(); + void notePressed(const Note & n); + void noteReleased(const Note & n); + bool keyPressEvent(QKeyEvent* ke); + bool mousePressEvent(QMouseEvent* ke); + void setCurrentPattern(Pattern* newPattern); + void setStepsLength(const MidiTime& newLength); + + QVector getCurStepNotes(); + + bool isRecording() const + { + return m_isRecording; + } + + QColor curStepNoteColor() const + { + return QColor(245,3,139); // radiant pink + } + + private slots: + void removeNotesReleasedForTooLong(); + + private: + void stepForwards(); + void stepBackwards(); + + void applyStep(); + void dismissStep(); + void prepareNewStep(); + + MidiTime getCurStepEndPos(); + + void updateCurStepNotes(); + void updateWidget(); + + bool allCurStepNotesReleased(); + + PianoRoll& m_pianoRoll; + StepRecorderWidget& m_stepRecorderWidget; + + bool m_isRecording = false; + MidiTime m_curStepStartPos = 0; + MidiTime m_curStepEndPos = 0; + + MidiTime m_stepsLength; + MidiTime m_curStepLength; // current step length refers to the step currently recorded. it may defer from m_stepsLength + // since the user can make current step larger + + QTimer m_updateReleasedTimer; + + Pattern* m_pattern; + + class StepNote + { + public: + StepNote(const Note & note) : m_note(note), m_pressed(true) {}; + + void setPressed() + { + m_pressed = true; + } + + void setReleased() + { + m_pressed = false; + releasedTimer.start(); + } + + int timeSinceReleased() + { + return releasedTimer.elapsed(); + } + + bool isPressed() const + { + return m_pressed; + } + + bool isReleased() const + { + return !m_pressed; + } + + Note m_note; + + private: + bool m_pressed; + QTime releasedTimer; + } ; + + QVector m_curStepNotes; // contains the current recorded step notes (i.e. while user still press the notes; before they are applied to the pattern) + + StepNote* findCurStepNote(const int key); + + bool m_isStepInProgress = false; +}; + +#endif //STEP_RECORDER_H \ No newline at end of file diff --git a/include/StepRecorderWidget.h b/include/StepRecorderWidget.h new file mode 100644 index 000000000..0e4512169 --- /dev/null +++ b/include/StepRecorderWidget.h @@ -0,0 +1,92 @@ +/* + * StepRecorderWidget.h - widget that provide gui markers for step recording + * + * 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 STEP_RECOREDER_WIDGET_H +#define STEP_RECOREDER_WIDGET_H + +#include "lmms_basics.h" +#include "Note.h" + +#include +#include +#include + +class StepRecorderWidget : public QWidget +{ + Q_OBJECT + +public: + StepRecorderWidget( + QWidget * parent, + const int ppt, + const int marginTop, + const int marginBottom, + const int marginLeft, + const int marginRight); + + //API used by PianoRoll + void setPixelsPerTact(int ppt); + void setCurrentPosition(MidiTime currentPosition); + void setBottomMargin(const int marginBottom); + + //API used by StepRecorder + void setStepsLength(MidiTime stepsLength); + void setStartPosition(MidiTime pos); + void setEndPosition(MidiTime pos); + + void showHint(); + +private: + virtual void paintEvent(QPaintEvent * pe); + + int xCoordOfTick(int tick); + + void drawVerLine(QPainter* painter, int x, const QColor& color, int top, int bottom); + void drawVerLine(QPainter* painter, const MidiTime& pos, const QColor& color, int top, int bottom); + + void updateBoundaries(); + + MidiTime m_stepsLength; + MidiTime m_curStepStartPos; + MidiTime m_curStepEndPos; + + int m_ppt; // pixels per tact + MidiTime m_currentPosition; // current position showed by on PianoRoll + + QColor m_colorLineStart; + QColor m_colorLineEnd; + + // boundaries within piano roll window + int m_top; + int m_bottom; + int m_left; + int m_right; + + const int m_marginTop; + int m_marginBottom; // not const since can change on resize of edit-note area + const int m_marginLeft; + const int m_marginRight; + +signals: + void positionChanged(const MidiTime & t); +} ; + +#endif //STEP_RECOREDER_WIDGET_H diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 85a00780b..7870415f9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -67,6 +67,7 @@ set(LMMS_SRCS core/TrackContainer.cpp core/ValueBuffer.cpp core/VstSyncController.cpp + core/StepRecorder.cpp core/audio/AudioAlsa.cpp core/audio/AudioDevice.cpp diff --git a/src/core/StepRecorder.cpp b/src/core/StepRecorder.cpp new file mode 100644 index 000000000..7a63e88e2 --- /dev/null +++ b/src/core/StepRecorder.cpp @@ -0,0 +1,366 @@ +/* + * 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 "StepRecorder.h" +#include "StepRecorderWidget.h" +#include "PianoRoll.h" + +#include + +#include +using std::min; +using std::max; + +const int REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS = 70; + +StepRecorder::StepRecorder(PianoRoll& pianoRoll, StepRecorderWidget& stepRecorderWidget): + m_pianoRoll(pianoRoll), + m_stepRecorderWidget(stepRecorderWidget) +{ + m_stepRecorderWidget.hide(); +} + +void StepRecorder::initialize() +{ + connect(&m_updateReleasedTimer, SIGNAL(timeout()), this, SLOT(removeNotesReleasedForTooLong())); +} + +void StepRecorder::start(const MidiTime& currentPosition, const MidiTime& stepLength) +{ + m_isRecording = true; + + setStepsLength(stepLength); + + // quantize current position to get start recording position + const int q = m_pianoRoll.quantization(); + const int curPosTicks = currentPosition.getTicks(); + const int QuantizedPosTicks = (curPosTicks / q) * q; + const MidiTime& QuantizedPos = MidiTime(QuantizedPosTicks); + + m_curStepStartPos = QuantizedPos; + m_curStepLength = 0; + + m_stepRecorderWidget.show(); + + m_stepRecorderWidget.showHint(); + + prepareNewStep(); +} + +void StepRecorder::stop() +{ + m_stepRecorderWidget.hide(); + m_isRecording = false; +} + +void StepRecorder::notePressed(const Note & n) +{ + //if this is the first pressed note in step, advance position + if(!m_isStepInProgress) + { + m_isStepInProgress = true; + + //move curser one step forwards + stepForwards(); + } + + StepNote* stepNote = findCurStepNote(n.key()); + if(stepNote == nullptr) + { + m_curStepNotes.append(new StepNote(Note(m_curStepLength, m_curStepStartPos, n.key(), n.getVolume(), n.getPanning()))); + m_pianoRoll.update(); + } + else if (stepNote->isReleased()) + { + stepNote->setPressed(); + } +} + +void StepRecorder::noteReleased(const Note & n) +{ + StepNote* stepNote = findCurStepNote(n.key()); + + if(stepNote != nullptr && stepNote->isPressed()) + { + stepNote->setReleased(); + + //if m_updateReleasedTimer is not already active, activate it + //(when activated, the timer will re-set itself as long as there are released notes) + if(!m_updateReleasedTimer.isActive()) + { + m_updateReleasedTimer.start(REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS); + } + + //check if all note are released, apply notes to pattern(or dimiss if length is zero) and prepare to record next step + if(allCurStepNotesReleased()) + { + if(m_curStepLength > 0) + { + applyStep(); + } + else + { + dismissStep(); + } + } + } +} + +bool StepRecorder::keyPressEvent(QKeyEvent* ke) +{ + bool event_handled = false; + + switch(ke->key()) + { + case Qt::Key_Right: + { + if(!ke->isAutoRepeat()) + { + stepForwards(); + } + event_handled = true; + break; + } + + case Qt::Key_Left: + { + if(!ke->isAutoRepeat()) + { + stepBackwards(); + } + event_handled = true; + break; + } + } + + return event_handled; +} + +void StepRecorder::setStepsLength(const MidiTime& newLength) +{ + if(m_isStepInProgress) + { + //update current step length by the new amount : (number_of_steps * newLength) + m_curStepLength = (m_curStepLength / m_stepsLength) * newLength; + + updateCurStepNotes(); + } + + m_stepsLength = newLength; + + updateWidget(); +} + +QVector StepRecorder::getCurStepNotes() +{ + QVector notes; + + if(m_isStepInProgress) + { + for(StepNote* stepNote: m_curStepNotes) + { + notes.append(&stepNote->m_note); + } + } + + return notes; +} + +void StepRecorder::stepForwards() +{ + if(m_isStepInProgress) + { + m_curStepLength += m_stepsLength; + + updateCurStepNotes(); + } + else + { + m_curStepStartPos += m_stepsLength; + } + + updateWidget(); +} + +void StepRecorder::stepBackwards() +{ + if(m_isStepInProgress) + { + if(m_curStepLength > 0) + { + m_curStepLength = max(m_curStepLength - m_stepsLength, 0); + } + else + { + //if length is already zero - move starting position backwards + m_curStepStartPos = max(m_curStepStartPos - m_stepsLength, 0); + } + + updateCurStepNotes(); + } + else + { + m_curStepStartPos = max(m_curStepStartPos - m_stepsLength, 0); + } + + updateWidget(); +} + +void StepRecorder::applyStep() +{ + m_pattern->addJournalCheckPoint(); + + for (const StepNote* stepNote : m_curStepNotes) + { + m_pattern->addNote(stepNote->m_note, false); + } + + m_pattern->rearrangeAllNotes(); + m_pattern->updateLength(); + m_pattern->dataChanged(); + Engine::getSong()->setModified(); + + prepareNewStep(); +} + +void StepRecorder::dismissStep() +{ + if(!m_isStepInProgress) + { + return; + } + + prepareNewStep(); +} + +void StepRecorder::prepareNewStep() +{ + for(StepNote* stepNote : m_curStepNotes) + { + delete stepNote; + } + m_curStepNotes.clear(); + + m_isStepInProgress = false; + + m_curStepStartPos = getCurStepEndPos(); + m_curStepLength = 0; + + updateWidget(); +} + +void StepRecorder::setCurrentPattern( Pattern* newPattern ) +{ + if(m_pattern != NULL && m_pattern != newPattern) + { + dismissStep(); + } + + m_pattern = newPattern; +} + +void StepRecorder::removeNotesReleasedForTooLong() +{ + int nextTimout = std::numeric_limits::max(); + bool notesRemoved = false; + + QMutableVectorIterator itr(m_curStepNotes); + while (itr.hasNext()) + { + StepNote* stepNote = itr.next(); + + if(stepNote->isReleased()) + { + const int timeSinceReleased = stepNote->timeSinceReleased(); // capture value to avoid wraparound when calculting nextTimout + if (timeSinceReleased >= REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS) + { + delete stepNote; + itr.remove(); + notesRemoved = true; + } + else + { + nextTimout = min(nextTimout, REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS - timeSinceReleased); + } + } + } + + if(notesRemoved) + { + m_pianoRoll.update(); + } + + if(nextTimout != std::numeric_limits::max()) + { + m_updateReleasedTimer.start(nextTimout); + } + else + { + // no released note found for next timout, stop timer + m_updateReleasedTimer.stop(); + } +} + +MidiTime StepRecorder::getCurStepEndPos() +{ + return m_curStepStartPos + m_curStepLength; +} + +void StepRecorder::updateCurStepNotes() +{ + for (StepNote* stepNote : m_curStepNotes) + { + stepNote->m_note.setLength(m_curStepLength); + stepNote->m_note.setPos(m_curStepStartPos); + } +} + +void StepRecorder::updateWidget() +{ + m_stepRecorderWidget.setStartPosition(m_curStepStartPos); + m_stepRecorderWidget.setEndPosition(getCurStepEndPos()); + m_stepRecorderWidget.setStepsLength(m_stepsLength); +} + +bool StepRecorder::allCurStepNotesReleased() +{ + for (const StepNote* stepNote : m_curStepNotes) + { + if(stepNote->isPressed()) + { + return false; + } + } + + return true; +} + +StepRecorder::StepNote* StepRecorder::findCurStepNote(const int key) +{ + for (StepNote* stepNote : m_curStepNotes) + { + if(stepNote->m_note.key() == key) + { + return stepNote; + } + } + + return nullptr; +} diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 5b4050bca..d5ff64612 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -87,6 +87,7 @@ SET(LMMS_SRCS gui/widgets/TrackLabelButton.cpp gui/widgets/TrackRenameLineEdit.cpp gui/widgets/VisualizationWidget.cpp + gui/widgets/StepRecorderWidget.cpp PARENT_SCOPE ) diff --git a/src/gui/editors/Editor.cpp b/src/gui/editors/Editor.cpp index bdc3e55d4..b82453acf 100644 --- a/src/gui/editors/Editor.cpp +++ b/src/gui/editors/Editor.cpp @@ -73,11 +73,12 @@ void Editor::togglePlayStop() play(); } -Editor::Editor(bool record) : +Editor::Editor(bool record, bool stepRecord) : m_toolBar(new DropToolBar(this)), m_playAction(nullptr), m_recordAction(nullptr), m_recordAccompanyAction(nullptr), + m_toggleStepRecordingAction(nullptr), m_stopAction(nullptr) { m_toolBar = addDropToolBarToTop(tr("Transport controls")); @@ -93,11 +94,13 @@ Editor::Editor(bool record) : m_recordAction = new QAction(embed::getIconPixmap("record"), tr("Record"), this); m_recordAccompanyAction = new QAction(embed::getIconPixmap("record_accompany"), tr("Record while playing"), this); + m_toggleStepRecordingAction = new QAction(embed::getIconPixmap("record_step_off"), tr("Toggle Step Recording"), this); // Set up connections connect(m_playAction, SIGNAL(triggered()), this, SLOT(play())); connect(m_recordAction, SIGNAL(triggered()), this, SLOT(record())); connect(m_recordAccompanyAction, SIGNAL(triggered()), this, SLOT(recordAccompany())); + connect(m_toggleStepRecordingAction, SIGNAL(triggered()), this, SLOT(toggleStepRecording())); connect(m_stopAction, SIGNAL(triggered()), this, SLOT(stop())); new QShortcut(Qt::Key_Space, this, SLOT(togglePlayStop())); @@ -108,6 +111,10 @@ Editor::Editor(bool record) : addButton(m_recordAction, "recordButton"); addButton(m_recordAccompanyAction, "recordAccompanyButton"); } + if(stepRecord) + { + addButton(m_toggleStepRecordingAction, "stepRecordButton"); + } addButton(m_stopAction, "stopButton"); } diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index b773724ea..4cda5c522 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -62,6 +62,7 @@ #include "stdshims.h" #include "TextFloat.h" #include "TimeLineWidget.h" +#include "StepRecorderWidget.h" using std::move; @@ -177,6 +178,8 @@ PianoRoll::PianoRoll() : m_ctrlMode( ModeDraw ), m_mouseDownRight( false ), m_scrollBack( false ), + m_stepRecorderWidget(this, DEFAULT_PR_PPT, PR_TOP_MARGIN, PR_BOTTOM_MARGIN + m_notesEditHeight, WHITE_KEY_WIDTH, 0), + m_stepRecorder(*this, m_stepRecorderWidget), m_barLineColor( 0, 0, 0 ), m_beatLineColor( 0, 0, 0 ), m_lineColor( 0, 0, 0 ), @@ -323,6 +326,10 @@ PianoRoll::PianoRoll() : connect( m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), this, SLOT( updatePosition( const MidiTime & ) ) ); + //update timeline when in step-recording mode + connect( &m_stepRecorderWidget, SIGNAL( positionChanged( const MidiTime & ) ), + this, SLOT( updatePositionStepRecording( const MidiTime & ) ) ); + // update timeline when in record-accompany mode connect( Engine::getSong()->getPlayPos( Song::Mode_PlaySong ).m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), @@ -395,7 +402,7 @@ PianoRoll::PianoRoll() : // Note length change can cause a redraw if Q is set to lock connect( &m_noteLenModel, SIGNAL( dataChanged() ), - this, SLOT( quantizeChanged() ) ); + this, SLOT( noteLengthChanged() ) ); // Set up scale model const InstrumentFunctionNoteStacking::ChordTable& chord_table = @@ -444,6 +451,8 @@ PianoRoll::PianoRoll() : //connection for selecion from timeline connect( m_timeLine, SIGNAL( regionSelectedFromPixels( int, int ) ), this, SLOT( selectRegionFromPixels( int, int ) ) ); + + m_stepRecorder.initialize(); } @@ -660,12 +669,19 @@ void PianoRoll::setCurrentPattern( Pattern* newPattern ) Engine::getSong()->playPattern( NULL ); } + if(m_stepRecorder.isRecording()) + { + m_stepRecorder.stop(); + } + // set new data m_pattern = newPattern; m_currentPosition = 0; m_currentNote = NULL; m_startKey = INITIAL_START_KEY; + m_stepRecorder.setCurrentPattern(newPattern); + if( ! hasValidPattern() ) { //resizeEvent( NULL ); @@ -1153,8 +1169,19 @@ int PianoRoll::selectionCount() const // how many notes are selected? -void PianoRoll::keyPressEvent(QKeyEvent* ke ) +void PianoRoll::keyPressEvent(QKeyEvent* ke) { + if(m_stepRecorder.isRecording()) + { + bool handled = m_stepRecorder.keyPressEvent(ke); + if(handled) + { + ke->accept(); + update(); + return; + } + } + if( hasValidPattern() && ke->modifiers() == Qt::NoModifier ) { const int key_num = PianoView::getKeyFromKeyEvent( ke ) + ( DefaultOctave - 1 ) * KeysPerOctave; @@ -1903,7 +1930,7 @@ void PianoRoll::testPlayNote( Note * n ) { m_lastKey = n->key(); - if( ! n->isPlaying() && ! m_recording ) + if( ! n->isPlaying() && ! m_recording && ! m_stepRecorder.isRecording()) { n->setIsPlaying( true ); @@ -2136,6 +2163,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) NOTE_EDIT_MIN_HEIGHT, height() - PR_TOP_MARGIN - NOTE_EDIT_RESIZE_BAR - PR_BOTTOM_MARGIN - KEY_AREA_MIN_HEIGHT ); + + m_stepRecorderWidget.setBottomMargin(PR_BOTTOM_MARGIN + m_notesEditHeight); repaint(); return; } @@ -3226,6 +3255,41 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) } } + //draw current step recording notes + for( const Note *note : m_stepRecorder.getCurStepNotes() ) + { + int len_ticks = note->length(); + + if( len_ticks == 0 ) + { + continue; + } + + const int key = note->key() - m_startKey + 1; + + int pos_ticks = note->pos(); + + int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + const int x = ( pos_ticks - m_currentPosition ) * + m_ppt / MidiTime::ticksPerTact(); + // skip this note if not in visible area at all + if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) + { + continue; + } + + // is the note in visible area? + if( key > 0 && key <= visible_keys ) + { + + // we've done and checked all, let's draw the note + drawNoteRect( p, x + WHITE_KEY_WIDTH, + y_base - key * KEY_LINE_HEIGHT, + note_width, note, m_stepRecorder.curStepNoteColor(), noteTextColor(), selectedNoteColor(), + noteOpacity(), noteBorders(), drawNoteNames ); + } + } + p.setPen( QPen( noteColor(), NOTE_EDIT_LINE_WIDTH + 2 ) ); p.drawPoints( editHandles ); @@ -3625,6 +3689,34 @@ void PianoRoll::recordAccompany() +bool PianoRoll::toggleStepRecording() +{ + if(m_stepRecorder.isRecording()) + { + m_stepRecorder.stop(); + } + else + { + if(hasValidPattern()) + { + if(Engine::getSong()->isPlaying()) + { + m_stepRecorder.start(0, newNoteLen()); + } + else + { + m_stepRecorder.start( + Engine::getSong()->getPlayPos( + Song::Mode_PlayPattern), newNoteLen()); + } + } + } + + return m_stepRecorder.isRecording();; +} + + + void PianoRoll::stop() { @@ -3638,22 +3730,29 @@ void PianoRoll::stop() void PianoRoll::startRecordNote(const Note & n ) { - if( m_recording && hasValidPattern() && + if(hasValidPattern()) + { + if( m_recording && Engine::getSong()->isPlaying() && (Engine::getSong()->playMode() == desiredPlayModeForAccompany() || - Engine::getSong()->playMode() == Song::Mode_PlayPattern )) - { - MidiTime sub; - if( Engine::getSong()->playMode() == Song::Mode_PlaySong ) + Engine::getSong()->playMode() == Song::Mode_PlayPattern )) { - sub = m_pattern->startPosition(); + MidiTime sub; + if( Engine::getSong()->playMode() == Song::Mode_PlaySong ) + { + sub = m_pattern->startPosition(); + } + Note n1( 1, Engine::getSong()->getPlayPos( + Engine::getSong()->playMode() ) - sub, + n.key(), n.getVolume(), n.getPanning() ); + if( n1.pos() >= 0 ) + { + m_recordingNotes << n1; + } } - Note n1( 1, Engine::getSong()->getPlayPos( - Engine::getSong()->playMode() ) - sub, - n.key(), n.getVolume(), n.getPanning() ); - if( n1.pos() >= 0 ) + else if (m_stepRecorder.isRecording()) { - m_recordingNotes << n1; + m_stepRecorder.notePressed(n); } } } @@ -3663,28 +3762,35 @@ void PianoRoll::startRecordNote(const Note & n ) void PianoRoll::finishRecordNote(const Note & n ) { - if( m_recording && hasValidPattern() && - Engine::getSong()->isPlaying() && - ( Engine::getSong()->playMode() == - desiredPlayModeForAccompany() || - Engine::getSong()->playMode() == - Song::Mode_PlayPattern ) ) + if(hasValidPattern()) { - for( QList::Iterator it = m_recordingNotes.begin(); - it != m_recordingNotes.end(); ++it ) + if( m_recording && + Engine::getSong()->isPlaying() && + ( Engine::getSong()->playMode() == + desiredPlayModeForAccompany() || + Engine::getSong()->playMode() == + Song::Mode_PlayPattern ) ) { - if( it->key() == n.key() ) + for( QList::Iterator it = m_recordingNotes.begin(); + it != m_recordingNotes.end(); ++it ) { - Note n1( n.length(), it->pos(), - it->key(), it->getVolume(), - it->getPanning() ); - n1.quantizeLength( quantization() ); - m_pattern->addNote( n1 ); - update(); - m_recordingNotes.erase( it ); - break; + if( it->key() == n.key() ) + { + Note n1( n.length(), it->pos(), + it->key(), it->getVolume(), + it->getPanning() ); + n1.quantizeLength( quantization() ); + m_pattern->addNote( n1 ); + update(); + m_recordingNotes.erase( it ); + break; + } } } + else if (m_stepRecorder.isRecording()) + { + m_stepRecorder.noteReleased(n); + } } } @@ -3694,6 +3800,7 @@ void PianoRoll::finishRecordNote(const Note & n ) void PianoRoll::horScrolled(int new_pos ) { m_currentPosition = new_pos; + m_stepRecorderWidget.setCurrentPosition(m_currentPosition); emit positionChanged( m_currentPosition ); update(); } @@ -4064,6 +4171,13 @@ void PianoRoll::updatePositionAccompany( const MidiTime & t ) } +void PianoRoll::updatePositionStepRecording( const MidiTime & t ) +{ + if( m_stepRecorder.isRecording() ) + { + autoScroll( t ); + } +} void PianoRoll::zoomingChanged() @@ -4073,6 +4187,8 @@ void PianoRoll::zoomingChanged() assert( m_ppt > 0 ); m_timeLine->setPixelsPerTact( m_ppt ); + m_stepRecorderWidget.setPixelsPerTact( m_ppt ); + update(); } @@ -4084,7 +4200,11 @@ void PianoRoll::quantizeChanged() update(); } - +void PianoRoll::noteLengthChanged() +{ + m_stepRecorder.setStepsLength(newNoteLen()); + update(); +} int PianoRoll::quantization() const @@ -4221,7 +4341,7 @@ Note * PianoRoll::noteUnderMouse() PianoRollWindow::PianoRollWindow() : - Editor(true), + Editor(true, true), m_editor(new PianoRoll()) { setCentralWidget( m_editor ); @@ -4229,6 +4349,7 @@ PianoRollWindow::PianoRollWindow() : m_playAction->setToolTip(tr( "Play/pause current pattern (Space)" ) ); m_recordAction->setToolTip(tr( "Record notes from MIDI-device/channel-piano" ) ); m_recordAccompanyAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano while playing song or BB track" ) ); + m_toggleStepRecordingAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano, one step at the time" ) ); m_stopAction->setToolTip( tr( "Stop playing of current pattern (Space)" ) ); DropToolBar *notesActionsToolBar = addDropToolBarToTop( tr( "Edit actions" ) ); @@ -4375,7 +4496,7 @@ PianoRollWindow::PianoRollWindow() : // Connections connect( m_editor, SIGNAL( currentPatternChanged() ), this, SIGNAL( currentPatternChanged() ) ); - connect( m_editor, SIGNAL( currentPatternChanged() ), this, SLOT( patternRenamed() ) ); + connect( m_editor, SIGNAL( currentPatternChanged() ), this, SLOT( updateAfterPatternChange() ) ); } @@ -4404,8 +4525,8 @@ void PianoRollWindow::setCurrentPattern( Pattern* pattern ) if ( pattern ) { setWindowTitle( tr( "Piano-Roll - %1" ).arg( pattern->name() ) ); - connect( pattern->instrumentTrack(), SIGNAL( nameChanged() ), this, SLOT( patternRenamed()) ); - connect( pattern, SIGNAL( dataChanged() ), this, SLOT( patternRenamed() ) ); + connect( pattern->instrumentTrack(), SIGNAL( nameChanged() ), this, SLOT( updateAfterPatternChange()) ); + connect( pattern, SIGNAL( dataChanged() ), this, SLOT( updateAfterPatternChange() ) ); } else { @@ -4450,6 +4571,8 @@ void PianoRollWindow::stop() void PianoRollWindow::record() { + stopStepRecording(); //step recording mode is mutually exclusive with other record modes + m_editor->record(); } @@ -4458,11 +4581,25 @@ void PianoRollWindow::record() void PianoRollWindow::recordAccompany() { + stopStepRecording(); //step recording mode is mutually exclusive with other record modes + m_editor->recordAccompany(); } +void PianoRollWindow::toggleStepRecording() +{ + if(isRecording()) + { + // step recording mode is mutually exclusive with other record modes + // stop them before starting step recording + stop(); + } + m_editor->toggleStepRecording(); + + updateStepRecordingIcon(); +} void PianoRollWindow::stopRecording() { @@ -4520,6 +4657,11 @@ QSize PianoRollWindow::sizeHint() const +void PianoRollWindow::updateAfterPatternChange() +{ + patternRenamed(); + updateStepRecordingIcon(); //pattern change turn step recording OFF - update icon accordingly +} void PianoRollWindow::patternRenamed() { @@ -4549,3 +4691,24 @@ void PianoRollWindow::focusInEvent( QFocusEvent * event ) // when the window is given focus, also give focus to the actual piano roll m_editor->setFocus( event->reason() ); } + +void PianoRollWindow::stopStepRecording() +{ + if(m_editor->isStepRecording()) + { + m_editor->toggleStepRecording(); + updateStepRecordingIcon(); + } +} + +void PianoRollWindow::updateStepRecordingIcon() +{ + if(m_editor->isStepRecording()) + { + m_toggleStepRecordingAction->setIcon(embed::getIconPixmap("record_step_on")); + } + else + { + m_toggleStepRecordingAction->setIcon(embed::getIconPixmap("record_step_off")); + } +} diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index a2e52e200..92a5c5fa5 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -654,7 +654,7 @@ ComboBoxModel *SongEditor::zoomingModel() const SongEditorWindow::SongEditorWindow(Song* song) : - Editor(Engine::mixer()->audioDev()->supportsCapture()), + Editor(Engine::mixer()->audioDev()->supportsCapture(), false), m_editor(new SongEditor(song)), m_crtlAction( NULL ) { diff --git a/src/gui/widgets/StepRecorderWidget.cpp b/src/gui/widgets/StepRecorderWidget.cpp new file mode 100644 index 000000000..f59e235fc --- /dev/null +++ b/src/gui/widgets/StepRecorderWidget.cpp @@ -0,0 +1,155 @@ +/* + * StepRecoderWidget.cpp - widget that provide gui markers for step recording + * + * 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 "StepRecorderWidget.h" +#include "TextFloat.h" +#include "embed.h" + +StepRecorderWidget::StepRecorderWidget( + QWidget * parent, + const int ppt, + const int marginTop, + const int marginBottom, + const int marginLeft, + const int marginRight) : + QWidget(parent), + m_marginTop(marginTop), + m_marginBottom(marginBottom), + m_marginLeft(marginLeft), + m_marginRight(marginRight) +{ + const QColor baseColor = QColor(255, 0, 0);// QColor(204, 163, 0); // Orange + m_colorLineEnd = baseColor.lighter(150); + m_colorLineStart = baseColor.darker(120); + + setAttribute(Qt::WA_NoSystemBackground, true); + setPixelsPerTact(ppt); + + m_top = m_marginTop; + m_left = m_marginLeft; +} + +void StepRecorderWidget::setPixelsPerTact(int ppt) +{ + m_ppt = ppt; +} + +void StepRecorderWidget::setCurrentPosition(MidiTime currentPosition) +{ + m_currentPosition = currentPosition; +} + +void StepRecorderWidget::setBottomMargin(const int marginBottom) +{ + m_marginBottom = marginBottom; +} + +void StepRecorderWidget::setStartPosition(MidiTime pos) +{ + m_curStepStartPos = pos; +} + +void StepRecorderWidget::setEndPosition(MidiTime pos) +{ + m_curStepEndPos = pos; + emit positionChanged(m_curStepEndPos); +} + +void StepRecorderWidget::showHint() +{ + TextFloat::displayMessage(tr( "Hint" ), tr("Move recording curser using arrows"), + embed::getIconPixmap("hint")); +} + +void StepRecorderWidget::setStepsLength(MidiTime stepsLength) +{ + m_stepsLength = stepsLength; +} + +void StepRecorderWidget::paintEvent(QPaintEvent * pe) +{ + QPainter painter(this); + + updateBoundaries(); + + move(0, 0); + + //draw steps ruler + painter.setPen(m_colorLineEnd); + + MidiTime curPos = m_curStepEndPos; + int x = xCoordOfTick(curPos); + while(x <= m_right) + { + const int w = 2; + const int h = 4; + painter.drawRect(x - 1, m_top, w, h); + curPos += m_stepsLength; + x = xCoordOfTick(curPos); + } + + //draw current step start/end position lines + if(m_curStepStartPos != m_curStepEndPos) + { + drawVerLine(&painter, m_curStepStartPos, m_colorLineStart, m_top, m_bottom); + } + + drawVerLine(&painter, m_curStepEndPos, m_colorLineEnd, m_top, m_bottom); + + //if the line is adjacent to the keyboard at the left - it cannot be seen. + //add another line to make it clearer + if(m_curStepEndPos == 0) + { + drawVerLine(&painter, xCoordOfTick(m_curStepEndPos) + 1, m_colorLineEnd, m_top, m_bottom); + } +} + +int StepRecorderWidget::xCoordOfTick(int tick) +{ + return m_marginLeft + ((tick - m_currentPosition) * m_ppt / MidiTime::ticksPerTact()); +} + + +void StepRecorderWidget::drawVerLine(QPainter* painter, int x, const QColor& color, int top, int bottom) +{ + if(x >= m_marginLeft && x <= (width() - m_marginRight)) + { + painter->setPen(color); + painter->drawLine( x, top, x, bottom ); + } +} + +void StepRecorderWidget::drawVerLine(QPainter* painter, const MidiTime& pos, const QColor& color, int top, int bottom) +{ + drawVerLine(painter, xCoordOfTick(pos), color, top, bottom); +} + +void StepRecorderWidget::updateBoundaries() +{ + setFixedSize(parentWidget()->size()); + + m_bottom = height() - m_marginBottom; + m_right = width() - m_marginTop; + + //(no need to change top and left as they are static) +} + From e94d1c91e9eaf92b5b33a1dbff89dc72ff1e8cce Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Mon, 11 Feb 2019 20:03:50 +0100 Subject: [PATCH 54/79] Move QT_X11_NO_NATIVE_MENUBAR to code (#4818) Set Qt::AA_DontUseNativeMenuBar Remove QT_X11_NO_NATIVE_MENUBAR from desktop launcher --- cmake/linux/lmms.desktop | 2 +- src/core/main.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/linux/lmms.desktop b/cmake/linux/lmms.desktop index 4f8000d29..2ef4c8148 100644 --- a/cmake/linux/lmms.desktop +++ b/cmake/linux/lmms.desktop @@ -8,7 +8,7 @@ Comment=Music sequencer and synthesizer Comment[ca]=Producció fàcil de música per a tothom! Comment[fr]=Production facile de musique pour tout le monde ! Icon=lmms -Exec=env QT_X11_NO_NATIVE_MENUBAR=1 lmms %f +Exec=lmms %f Terminal=false Type=Application Categories=Qt;AudioVideo;Audio;Midi; diff --git a/src/core/main.cpp b/src/core/main.cpp index a71461799..cc9cb4f2a 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -252,6 +252,10 @@ int main( int argc, char * * argv ) return EXIT_FAILURE; } #endif +#ifdef LMMS_BUILD_LINUX + // don't let OS steal the menu bar. FIXME: only effective on Qt4 + QCoreApplication::setAttribute( Qt::AA_DontUseNativeMenuBar ); +#endif #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif From fcacf443750f7cb83d38a4daaaa8adb2971ec3ef Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 12 Feb 2019 14:27:08 +0900 Subject: [PATCH 55/79] Ensure the restore button of a subwindow shows up correctly (#4819) * SubWindow: ensure the restore button shows up correctly * Remove old workaround for the maximize behavior on Mac --- include/SubWindow.h | 1 - src/gui/SubWindow.cpp | 22 ++++------------------ 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/include/SubWindow.h b/include/SubWindow.h index 99bd49552..ac5a4e63c 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -81,7 +81,6 @@ private: QGraphicsDropShadowEffect * m_shadow; static void elideText( QLabel *label, QString text ); - bool isMaximized(); void adjustTitleBar(); }; diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 0a0effc45..8341024b3 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -148,23 +148,6 @@ void SubWindow::elideText( QLabel *label, QString text ) -bool SubWindow::isMaximized() -{ -#ifdef LMMS_BUILD_APPLE - // check if subwindow size is identical to the MdiArea size, accounting for scrollbars - int hScrollBarHeight = mdiArea()->horizontalScrollBar()->isVisible() ? mdiArea()->horizontalScrollBar()->size().height() : 0; - int vScrollBarWidth = mdiArea()->verticalScrollBar()->isVisible() ? mdiArea()->verticalScrollBar()->size().width() : 0; - QSize areaSize( this->mdiArea()->size().width() - vScrollBarWidth, this->mdiArea()->size().height() - hScrollBarHeight ); - - return areaSize == this->size(); -#else - return QMdiSubWindow::isMaximized(); -#endif -} - - - - QRect SubWindow::getTrueNormalGeometry() const { return m_trackedNormalGeom; @@ -302,8 +285,11 @@ void SubWindow::adjustTitleBar() void SubWindow::resizeEvent( QResizeEvent * event ) { - adjustTitleBar(); + // When the parent QMdiArea gets resized, maximized subwindows also gets resized, if any. + // In that case, we should call QMdiSubWindow::resizeEvent first + // to ensure we get the correct window state. QMdiSubWindow::resizeEvent( event ); + adjustTitleBar(); // if the window was resized and ISN'T minimized/maximized/fullscreen, // then save the current size From 8d707df171fa89c8426dca2d0d42de744d5db365 Mon Sep 17 00:00:00 2001 From: Douglas <34612565+DouglasDGI@users.noreply.github.com> Date: Wed, 13 Feb 2019 11:46:47 -0700 Subject: [PATCH 56/79] Fix Bitinvader waveform cutoff behavior --- include/Graph.h | 1 + plugins/bit_invader/bit_invader.cpp | 36 ++++++++--------------------- src/gui/widgets/Graph.cpp | 10 +++++++- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/include/Graph.h b/include/Graph.h index 38e92a4b4..18a02df6e 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -165,6 +165,7 @@ public slots: void normalize(); void invert(); void shiftPhase( int _deg ); + void clearInvisible(); signals: void lengthChanged(); diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index 983df5ec2..4e7945a40 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -472,6 +472,7 @@ void bitInvaderView::modelChanged() void bitInvaderView::sinWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToSine(); Engine::getSong()->setModified(); } @@ -481,6 +482,7 @@ void bitInvaderView::sinWaveClicked() void bitInvaderView::triangleWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToTriangle(); Engine::getSong()->setModified(); } @@ -490,6 +492,7 @@ void bitInvaderView::triangleWaveClicked() void bitInvaderView::sawWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToSaw(); Engine::getSong()->setModified(); } @@ -499,6 +502,7 @@ void bitInvaderView::sawWaveClicked() void bitInvaderView::sqrWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToSquare(); Engine::getSong()->setModified(); } @@ -508,6 +512,7 @@ void bitInvaderView::sqrWaveClicked() void bitInvaderView::noiseWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToNoise(); Engine::getSong()->setModified(); } @@ -518,35 +523,12 @@ void bitInvaderView::noiseWaveClicked() void bitInvaderView::usrWaveClicked() { QString fileName = m_graph->model()->setWaveToUser(); - ToolTip::add( m_usrWaveBtn, fileName ); - Engine::getSong()->setModified(); - /* - m_graph->model()->setWaveToNoise(); - Engine::getSong()->setModified(); - // zero sample_shape - for (int i = 0; i < sample_length; i++) + if (!fileName.isEmpty()) { - sample_shape[i] = 0; + ToolTip::add(m_usrWaveBtn, fileName); + m_graph->model()->clearInvisible(); + Engine::getSong()->setModified(); } - - // load user shape - sampleBuffer buffer; - QString af = buffer.openAudioFile(); - if ( af != "" ) - { - buffer.setAudioFile( af ); - - // copy buffer data - sample_length = min( sample_length, static_cast( - buffer.frames() ) ); - for ( int i = 0; i < sample_length; i++ ) - { - sample_shape[i] = (float)*buffer.data()[i]; - } - } - - sampleChanged(); - */ } diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index 44c37165e..458160c41 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -692,7 +692,15 @@ void graphModel::shiftPhase( int _deg ) emit samplesChanged( 0, length()-1 ); } - +// Clear any part of the graph that isn't displayed +void graphModel::clearInvisible() +{ + const int graph_length = length(); + const int full_graph_length = m_samples.size(); + for( int i = graph_length; i < full_graph_length; i++ ) + m_samples[i] = 0; + emit samplesChanged( graph_length, full_graph_length - 1 ); +} void graphModel::drawSampleAt( int x, float val ) { From 505c642fbc8df3876497547969a519e547737bad Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 17 Feb 2019 19:07:40 +0000 Subject: [PATCH 57/79] Bring back PortAudio support on Windows (#4770) Population of the PortAudio setup widget has been delayed until it is shown, as it was causing crashes on some systems. --- CMakeLists.txt | 2 - include/AudioPortAudio.h | 2 + src/core/audio/AudioPortAudio.cpp | 84 +++++++++++++++++++------------ 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c25e0aec8..5fa83f854 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,6 @@ IF(LMMS_BUILD_WIN32) SET(WANT_ALSA OFF) SET(WANT_JACK OFF) SET(WANT_PULSEAUDIO OFF) - SET(WANT_PORTAUDIO OFF) SET(WANT_SNDIO OFF) SET(WANT_SOUNDIO OFF) SET(WANT_WINMM ON) @@ -96,7 +95,6 @@ IF(LMMS_BUILD_WIN32) SET(STATUS_ALSA "") SET(STATUS_JACK "") SET(STATUS_PULSEAUDIO "") - SET(STATUS_PORTAUDIO "") SET(STATUS_SOUNDIO "") SET(STATUS_WINMM "OK") SET(STATUS_APPLEMIDI "") diff --git a/include/AudioPortAudio.h b/include/AudioPortAudio.h index e4f27c7e1..e1288c3a4 100644 --- a/include/AudioPortAudio.h +++ b/include/AudioPortAudio.h @@ -34,6 +34,7 @@ class AudioPortAudioSetupUtil : public QObject { Q_OBJECT public slots: + void updateBackends(); void updateDevices(); void updateChannels(); @@ -87,6 +88,7 @@ public: virtual ~setupWidget(); virtual void saveSettings(); + virtual void show(); private: ComboBox * m_backend; diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index 6abb29453..5566d7a36 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -27,6 +27,10 @@ #include "AudioPortAudio.h" #ifndef LMMS_HAVE_PORTAUDIO +void AudioPortAudioSetupUtil::updateBackends() +{ +} + void AudioPortAudioSetupUtil::updateDevices() { } @@ -328,6 +332,28 @@ int AudioPortAudio::_process_callback( + +void AudioPortAudioSetupUtil::updateBackends() +{ + PaError err = Pa_Initialize(); + if( err != paNoError ) { + printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) ); + return; + } + + const PaHostApiInfo * hi; + for( int i = 0; i < Pa_GetHostApiCount(); ++i ) + { + hi = Pa_GetHostApiInfo( i ); + m_backendModel.addItem( hi->name ); + } + + Pa_Terminate(); +} + + + + void AudioPortAudioSetupUtil::updateDevices() { PaError err = Pa_Initialize(); @@ -409,37 +435,6 @@ AudioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : m_channels->setLabel( tr( "CHANNELS" ) ); m_channels->move( 308, 20 );*/ - // Setup models - PaError err = Pa_Initialize(); - if( err != paNoError ) { - printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) ); - return; - } - - // todo: setup backend model - const PaHostApiInfo * hi; - for( int i = 0; i < Pa_GetHostApiCount(); ++i ) - { - hi = Pa_GetHostApiInfo( i ); - m_setupUtil.m_backendModel.addItem( hi->name ); - } - - Pa_Terminate(); - - - const QString& backend = ConfigManager::inst()->value( "audioportaudio", - "backend" ); - const QString& device = ConfigManager::inst()->value( "audioportaudio", - "device" ); - - int i = qMax( 0, m_setupUtil.m_backendModel.findText( backend ) ); - m_setupUtil.m_backendModel.setValue( i ); - - m_setupUtil.updateDevices(); - - i = qMax( 0, m_setupUtil.m_deviceModel.findText( device ) ); - m_setupUtil.m_deviceModel.setValue( i ); - connect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ), &m_setupUtil, SLOT( updateDevices() ) ); @@ -478,6 +473,33 @@ void AudioPortAudio::setupWidget::saveSettings() } + + +void AudioPortAudio::setupWidget::show() +{ + if( m_setupUtil.m_backendModel.size() == 0 ) + { + // populate the backend model the first time we are shown + m_setupUtil.updateBackends(); + + const QString& backend = ConfigManager::inst()->value( + "audioportaudio", "backend" ); + const QString& device = ConfigManager::inst()->value( + "audioportaudio", "device" ); + + int i = qMax( 0, m_setupUtil.m_backendModel.findText( backend ) ); + m_setupUtil.m_backendModel.setValue( i ); + + m_setupUtil.updateDevices(); + + i = qMax( 0, m_setupUtil.m_deviceModel.findText( device ) ); + m_setupUtil.m_deviceModel.setValue( i ); + } + + AudioDeviceSetupWidget::show(); +} + + #endif From 71dbfb5297dbd331f8799f9dfd9ed97cba91649f Mon Sep 17 00:00:00 2001 From: liushuyu Date: Mon, 18 Feb 2019 16:42:03 -0700 Subject: [PATCH 58/79] i18n: pull from Transifex --- data/locale/en.ts | 1222 ++--- data/locale/id.ts | 12760 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 13374 insertions(+), 608 deletions(-) create mode 100644 data/locale/id.ts diff --git a/data/locale/en.ts b/data/locale/en.ts index 12b1b30cc..cb596387a 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -280,12 +280,12 @@ If you're interested in translating LMMS in another language or want to imp - + CLIENT-NAME - + CHANNELS @@ -306,12 +306,12 @@ If you're interested in translating LMMS in another language or want to imp AudioPortAudio::setupWidget - + BACKEND - + DEVICE @@ -319,12 +319,12 @@ If you're interested in translating LMMS in another language or want to imp AudioPulseAudio::setupWidget - + DEVICE - + CHANNELS @@ -332,7 +332,7 @@ If you're interested in translating LMMS in another language or want to imp AudioSdl::setupWidget - + DEVICE @@ -353,12 +353,12 @@ If you're interested in translating LMMS in another language or want to imp AudioSoundIo::setupWidget - + BACKEND - + DEVICE @@ -424,17 +424,17 @@ If you're interested in translating LMMS in another language or want to imp AutomationEditor - + Please open an automation pattern with the context menu of a control! - + Values copied - + All selected values were copied to the clipboard. @@ -442,184 +442,184 @@ If you're interested in translating LMMS in another language or want to imp AutomationEditorWindow - + Play/pause current pattern (Space) - + Click here if you want to play the current pattern. This is useful while editing it. The pattern is automatically looped when the end is reached. - + Stop playing of current pattern (Space) - + Click here if you want to stop playing of the current pattern. - + Edit actions - + Draw mode (Shift+D) - + Erase mode (Shift+E) - + Flip vertically - + Flip horizontally - + Click here and the pattern will be inverted.The points are flipped in the y direction. - + Click here and the pattern will be reversed. The points are flipped in the x direction. - + Click here and draw-mode will be activated. In this mode you can add and move single values. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. - + Click here and erase-mode will be activated. In this mode you can erase single values. You can also press 'Shift+E' on your keyboard to activate this mode. - + Interpolation controls - + Discrete progression - + Linear progression - + Cubic Hermite progression - + Tension value for spline - + A higher tension value may make a smoother curve but overshoot some values. A low tension value will cause the slope of the curve to level off at each control point. - + Click here to choose discrete progressions for this automation pattern. The value of the connected object will remain constant between control points and be set immediately to the new value when each control point is reached. - + Click here to choose linear progressions for this automation pattern. The value of the connected object will change at a steady rate over time between control points to reach the correct value at each control point without a sudden change. - + Click here to choose cubic hermite progressions for this automation pattern. The value of the connected object will change in a smooth curve and ease in to the peaks and valleys. - + Tension: - + Cut selected values (%1+X) - + Copy selected values (%1+C) - + Paste values from clipboard (%1+V) - + Click here and selected values will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - + Click here and selected values will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - + Click here and the values from the clipboard will be pasted at the first visible measure. - + Zoom controls - + Quantization controls - + Quantization - + Quantization. Sets the smallest step size for the Automation Point. By default this also sets the length, clearing out other points in the range. Press <Ctrl> to override this behaviour. - - + + Automation Editor - no pattern - - + + Automation Editor - %1 - + Model is already connected to this pattern. @@ -627,7 +627,7 @@ If you're interested in translating LMMS in another language or want to imp AutomationPattern - + Drag a control while pressing <%1> @@ -973,12 +973,12 @@ If you're interested in translating LMMS in another language or want to imp CarlaInstrumentView - + Show GUI - + Click here to show or hide the graphical user interface (GUI) of Carla. @@ -1648,67 +1648,67 @@ If you're interested in translating LMMS in another language or want to imp EffectView - + Toggles the effect on or off. - + On/Off - + W/D - + Wet Level: - + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. - + DECAY - + Time: - + The Decay knob controls how many buffers of silence must pass before the plugin stops processing. Smaller values will reduce the CPU overhead but run the risk of clipping the tail on delay and reverb effects. - + GATE - + Gate: - + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. - + Controls - + Effect plugins function as a chained series of effects where the signal will be processed from top to bottom. The On/Off switch allows you to bypass a given plugin at any point in time. @@ -1725,17 +1725,17 @@ Right clicking will bring up a context menu where you can change the order in wh - + Move &up - + Move &down - + &Remove this plugin @@ -2025,17 +2025,17 @@ Right clicking will bring up a context menu where you can change the order in wh - + ms/LFO: - + Hint - + Drag a sample from somewhere and drop it in this window. @@ -2581,17 +2581,17 @@ Please make sure you have write permission to the file and the directory contain - + Error - + Error while determining file-encoder device. Please try to choose a different output format. - + Rendering: %1% @@ -2599,8 +2599,8 @@ Please make sure you have write permission to the file and the directory contain Fader - - + + Please enter a new value between %1 and %2: @@ -2656,7 +2656,7 @@ Please make sure you have write permission to the file and the directory contain - + --- Factory files --- @@ -2799,29 +2799,29 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxMixer - + Master - - - + + + FX %1 - + Volume - + Mute - + Solo @@ -2948,52 +2948,52 @@ You can remove and move FX channels in the context menu, which is accessed by ri GuiApplication - + Working directory - + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. - + Preparing UI - + Preparing song editor - + Preparing mixer - + Preparing controller rack - + Preparing project notes - + Preparing beat/bassline editor - + Preparing piano roll - + Preparing automation editor @@ -3651,7 +3651,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri - Phrygolydian + Phrygian @@ -4098,7 +4098,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri - + Default preset @@ -4106,52 +4106,52 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackView - + Volume - + Volume: - + VOL - + Panning - + Panning: - + PAN - + MIDI - + Input - + Output - + FX %1: %2 @@ -4159,137 +4159,137 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackWindow - + GENERAL SETTINGS - + Use these controls to view and edit the next/previous track in the song editor. - + Instrument volume - + Volume: - + VOL - + Panning - + Panning: - + PAN - + Pitch - + Pitch: - + cents - + PITCH - + Pitch range (semitones) - + RANGE - + FX channel - + FX - + Save current instrument track settings in a preset file - + Click here, if you want to save current instrument track settings in a preset file. Later you can load this preset by double-clicking it in the preset-browser. - + SAVE - + Envelope, filter & LFO - + Chord stacking & arpeggio - + Effects - + MIDI settings - + Miscellaneous - + Save preset - + XML preset file (*.xpf) - + Plugin @@ -4297,22 +4297,22 @@ You can remove and move FX channels in the context menu, which is accessed by ri Knob - + Set linear - + Set logarithmic - + Please enter a new value between -96.0 dBFS and 6.0 dBFS: - + Please enter a new value between %1 and %2: @@ -4582,62 +4582,62 @@ Double click to pick a file. MainWindow - + Configuration file - + Error while parsing configuration file at line %1:%2: %3 - + Could not open file - + Could not open file %1 for writing. Please make sure you have write permission to the file and the directory containing the file and try again! - + Project recovery - + There is a recovery file present. It looks like the last session did not end properly or another instance of LMMS is already running. Do you want to recover the project of this session? - - - + + + Recover - + Recover the file. Please don't run multiple instances of LMMS when you do this. - - - + + + Discard - + Launch a default session and delete the restored files. This is not reversible. - + Version %1 @@ -4922,138 +4922,138 @@ Please make sure you have write permission to the file and the directory contain - + Untitled - + Recover session. Please save your work! - + LMMS %1 - + Recovered project not saved - + This project was recovered from the previous session. It is currently unsaved and will be lost if you don't save it. Do you want to save it now? - + Project not saved - + The current project was modified since last saving. Do you want to save it now? - + Open Project - + LMMS (*.mmp *.mmpz) - + Save Project - + LMMS Project - + LMMS Project Template - + Save project template - + Overwrite default template? - + This will overwrite your current default template. - + Help not available - + Currently there's no help available in LMMS. Please visit http://lmms.sf.net/wiki for documentation on LMMS. - + Song Editor - + Beat+Bassline Editor - + Piano Roll - + Automation Editor - + FX Mixer - + Project Notes - + Controller Rack - + Volume as dBFS - + Smooth scroll - + Enable note labels in piano roll @@ -5107,23 +5107,23 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiImport - - + + Setup incomplete - + You do not have set up a default soundfont in the settings dialog (Edit->Settings). Therefore no sound will be played back after importing this MIDI file. You should download a General MIDI soundfont, specify it in settings dialog and try again. - + You did not compile LMMS with support for SoundFont2 player, which is used to add default sound to imported MIDI files. Therefore no sound will be played back after importing this MIDI file. - + Track @@ -5146,57 +5146,57 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiPort - + Input channel - + Output channel - + Input controller - + Output controller - + Fixed input velocity - + Fixed output velocity - + Fixed output note - + Output MIDI program - + Base velocity - + Receive MIDI-events - + Send MIDI-events @@ -6754,17 +6754,17 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakController - + Peak Controller - + Peak Controller Bug - + Due to a bug in older version of LMMS, the peak controllers may not be connect properly. Please ensure that peak controllers are connected properly and re-save this file. Sorry for any inconvenience caused. @@ -6848,42 +6848,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakControllerEffectControls - + Base value - + Modulation amount - + Attack - + Release - + Treshold - + Mute output - + Abs Value - + Amount Multiplicator @@ -6891,93 +6891,93 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PianoRoll - + Note Velocity - + Note Panning - + Mark/unmark current semitone - + Mark/unmark all corresponding octave semitones - + Mark current scale - + Mark current chord - + Unmark all - + Select all notes on this key - + Note lock - + Last note - + No scale - + No chord - + Velocity: %1% - + Panning: %1% left - + Panning: %1% right - + Panning: center - + Please open a pattern by double-clicking on it! - - + + Please enter a new value between %1 and %2: @@ -6985,174 +6985,174 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PianoRollWindow - + Play/pause current pattern (Space) - + Record notes from MIDI-device/channel-piano - + Record notes from MIDI-device/channel-piano while playing song or BB track - + Stop playing of current pattern (Space) - + Click here to play the current pattern. This is useful while editing it. The pattern is automatically looped when its end is reached. - + Click here to record notes from a MIDI-device or the virtual test-piano of the according channel-window to the current pattern. When recording all notes you play will be written to this pattern and you can play and edit them afterwards. - + Click here to record notes from a MIDI-device or the virtual test-piano of the according channel-window to the current pattern. When recording all notes you play will be written to this pattern and you will hear the song or BB track in the background. - + Click here to stop playback of current pattern. - + Edit actions - + Draw mode (Shift+D) - + Erase mode (Shift+E) - + Select mode (Shift+S) - - Detune mode (Shift+T) - - - - + Click here and draw mode will be activated. In this mode you can add, resize and move notes. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. In this mode, hold %1 to temporarily go into select mode. - + Click here and erase mode will be activated. In this mode you can erase notes. You can also press 'Shift+E' on your keyboard to activate this mode. - + Click here and select mode will be activated. In this mode you can select notes. Alternatively, you can hold %1 in draw mode to temporarily use select mode. - - Click here and detune mode will be activated. In this mode you can click a note to open its automation detuning. You can utilize this to slide notes from one to another. You can also press 'Shift+T' on your keyboard to activate this mode. + + Pitch Bend mode (Shift+T) - + + Click here and Pitch Bend mode will be activated. In this mode you can click a note to open its automation detuning. You can utilize this to slide notes from one to another. You can also press 'Shift+T' on your keyboard to activate this mode. + + + + Quantize - + Copy paste controls - + Cut selected notes (%1+X) - + Copy selected notes (%1+C) - + Paste notes from clipboard (%1+V) - + Click here and the selected notes will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - + Click here and the selected notes will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - + Click here and the notes from the clipboard will be pasted at the first visible measure. - + Timeline controls - + Zoom and note controls - + This controls the magnification of an axis. It can be helpful to choose magnification for a specific task. For ordinary editing, the magnification should be fitted to your smallest notes. - + The 'Q' stands for quantization, and controls the grid size notes and control points snap to. With smaller quantization values, you can draw shorter notes in Piano Roll, and more exact control points in the Automation Editor. - + This lets you select the length of new notes. 'Last Note' means that LMMS will use the note length of the note you last edited - + The feature is directly connected to the context-menu on the virtual keyboard, to the left in Piano Roll. After you have chosen the scale you want in this drop-down menu, you can right click on a desired key in the virtual keyboard, and then choose 'Mark current Scale'. LMMS will highlight all notes that belongs to the chosen scale, and in the key you have selected! - + Let you select a chord which LMMS then can draw or highlight.You can find the most common chords in this drop-down menu. After you have selected a chord, click anywhere to place the chord, and right click on the virtual keyboard to open context menu and highlight the chord. To return to single note placement, you need to choose 'No chord' in this drop-down menu. - - + + Piano-Roll - %1 - - + + Piano-Roll - no pattern @@ -7160,7 +7160,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PianoView - + Base note @@ -7545,67 +7545,67 @@ Reason: "%2" SampleBuffer - + Fail to open file - + Audio files are limited to %1 MB in size and %2 minutes of playing time - + Open audio file - + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - + Wave-Files (*.wav) - + OGG-Files (*.ogg) - + DrumSynth-Files (*.ds) - + FLAC-Files (*.flac) - + SPEEX-Files (*.spx) - + VOC-Files (*.voc) - + AIFF-Files (*.aif *.aiff) - + AU-Files (*.au) - + RAW-Files (*.raw) @@ -7613,32 +7613,32 @@ Reason: "%2" SampleTCOView - + double-click to select sample - + Delete (middle mousebutton) - + Cut - + Copy - + Paste - + Mute/unmute (<%1> + middle click) @@ -7646,18 +7646,18 @@ Reason: "%2" SampleTrack - + Volume - + Panning - - + + Sample track @@ -7665,12 +7665,12 @@ Reason: "%2" SampleTrackView - + Track volume - + Channel volume: @@ -7698,350 +7698,355 @@ Reason: "%2" SetupDialog - + Setup LMMS - - + + General settings - + BUFFER SIZE - - + + Reset to default-value - + MISC - + Enable tooltips - + Show restart warning after changing settings - + Display volume as dBFS - + Compress project files per default - + One instrument track window mode - + HQ-mode for output audio-device - + Compact track buttons - + Sync VST plugins to host playback - + Enable note labels in piano roll - + Enable waveform display by default - + Keep effects running even without input - + Create backup file when saving a project - + Reopen last project on start - + + Use built-in NaN handler + + + + PLUGIN EMBEDDING - + No embedding - + Embed using Qt API - + Embed using native Win32 API - + Embed using XEmbed protocol - + LANGUAGE - - + + Paths - + Directories - + LMMS working directory - + Themes directory - + Background artwork - + VST-plugin directory - + GIG directory - + SF2 directory - + LADSPA plugin directories - + STK rawwave directory - + Default Soundfont File - - + + Performance settings - + Auto save - + Enable auto-save - + Allow auto-save while playing - + UI effects vs. performance - + Smooth scroll in Song Editor - + Show playback cursor in AudioFileProcessor - - + + Audio settings - + AUDIO INTERFACE - - + + MIDI settings - + MIDI INTERFACE - + OK - + Cancel - + Restart LMMS - + Please note that most changes won't take effect until you restart LMMS! - + Frames: %1 Latency: %2 ms - + Here you can setup the internal buffer-size used by LMMS. Smaller values result in a lower latency but also may cause unusable sound or bad performance, especially on older computers or systems with a non-realtime kernel. - + Choose LMMS working directory - + Choose your GIG directory - + Choose your SF2 directory - + Choose your VST-plugin directory - + Choose artwork-theme directory - + Choose LADSPA plugin directory - + Choose STK rawwave directory - + Choose default SoundFont - + Choose background artwork - + minutes - + minute - + Disabled - + Auto-save interval: %1 - + Set the time between automatic backup to %1. Remember to also save your project manually. You can choose to disable saving while playing, something some older systems find difficult. - + Here you can select your preferred audio-interface. Depending on the configuration of your system during compilation time you can choose between ALSA, JACK, OSS and more. Below you see a box which offers controls to setup the selected audio-interface. - + Here you can select your preferred MIDI-interface. Depending on the configuration of your system during compilation time you can choose between ALSA, OSS and more. Below you see a box which offers controls to setup the selected MIDI-interface. @@ -8064,91 +8069,91 @@ Remember to also save your project manually. You can choose to disable saving wh - + LMMS Error report - + Project saved - + The project %1 is now saved. - + Project NOT saved. - + The project %1 was not saved! - + Import file - + MIDI sequences - + Hydrogen projects - + All file types - - + + Empty project - - + + This project is empty so exporting makes no sense. Please put some items into Song Editor first! - + Select directory for writing exported tracks... - - + + untitled - - + + Select file for project-export... - + Save project - + MIDI File (*.mid) - + The following errors occured while loading: @@ -8156,53 +8161,53 @@ Remember to also save your project manually. You can choose to disable saving wh SongEditor - + Could not open file - + Could not open file %1. You probably have no permissions to read this file. Please make sure to have at least read permissions to the file and try again. - + Could not write file - + Could not open %1 for writing. You probably are not permitted to write to this file. Please make sure you have write-access to the file and try again. - + Error in file - + The file %1 seems to contain errors and therefore can't be loaded. - + Version difference - + This %1 was created with LMMS %2. - + template - + project @@ -8584,12 +8589,12 @@ Remember to also save your project manually. You can choose to disable saving wh Track - + Mute - + Solo @@ -8625,13 +8630,13 @@ Please make sure you have read-permission to the file and the directory containi - + Cancel - + Please wait... @@ -8651,7 +8656,7 @@ Please make sure you have read-permission to the file and the directory containi - + Importing MIDI-file... @@ -8667,13 +8672,13 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObjectView - + Current position - + Hint @@ -8683,42 +8688,43 @@ Please make sure you have read-permission to the file and the directory containi - + Current length - + Press <%1> for free resizing. - + + %1:%2 (%3:%4 to %5:%6) - + Delete (middle mousebutton) - + Cut - + Copy - + Paste - + Mute/unmute (<%1> + middle click) @@ -8726,63 +8732,63 @@ Please make sure you have read-permission to the file and the directory containi TrackOperationsWidget - + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. - + Actions for this track - + Mute - - + + Solo - + Mute this track - + Clone this track - + Remove this track - + Clear this track - + FX %1: %2 - + Assign to new FX Channel - + Turn all recording on - + Turn all recording off @@ -8988,113 +8994,113 @@ Please make sure you have read-permission to the file and the directory containi VestigeInstrumentView - + Open other VST-plugin - + Click here, if you want to open another VST-plugin. After clicking on this button, a file-open-dialog appears and you can select your file. - + Control VST-plugin from LMMS host - + Click here, if you want to control VST-plugin from host. - + Open VST-plugin preset - + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + Previous (-) - - + + Click here, if you want to switch to another VST-plugin preset program. - + Save preset - + Click here, if you want to save current VST-plugin preset program. - + Next (+) - + Click here to select presets that are currently loaded in VST. - + Show/hide GUI - + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - + Turn off all notes - + Open VST-plugin - + DLL-files (*.dll) - + EXE-files (*.exe) - + No VST-plugin loaded - + Preset - + by - + - VST plugin control @@ -9102,12 +9108,12 @@ Please make sure you have read-permission to the file and the directory containi VisualizationWidget - + click to enable/disable visualization of master-output - + Click to enable @@ -9115,69 +9121,69 @@ Please make sure you have read-permission to the file and the directory containi VstEffectControlDialog - + Show/hide - + Control VST-plugin from LMMS host - + Click here, if you want to control VST-plugin from host. - + Open VST-plugin preset - + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + Previous (-) - - + + Click here, if you want to switch to another VST-plugin preset program. - + Next (+) - + Click here to select presets that are currently loaded in VST. - + Save preset - + Click here, if you want to save current VST-plugin preset program. - - + + Effect by: - + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -9185,69 +9191,69 @@ Please make sure you have read-permission to the file and the directory containi VstPlugin - - + + The VST plugin %1 could not be loaded. - + Open Preset - - + + Vst Plugin Preset (*.fxp *.fxb) - + : default - + " - + ' - + Save Preset - + .fxp - + .FXP - + .FXB - + .fxb - + Loading plugin - + Please wait while loading VST plugin... @@ -9652,42 +9658,42 @@ Please make sure you have read-permission to the file and the directory containi ZynAddSubFxInstrument - + Portamento - + Filter Frequency - + Filter Resonance - + Bandwidth - + FM Gain - + Resonance Center Frequency - + Resonance Bandwidth - + Forward MIDI Control Change Events @@ -9695,87 +9701,87 @@ Please make sure you have read-permission to the file and the directory containi ZynAddSubFxView - + Portamento: - + PORT - + Filter Frequency: - + FREQ - + Filter Resonance: - + RES - + Bandwidth: - + BW - + FM Gain: - + FM GAIN - + Resonance center frequency: - + RES CF - + Resonance bandwidth: - + RES BW - + Forward MIDI Control Changes - + Show GUI - + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. @@ -10088,12 +10094,12 @@ Please make sure you have read-permission to the file and the directory containi fxLineLcdSpinBox - + Assign to: - + New FX Channel @@ -10885,38 +10891,38 @@ Double clicking any of the plugins will bring up information on the ports. manageVSTEffectView - + - VST parameter control - + VST Sync - + Click here if you want to synchronize all parameters with VST plugin. - - + + Automated - + Click here if you want to display automated parameters only. - + Close - + Close VST effect knob-controller window. @@ -10924,39 +10930,39 @@ Double clicking any of the plugins will bring up information on the ports. manageVestigeInstrumentView - - + + - VST plugin control - + VST Sync - + Click here if you want to synchronize all parameters with VST plugin. - - + + Automated - + Click here if you want to display automated parameters only. - + Close - + Close VST plugin knob-controller window. @@ -11339,228 +11345,228 @@ Double clicking any of the plugins will bring up information on the ports. papuInstrumentView - + Sweep Time: - + Sweep Time - + The amount of increase or decrease in frequency - + Sweep RtShift amount: - + Sweep RtShift amount - + The rate at which increase or decrease in frequency occurs - - + + Wave pattern duty: - + Wave Pattern Duty - - + + The duty cycle is the ratio of the duration (time) that a signal is ON versus the total period of the signal. - - + + Square Channel 1 Volume: - + Square Channel 1 Volume - - - + + + Length of each step in sweep: - - - - - Length of each step in sweep - - + Length of each step in sweep + + + + + + The delay between step change - + Wave pattern duty - + Square Channel 2 Volume: - + Square Channel 2 Volume - + Wave Channel Volume: - + Wave Channel Volume - + Noise Channel Volume: - + Noise Channel Volume - + SO1 Volume (Right): - + SO1 Volume (Right) - + SO2 Volume (Left): - + SO2 Volume (Left) - + Treble: - + Treble - + Bass: - + Bass - + Sweep Direction - - - - - + + + + + Volume Sweep Direction - + Shift Register Width - + Channel1 to SO1 (Right) - + Channel2 to SO1 (Right) - + Channel3 to SO1 (Right) - + Channel4 to SO1 (Right) - + Channel1 to SO2 (Left) - + Channel2 to SO2 (Left) - + Channel3 to SO2 (Left) - + Channel4 to SO2 (Left) - + Wave Pattern - + Draw the wave here @@ -11711,12 +11717,12 @@ Double clicking any of the plugins will bring up information on the ports. - + Filter for exporting MIDI-files from LMMS - + Filter for importing MIDI-files into LMMS @@ -11756,7 +11762,7 @@ Double clicking any of the plugins will bring up information on the ports. - + Plugin for controlling knobs with sound peaks @@ -11807,7 +11813,7 @@ This chip was used in the Commodore 64 computer. - + VST-host for using VST(i)-plugins within LMMS @@ -11817,7 +11823,7 @@ This chip was used in the Commodore 64 computer. - + plugin for using arbitrary VST effects inside LMMS. @@ -11832,7 +11838,7 @@ This chip was used in the Commodore 64 computer. - + Embedded ZynAddSubFX @@ -11905,7 +11911,7 @@ This chip was used in the Commodore 64 computer. - + A soundfont %1 could not be loaded. @@ -11913,92 +11919,92 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView - + Open other SoundFont file - + Click here to open another SF2 file - + Choose the patch - + Gain - + Apply reverb (if supported) - + This button enables the reverb effect. This is useful for cool effects, but only works on files that support it. - + Reverb Roomsize: - + Reverb Damping: - + Reverb Width: - + Reverb Level: - + Apply chorus (if supported) - + This button enables the chorus effect. This is useful for cool echo effects, but only works on files that support it. - + Chorus Lines: - + Chorus Level: - + Chorus Speed: - + Chorus Depth: - + Open SoundFont file - + SoundFont2 Files (*.sf2) @@ -12287,12 +12293,12 @@ This chip was used in the Commodore 64 computer. vestigeInstrument - + Loading plugin - + Please wait while loading VST-plugin... diff --git a/data/locale/id.ts b/data/locale/id.ts new file mode 100644 index 000000000..812a90d70 --- /dev/null +++ b/data/locale/id.ts @@ -0,0 +1,12760 @@ + + + AboutDialog + + + About LMMS + Ihwal LMMS + + + + LMMS + LMMS + + + + Version %1 (%2/%3, Qt %4, %5) + Versi %1 (%2/%3, Qt %4, %5) + + + + About + Ihwal + + + + LMMS - easy music production for everyone + LMMS - mudahnya produksi musik untuk semua orang + + + + Copyright © %1 + Hak cipta © %1 + + + + <html><head/><body><p><a href="https://lmms.io"><span style=" text-decoration: underline; color:#0000ff;">https://lmms.io</span></a></p></body></html> + <html><head/><body><p><a href="https://lmms.io"><span style=" text-decoration: underline; color:#0000ff;">https://lmms.io</span></a></p></body></html> + + + + Authors + Pencipta + + + + Involved + Terlibat + + + + Contributors ordered by number of commits: + Kontributor disortir oleh jumlah komit: + + + + Translation + Terjemahan + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + bahasa saat ini tidak diterjemahkan (atau asli bahasa Inggris). + +Jika Anda tertarik untuk menerjemahkan LMMS dalam bahasa lain atau ingin meningkatkan terjemahan yang ada, Anda dipersilakan untuk membantu kami! Cukup hubungi pengelola! + + + + License + Lisensi + + + + AmplifierControlDialog + + + VOL + VOL + + + + Volume: + Volume: + + + + PAN + SEIMBANG + + + + Panning: + Keseimbangan: + + + + LEFT + KIRI + + + + Left gain: + gain kiri: + + + + RIGHT + KANAN + + + + Right gain: + gain kanan: + + + + AmplifierControls + + + Volume + Volume + + + + Panning + Keseimbangan + + + + Left gain + gain Kiri + + + + Right gain + gain Kanan + + + + AudioAlsaSetupWidget + + + DEVICE + PERANGKAT + + + + CHANNELS + SALURAN + + + + AudioFileProcessorView + + + Open other sample + Buka sampel lain + + + + Click here, if you want to open another audio-file. A dialog will appear where you can select your file. Settings like looping-mode, start and end-points, amplify-value, and so on are not reset. So, it may not sound like the original sample. + Klik disini, jika anda ingin membuka berkas audio lain. Sebuah dialog akan muncul dimana anda bisa memilih berkas anda. Pengaturan seperti mode-pengulangan, titik mulai-akhir, nilai ampli, dan lainnya tidak akan berubah. Jadi, ini mungkin tidak akan terdengar seperti sampel orsinil. + + + + Reverse sample + Balikan sampel + + + + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. + Jika anda mengaktifkan tombol ini, seluruh sampel dibalik. Hal ini cocok untuk efek yang keren, misalnya crash terbalik. + + + + Disable loop + Nonaktifkan pengulangan + + + + This button disables looping. The sample plays only once from start to end. + Tombol ini menonaktifkan pengulangan. Sampel diputar hanya sekali dari awal sampai akhir + + + + + Enable loop + Aktifkan pengulangan + + + + This button enables forwards-looping. The sample loops between the end point and the loop point. + Tombol ini memungkinkan pengulangan ke depan. Contoh pengulangan antara titik akhir dan titik pengulangan. + + + + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. + Tombol ini memungkinkan perulangan ping-pong. Sampel pengulangan mundur dan maju antara titik akhir dan titik pengulangan. + + + + Continue sample playback across notes + Lanjutkan pemutaran sampel di catatan melintasi not + + + + Enabling this option makes the sample continue playing across different notes - if you change pitch, or the note length stops before the end of the sample, then the next note played will continue where it left off. To reset the playback to the start of the sample, insert a note at the bottom of the keyboard (< 20 Hz) + Mengaktifkan opsi ini membuat sampel terus bermain melintasi not yang berbeda - jika anda merubah pitch, atau panjang not berhenti sebelum sampel akhir, maka not berikutnya yang diputar akan berlanjut dari tempat tinggalnya. Untuk mengatur ulang pemutaran ke awal sampel, masukan not dibagian bawah keyboard (< 20 Hz) + + + + Amplify: + Penguatan: + + + + With this knob you can set the amplify ratio. When you set a value of 100% your sample isn't changed. Otherwise it will be amplified up or down (your actual sample-file isn't touched!) + Dengan kenop ini Anda bisa mengatur rasio amplitudo. Bila Anda menetapkan nilai 100% sampel Anda tidak berubah. Jika tidak, itu akan diperkuat ke atas atau ke bawah (berkas sampel Anda yang sebenarnya tidak disentuh!) + + + + Startpoint: + Titik mulai: + + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. + Dengan kenop ini Anda dapat mengatur titik dimana AudioFileProcessor harus memutar sampel Anda. + + + + Endpoint: + Titik akhir: + + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. + Dengan kenop ini Anda dapat mengatur titik di mana AudioFileProcessor harus berhenti memainkan sampel Anda. + + + + Loopback point: + Titik pengulangan: + + + + With this knob you can set the point where the loop starts. + Dengan tombol ini Anda dapat mengatur titik di mana pengulangan dimulai. + + + + AudioFileProcessorWaveView + + + Sample length: + Panjang sampel: + + + + AudioJack + + + JACK client restarted + klien JACK dimulai ulang + + + + LMMS was kicked by JACK for some reason. Therefore the JACK backend of LMMS has been restarted. You will have to make manual connections again. + LMMS dikeluarkan oleh JACK karena alasan tertentu. Oleh karena itu backend LMMS JACK, telah dimulai ulang. Anda harus membuat koneksi manual lagi. + + + + JACK server down + Server JACK lumpuh + + + + The JACK server seems to have been shutdown and starting a new instance failed. Therefore LMMS is unable to proceed. You should save your project and restart JACK and LMMS. + Server JACK sepertinya telah dimatikan dan pemulaian instansi baru gagal. Oleh karena itu LMMS tidak bisa dilanjutkan. Anda harus menyimpan proyek anda dan memulai ulang JACK dan LMMS. + + + + CLIENT-NAME + NAMA-KLIEN + + + + CHANNELS + SALURAN + + + + AudioOss::setupWidget + + + DEVICE + PERANGKAT + + + + CHANNELS + KANAL + + + + AudioPortAudio::setupWidget + + + BACKEND + BACKEND + + + + DEVICE + PERANGKAT + + + + AudioPulseAudio::setupWidget + + + DEVICE + PERANGKAT + + + + CHANNELS + KANAL + + + + AudioSdl::setupWidget + + + DEVICE + PERANGKAT + + + + AudioSndio::setupWidget + + + DEVICE + PERANGKAT + + + + CHANNELS + KANAL + + + + AudioSoundIo::setupWidget + + + BACKEND + BACKEND + + + + DEVICE + PERANGKAT + + + + AutomatableModel + + + &Reset (%1%2) + &Mulai ulang (%1%2) + + + + &Copy value (%1%2) + &Salin nilai (%1%2) + + + + &Paste value (%1%2) + &Tempel nilai (%1%2) + + + + Edit song-global automation + Ubah lagu otomasi global + + + + Remove song-global automation + Hapus lagu otomasi global + + + + Remove all linked controls + Hapus semua pengendali yang terhubung + + + + Connected to %1 + Terhubung ke %1 + + + + Connected to controller + Terhubung ke pengendali + + + + Edit connection... + Ubah koneksi... + + + + Remove connection + Hapus koneksi + + + + Connect to controller... + Hubungkan ke pengendali... + + + + AutomationEditor + + + Please open an automation pattern with the context menu of a control! + Silakan buka pola otomasi dengan menu konteks kontrol! + + + + Values copied + Nilai disalin + + + + All selected values were copied to the clipboard. + Semua nilai yang dipilih telah disalin ke clipboard. + + + + AutomationEditorWindow + + + Play/pause current pattern (Space) + Putar/jeda pola saat ini (Spasi) + + + + Click here if you want to play the current pattern. This is useful while editing it. The pattern is automatically looped when the end is reached. + Klik di sini untuk memainkan pola saat ini. Ini berguna saat mengeditnya. Pola diulang secara otomatis saat ujungnya tercapai. + + + + Stop playing of current pattern (Space) + Berhenti memutar pola saat ini (Spasi) + + + + Click here if you want to stop playing of the current pattern. + Klik disini jika anda ingin berhenti memutar pola saat ini. + + + + Edit actions + Ubah aksi + + + + Draw mode (Shift+D) + Mode menggambar (Shift+D) + + + + Erase mode (Shift+E) + Mode penghapus (Shift+E) + + + + Flip vertically + Balik secara vertikal + + + + Flip horizontally + Balik secara horizontal + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + Klik disini dan pola akan dibalik. Titik nya akan dibalik dengan arah y. + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + Klik disini dan pola akan dibalik. Titik nya akan dibalik dengan arah x. + + + + Click here and draw-mode will be activated. In this mode you can add and move single values. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. + Klik di sini dan mode-gambar akan diaktifkan. Dalam mode ini Anda bisa menambahkan dan memindahkan nilai tunggal. Ini adalah mode default yang sering digunakan. Anda juga dapat menekan 'Shift+D' pada keyboard untuk mengaktifkan mode ini. + + + + Click here and erase-mode will be activated. In this mode you can erase single values. You can also press 'Shift+E' on your keyboard to activate this mode. + Klik di sini dan mode-penghapus akan diaktifkan. Dalam mode ini Anda bisa menghapus nilai tunggal. Anda juga dapat menekan 'Shift+E' pada keyboard untuk mengaktifkan mode ini. + + + + Interpolation controls + Kontrol interpolasi + + + + Discrete progression + Perkembangan diskrit + + + + Linear progression + perkembangan linier + + + + Cubic Hermite progression + Perkembangan Hermite Cubic + + + + Tension value for spline + nilai tegangan untuk spline + + + + A higher tension value may make a smoother curve but overshoot some values. A low tension value will cause the slope of the curve to level off at each control point. + + + + + Click here to choose discrete progressions for this automation pattern. The value of the connected object will remain constant between control points and be set immediately to the new value when each control point is reached. + + + + + Click here to choose linear progressions for this automation pattern. The value of the connected object will change at a steady rate over time between control points to reach the correct value at each control point without a sudden change. + + + + + Click here to choose cubic hermite progressions for this automation pattern. The value of the connected object will change in a smooth curve and ease in to the peaks and valleys. + + + + + Tension: + Tegangan: + + + + Cut selected values (%1+X) + Potong nilai yang dipilih (%1+X) + + + + Copy selected values (%1+C) + Salin nilai yang dipilih (%1+X) + + + + Paste values from clipboard (%1+V) + Tempel nilai dari clipboard (%1+V) + + + + Click here and selected values will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. + Klik disini dan nilai yang dipilih akan dipotong ke papan klip. Anda bisa menempelkannya di manapun dalam pola apapun dengan mengklik tombol tempel. + + + + Click here and selected values will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. + Klik di sini dan nilai yang dipilih akan disalin ke papan klip. Anda bisa menempelkannya di manapun dalam pola apapun dengan mengklik tombol tempel. + + + + Click here and the values from the clipboard will be pasted at the first visible measure. + Klik di sini dan nilai dari papan klip akan disisipkan pada ukuran pertama yang terlihat. + + + + Zoom controls + Kontrol Zum + + + + Quantization controls + Kontrol kuantitasi + + + + Quantization + Kuantitasi + + + + Quantization. Sets the smallest step size for the Automation Point. By default this also sets the length, clearing out other points in the range. Press <Ctrl> to override this behaviour. + Kuantitasi. Tetapkan ukuran langkah terkecil untuk Titik Otomasi. Secara deafult ini juga menentukan panjangnya, membersihkan titik lain di kisaran ini. Tekan <Ctrl> untuk mengganti perilaku ini. + + + + + Automation Editor - no pattern + Editor Otomasi - tiada pola + + + + + Automation Editor - %1 + Editor Otomasi - %1 + + + + Model is already connected to this pattern. + Model sudah terhubung ke pola ini. + + + + AutomationPattern + + + Drag a control while pressing <%1> + Tarik kontrol sambil menekan <%1> + + + + AutomationPatternView + + + double-click to open this pattern in automation editor + klik dua-kali untuk membuka pola ini di editor otomasi + + + + Open in Automation editor + Buka di editor Otomasi + + + + Clear + Bersih + + + + Reset name + Reset nama + + + + Change name + Ganti nama + + + + Set/clear record + Setel/bersihkan catatan + + + + Flip Vertically (Visible) + Balik secara Vertikal (Terlihat) + + + + Flip Horizontally (Visible) + Balik secara Horizontal (Terlihat) + + + + %1 Connections + %1 Koneksi + + + + Disconnect "%1" + Putuskan "%1" + + + + Model is already connected to this pattern. + Model sudah terhubung ke pola ini. + + + + AutomationTrack + + + Automation track + Trek otomasi + + + + BBEditor + + + Beat+Bassline Editor + Editor Bassline+ketukan + + + + Play/pause current beat/bassline (Space) + Putar/jeda ketukan/bassline saat ini (Spasi) + + + + Stop playback of current beat/bassline (Space) + Hentikan pemutaran ketukan/bassline saat ini (Spasi) + + + + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. + Klik disini untuk memutar ketukan/bassline saat ini. Ketukan/bassline otomatis diulang ketika mencapai akhir. + + + + Click here to stop playing of current beat/bassline. + Klik disini untuk menghentikan pemutaran ketukan/bassline saat ini. + + + + Beat selector + Pemilih Ketukan + + + + Track and step actions + Aksi trek dan langkah + + + + Add beat/bassline + Tambah ketukan/bassline + + + + Add sample-track + Tambah Trek-sampel + + + + Add automation-track + Tambah trek-otomasi + + + + Remove steps + Hapus langkah + + + + Add steps + Tambah langkah + + + + Clone Steps + Klon langkah + + + + BBTCOView + + + Open in Beat+Bassline-Editor + Buka di Ketukan/Bassline-Editor + + + + Reset name + Reset nama + + + + Change name + Ganti nama + + + + Change color + Ganti warna + + + + Reset color to default + Reset warna ke default + + + + BBTrack + + + Beat/Bassline %1 + Ketukan/Bassline %1 + + + + Clone of %1 + Klon dari %1 + + + + BassBoosterControlDialog + + + FREQ + FREK + + + + Frequency: + Frekuensi: + + + + GAIN + GAIN + + + + Gain: + Gain: + + + + RATIO + RASIO + + + + Ratio: + Rasio: + + + + BassBoosterControls + + + Frequency + Frekuensi + + + + Gain + Gain + + + + Ratio + Rasio + + + + BitcrushControlDialog + + + IN + MASUK + + + + OUT + KELUAR + + + + + GAIN + GAIN + + + + Input Gain: + Gain Masuk: + + + + NOISE + RIUH + + + + Input Noise: + Bising Masukan: + + + + Output Gain: + Gain Keluaran: + + + + CLIP + KLIP + + + + Output Clip: + Klip Keluaran: + + + + Rate Enabled + Aktifkan Nilai + + + + Enable samplerate-crushing + Aktifkan samplerate-crushing + + + + Depth Enabled + Aktifkan Kedalaman + + + + Enable bitdepth-crushing + Aktifkan bitdepth-crushing + + + + FREQ + FREK + + + + Sample rate: + Nilai sampel: + + + + STEREO + STEREO + + + + Stereo difference: + Perbedaan stereo: + + + + QUANT + + + + + Levels: + Tingkat: + + + + CaptionMenu + + + &Help + &Bantuan + + + + Help (not available) + Bantuan (tidak tersedia) + + + + CarlaInstrumentView + + + Show GUI + Tampilkan GUI + + + + Click here to show or hide the graphical user interface (GUI) of Carla. + Klik disini untuk menampilkan atau menyembunyikan antarmuka pengguna (GUI) dari Carla. + + + + Controller + + + Controller %1 + Kontroler %1 + + + + ControllerConnectionDialog + + + Connection Settings + Pengaturan Koneksi + + + + MIDI CONTROLLER + KONTROLER MIDI + + + + Input channel + Saluran Masukan + + + + CHANNEL + SALURAN + + + + Input controller + Kontroler masukan + + + + CONTROLLER + KONTROLER + + + + + Auto Detect + Deteksi Otomatis + + + + MIDI-devices to receive MIDI-events from + Perangkat MIDI untuk menerima aktifitas-MIDI dari + + + + USER CONTROLLER + KONTROLER PENGGUNA + + + + MAPPING FUNCTION + PEMETAAN FUNGSI + + + + OK + OK + + + + Cancel + Batal + + + + LMMS + LMMS + + + + Cycle Detected. + Siklus terdeteksi. + + + + ControllerRackView + + + Controller Rack + Kontroler rak + + + + Add + Tambah + + + + Confirm Delete + Konfirmasi Hapus + + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + Konfirmasi hapus? Ada (beberapa) koneksi yang terasosiasi dengan kontroler ini. Tidak mungkin untuk melakukan undi. + + + + ControllerView + + + Controls + Kontrol + + + + Controllers are able to automate the value of a knob, slider, and other controls. + Kontroler dapat mengotomatisasi nilai kenop, slider, dan kontrol lainnya. + + + + Rename controller + Ganti nama kontroler + + + + Enter the new name for this controller + Masukan nama baru untuk kontroler ini + + + + LFO + LFO + + + + &Remove this controller + &Hapus kontroler ini + + + + Re&name this controller + Ganti&Nama kontroler ini + + + + CrossoverEQControlDialog + + + Band 1/2 Crossover: + Band 1/2 Crossover: + + + + Band 2/3 Crossover: + Band 2/3 Crossover: + + + + Band 3/4 Crossover: + Band 3/4 Crossover: + + + + Band 1 Gain: + Gain Band 1: + + + + Band 2 Gain: + Gain Band 2: + + + + Band 3 Gain: + Gain Band 3: + + + + Band 4 Gain: + Gain Band 4: + + + + Band 1 Mute + Bisukan Band 1 + + + + Mute Band 1 + Bisukan Band 1 + + + + Band 2 Mute + Bisukan Band 2 + + + + Mute Band 2 + Bisukan Band 2 + + + + Band 3 Mute + Bisukan Band 3 + + + + Mute Band 3 + Bisukan Band 3 + + + + Band 4 Mute + Bisukan Band 4 + + + + Mute Band 4 + Bisukan Band 4 + + + + DelayControls + + + Delay Samples + Sampel Delay + + + + Feedback + Umpan balik + + + + Lfo Frequency + Frekuensi Lfo + + + + Lfo Amount + Jumlah Lfo + + + + Output gain + Gain keluaran + + + + DelayControlsDialog + + + DELAY + DELAY + + + + Delay Time + Waktu Delay + + + + FDBK + UMPBLK + + + + Feedback Amount + Jumlah Umpan balik + + + + RATE + NILAI + + + + Lfo + Lfo + + + + AMNT + JMLH + + + + Lfo Amt + jmlh Lfo + + + + Out Gain + Gain Keluar + + + + Gain + GainGain + + + + DualFilterControlDialog + + + + FREQ + FREK + + + + + Cutoff frequency + Frekuensi cutoff + + + + + RESO + RESO + + + + + Resonance + Resonansi + + + + + GAIN + GAIN + + + + + Gain + Gain + + + + MIX + MIX + + + + Mix + Mix + + + + Filter 1 enabled + Filter 1 diaktifkan + + + + Filter 2 enabled + Filter 2 diaktifkan + + + + Click to enable/disable Filter 1 + Klik untuk mengaktifkan/menonaktifkan Filter 1 + + + + Click to enable/disable Filter 2 + Klik untuk mengaktifkan/menonaktifkan Filter 2 + + + + DualFilterControls + + + Filter 1 enabled + Filter 1 diaktifkan + + + + Filter 1 type + Tipe Filter 1 + + + + Cutoff 1 frequency + Frekuensi Cutoff 1 + + + + Q/Resonance 1 + Q/Resonansi 1 + + + + Gain 1 + Gain 1 + + + + Mix + Mix + + + + Filter 2 enabled + Filter 2 diaktifkan + + + + Filter 2 type + Tipe Filter 2 + + + + Cutoff 2 frequency + Frekuensi Cutoff 2 + + + + Q/Resonance 2 + Q/Resonansi 2 + + + + Gain 2 + Gain 2 + + + + + LowPass + LowPass + + + + + HiPass + HiPass + + + + + BandPass csg + BandPass csg + + + + + BandPass czpg + BandPass czpg + + + + + Notch + Notch + + + + + Allpass + Allpass + + + + + Moog + Moog + + + + + 2x LowPass + 2x LowPass + + + + + RC LowPass 12dB + RC LowPass 12dB + + + + + RC BandPass 12dB + RC BandPass 12dB + + + + + RC HighPass 12dB + RC HighPass 12dB + + + + + RC LowPass 24dB + RC LowPass 24dB + + + + + RC BandPass 24dB + RC BandPass 24dB + + + + + RC HighPass 24dB + RC HighPass 24dB + + + + + Vocal Formant Filter + Filter Formant Vokal + + + + + 2x Moog + 2x Moog + + + + + SV LowPass + SV LowPass + + + + + SV BandPass + SV BandPass + + + + + SV HighPass + SV HighPass + + + + + SV Notch + SV Notch + + + + + Fast Formant + Formant Cepat + + + + + Tripole + Tripol + + + + Editor + + + Transport controls + Kontrol transport + + + + Play (Space) + Putar (Spasi) + + + + Stop (Space) + Hentikan (Spasi) + + + + Record + Rekam + + + + Record while playing + Rekam ketika memutar + + + + Effect + + + Effect enabled + Efek diaktifkan + + + + Wet/Dry mix + + + + + Gate + Lawang + + + + Decay + Tahan + + + + EffectChain + + + Effects enabled + Aktifkan efek + + + + EffectRackView + + + EFFECTS CHAIN + RANTAI EFEK + + + + Add effect + Tambah efek + + + + EffectSelectDialog + + + Add effect + Tambah efek + + + + + Name + Nama + + + + Type + Tipe + + + + Description + Deskripsi + + + + Author + Pencipta + + + + EffectView + + + Toggles the effect on or off. + Mengaktifkan atau menonaktifkan efek. + + + + On/Off + Nyala/Mati + + + + W/D + B/K + + + + Wet Level: + Tingkat Basah: + + + + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. + + + + + DECAY + DECAY + + + + Time: + Waktu: + + + + The Decay knob controls how many buffers of silence must pass before the plugin stops processing. Smaller values will reduce the CPU overhead but run the risk of clipping the tail on delay and reverb effects. + Kenop Decay mengontrol berapa banyak buffers of silence yang harus dilewati sebelum plugin berhenti diproses. Nilai yang lebih kecil akan mengurangi overhead CPU namun berisiko clipping pada efek delay dan reverb. + + + + GATE + LAWANG + + + + Gate: + Lawang: + + + + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. + Tombol Lawang mengontrol tingkat sinyal yang dianggap 'diam' saat memutuskan kapan harus menghentikan pemrosesan sinyal. + + + + Controls + Kontrol + + + + Effect plugins function as a chained series of effects where the signal will be processed from top to bottom. + +The On/Off switch allows you to bypass a given plugin at any point in time. + +The Wet/Dry knob controls the balance between the input signal and the effected signal that is the resulting output from the effect. The input for the stage is the output from the previous stage. So, the 'dry' signal for effects lower in the chain contains all of the previous effects. + +The Decay knob controls how long the signal will continue to be processed after the notes have been released. The effect will stop processing signals when the volume has dropped below a given threshold for a given length of time. This knob sets the 'given length of time'. Longer times will require more CPU, so this number should be set low for most effects. It needs to be bumped up for effects that produce lengthy periods of silence, e.g. delays. + +The Gate knob controls the 'given threshold' for the effect's auto shutdown. The clock for the 'given length of time' will begin as soon as the processed signal level drops below the level specified with this knob. + +The Controls button opens a dialog for editing the effect's parameters. + +Right clicking will bring up a context menu where you can change the order in which the effects are processed or delete an effect altogether. + + + + + Move &up + Pindah ke &atas + + + + Move &down + Pindah ke &bawah + + + + &Remove this plugin + &Hapus plugin ini + + + + EnvelopeAndLfoParameters + + + Predelay + Prapenundaan + + + + Attack + Attack + + + + Hold + Tahan + + + + Decay + Decay + + + + Sustain + Tahan + + + + Release + Release + + + + Modulation + Modulasi + + + + LFO Predelay + Prapenundaan LFO + + + + LFO Attack + Attack LFO + + + + LFO speed + Kecepatan LFO + + + + LFO Modulation + Modulasi LFO + + + + LFO Wave Shape + Bentuk Gelombang LFO + + + + Freq x 100 + Frek x 100 + + + + Modulate Env-Amount + Modulasikan Jumlah-Env + + + + EnvelopeAndLfoView + + + + DEL + DEL + + + + Predelay: + Prapenundaan: + + + + Use this knob for setting predelay of the current envelope. The bigger this value the longer the time before start of actual envelope. + + + + + + ATT + ATT + + + + Attack: + Attack: + + + + Use this knob for setting attack-time of the current envelope. The bigger this value the longer the envelope needs to increase to attack-level. Choose a small value for instruments like pianos and a big value for strings. + + + + + HOLD + HOLD + + + + Hold: + Hold: + + + + Use this knob for setting hold-time of the current envelope. The bigger this value the longer the envelope holds attack-level before it begins to decrease to sustain-level. + + + + + DEC + DEC + + + + Decay: + Decay: + + + + Use this knob for setting decay-time of the current envelope. The bigger this value the longer the envelope needs to decrease from attack-level to sustain-level. Choose a small value for instruments like pianos. + + + + + SUST + SUST + + + + Sustain: + Sustain: + + + + Use this knob for setting sustain-level of the current envelope. The bigger this value the higher the level on which the envelope stays before going down to zero. + + + + + REL + REL + + + + Release: + Release: + + + + Use this knob for setting release-time of the current envelope. The bigger this value the longer the envelope needs to decrease from sustain-level to zero. Choose a big value for soft instruments like strings. + + + + + + AMT + JMLH + + + + + Modulation amount: + Jumlah modulasi: + + + + Use this knob for setting modulation amount of the current envelope. The bigger this value the more the according size (e.g. volume or cutoff-frequency) will be influenced by this envelope. + + + + + LFO predelay: + Prapenundaan LFO: + + + + Use this knob for setting predelay-time of the current LFO. The bigger this value the the time until the LFO starts to oscillate. + + + + + LFO- attack: + Attack LFO: + + + + Use this knob for setting attack-time of the current LFO. The bigger this value the longer the LFO needs to increase its amplitude to maximum. + + + + + SPD + SPD + + + + LFO speed: + kecepatan LFO: + + + + Use this knob for setting speed of the current LFO. The bigger this value the faster the LFO oscillates and the faster will be your effect. + + + + + Use this knob for setting modulation amount of the current LFO. The bigger this value the more the selected size (e.g. volume or cutoff-frequency) will be influenced by this LFO. + + + + + Click here for a sine-wave. + Klik disini untuk gelombang-sinus. + + + + Click here for a triangle-wave. + Klik disini untuk gelombang-segitiga. + + + + Click here for a saw-wave for current. + Klik disini untuk gelombang-gergaji untuk saat ini. + + + + Click here for a square-wave. + Klik disini untuk gelombang-kotak. + + + + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. + + + + + Click here for random wave. + Klik di sini untuk gelombang acak. + + + + FREQ x 100 + FREK x 100 + + + + Click here if the frequency of this LFO should be multiplied by 100. + Klik disini jika frekuensi LFO ini dikalikan dengan 100. + + + + multiply LFO-frequency by 100 + Kalikan frekuensi-LFO oleh 100 + + + + MODULATE ENV-AMOUNT + MODULASIKAN JUMLAH-ENV + + + + Click here to make the envelope-amount controlled by this LFO. + + + + + control envelope-amount by this LFO + + + + + ms/LFO: + md/LFO: + + + + Hint + Petunjuk + + + + Drag a sample from somewhere and drop it in this window. + Seret sampel dari suatu tempat dan jatuhkan di jendela ini. + + + + EqControls + + + Input gain + Gain masukan + + + + Output gain + Gain keluaran + + + + Low shelf gain + + + + + Peak 1 gain + Gain peak 1 + + + + Peak 2 gain + Gain peak 2 + + + + Peak 3 gain + Gain peak 3 + + + + Peak 4 gain + Gain peak 4 + + + + High Shelf gain + + + + + HP res + HP res + + + + Low Shelf res + + + + + Peak 1 BW + Peak 1 BW + + + + Peak 2 BW + Peak 2 BW + + + + Peak 3 BW + + + + + Peak 4 BW + + + + + High Shelf res + + + + + LP res + LP res + + + + HP freq + HP freq + + + + Low Shelf freq + + + + + Peak 1 freq + Frek peak 1 + + + + Peak 2 freq + Frek peak 2 + + + + Peak 3 freq + Frek peak 3 + + + + Peak 4 freq + Frek peak 4 + + + + High shelf freq + + + + + LP freq + Frek LP + + + + HP active + HP aktif + + + + Low shelf active + + + + + Peak 1 active + Peak 1 aktif + + + + Peak 2 active + Peak 2 aktif + + + + Peak 3 active + Peak 3 aktif + + + + Peak 4 active + Peak 4 aktif + + + + High shelf active + + + + + LP active + LP aktif + + + + LP 12 + LP 12 + + + + LP 24 + LP 24 + + + + LP 48 + LP 48 + + + + HP 12 + HP 12 + + + + HP 24 + HP 24 + + + + HP 48 + Hp 48 + + + + low pass type + + + + + high pass type + + + + + Analyse IN + + + + + Analyse OUT + + + + + EqControlsDialog + + + HP + HP + + + + Low Shelf + + + + + Peak 1 + Peak 1 + + + + Peak 2 + Peak 2 + + + + Peak 3 + Peak 3 + + + + Peak 4 + Peak 4 + + + + High Shelf + + + + + LP + LP + + + + In Gain + + + + + + + Gain + Gain + + + + Out Gain + Gain Keluar + + + + Bandwidth: + + + + + Octave + Oktaf + + + + Resonance : + Resonansi : + + + + Frequency: + Frekuensi: + + + + lp grp + lp grp + + + + hp grp + hp grp + + + + EqHandle + + + Reso: + Reso: + + + + BW: + BW: + + + + + Freq: + Frek: + + + + ExportProjectDialog + + + Export project + Ekspor proyek + + + + Output + Keluaran + + + + File format: + Format berkas: + + + + Samplerate: + Sampelrate: + + + + 44100 Hz + 44100 Hz + + + + 48000 Hz + 48000 Hz + + + + 88200 Hz + 88200 Hz + + + + 96000 Hz + 96000 Hz + + + + 192000 Hz + 192000 Hz + + + + Depth: + Kedalaman: + + + + 16 Bit Integer + 16 Bit Integer + + + + 24 Bit Integer + 24 Bit Integer + + + + 32 Bit Float + 32 Bit Float + + + + Stereo mode: + Mode Stereo: + + + + Stereo + Stereo + + + + Joint Stereo + + + + + Mono + Mono + + + + Bitrate: + Kecepatan Bit: + + + + 64 KBit/s + 64 KBit/dtk + + + + 128 KBit/s + 128 KBit/dtk + + + + 160 KBit/s + 160 KBit/dtk + + + + 192 KBit/s + 192 KBit/dtk + + + + 256 KBit/s + 256 KBit/dtk + + + + 320 KBit/s + 320 KBit/dtk + + + + Use variable bitrate + Gunakan variabel kecepatan bit + + + + Quality settings + Pengaturan kualitas + + + + Interpolation: + Interpolasi: + + + + Zero Order Hold + + + + + Sinc Fastest + Sinc Tercepat + + + + Sinc Medium (recommended) + Sinc Sedang (direkomendasikan) + + + + Sinc Best (very slow!) + Sinc Terbaik (sangat lambat!) + + + + Oversampling (use with care!): + Oversampling (gunakan dengan hati-hati!): + + + + 1x (None) + 1x (Tidak ada) + + + + 2x + 2x + + + + 4x + 4x + + + + 8x + 8x + + + + Export as loop (remove end silence) + Ekspor sebagai pengulangan (hapus keheningan akhir) + + + + Export between loop markers + Ekspor antar titik pengulangan + + + + Start + Mulai + + + + Cancel + Batal + + + + Could not open file + Tidak bisa membuka berkas + + + + Could not open file %1 for writing. +Please make sure you have write permission to the file and the directory containing the file and try again! + Tidak bisa membuka berkas %1 untuk menulis. +Pastikan Anda memiliki izin menulis ke file dan direktori yang berisi berkas tersebut dan coba lagi! + + + + Export project to %1 + Ekspor proyek ke %1 + + + + Error + Kesalahan + + + + Error while determining file-encoder device. Please try to choose a different output format. + Kesalahan ketika menentukan perangkat encoder-file. Cobalah untuk memilih format keluaran yang berbeda. + + + + Rendering: %1% + Merender: %1% + + + + Fader + + + + Please enter a new value between %1 and %2: + Silakan masukan nilai baru antara %1 dan %2: + + + + FileBrowser + + + Browser + Penjelajah + + + + FileBrowserTreeWidget + + + Send to active instrument-track + Kirim ke trek-instrumen yang aktif + + + + Open in new instrument-track/Song Editor + Buka di trek-instrumen/Editor Lagu yang baru + + + + Open in new instrument-track/B+B Editor + Buka di trek-instrumen/Editor B+B yang baru + + + + Loading sample + Memuat sampel + + + + Please wait, loading sample for preview... + Mohon tunggu, memuat sampel untuk pratinjau... + + + + Error + Kesalahan + + + + does not appear to be a valid + Tampaknya tidak valid + + + + file + berkas + + + + --- Factory files --- + --- Berkas pabrik --- + + + + FlangerControls + + + Delay Samples + Sampel Delay + + + + Lfo Frequency + Frekuensi Lfo + + + + Seconds + Detik + + + + Regen + Regen + + + + Noise + Derau + + + + Invert + Balik + + + + FlangerControlsDialog + + + DELAY + DELAY + + + + Delay Time: + Waktu Delay: + + + + RATE + NILAI + + + + Period: + Periode: + + + + AMNT + JMLH + + + + Amount: + Jumlah: + + + + FDBK + UMPBLK + + + + Feedback Amount: + Jumlah Timbal balik: + + + + NOISE + RIUH + + + + White Noise Amount: + Jumlah Gelombang Riuh: + + + + Invert + Balik + + + + FxLine + + + Channel send amount + Jumlah kirim saluran + + + + The FX channel receives input from one or more instrument tracks. + It in turn can be routed to multiple other FX channels. LMMS automatically takes care of preventing infinite loops for you and doesn't allow making a connection that would result in an infinite loop. + +In order to route the channel to another channel, select the FX channel and click on the "send" button on the channel you want to send to. The knob under the send button controls the level of signal that is sent to the channel. + +You can remove and move FX channels in the context menu, which is accessed by right-clicking the FX channel. + + Saluran FX menerima masukan dari satu atau beberapa trek instrumen. +Hal ini pada gilirannya dapat diarahkan ke beberapa saluran FX lainnya. LMMS secara otomatis menangani mencegah loop tak terbatas untuk Anda dan tidak membiarkan membuat sambungan yang menghasilkan loop tak terbatas. +Untuk mengarahkan saluran ke saluran lain, pilih saluran FX dan klik tombol "kirim" pada saluran yang ingin Anda kirimi. Tombol di bawah tombol kirim mengontrol tingkat sinyal yang dikirim ke saluran . + +Anda dapat menghapus dan memindahkan saluran FX dalam menu konteks, yang diakses dengan mengklik kanan saluran FX. + + + + + Move &left + Pindah ke &kiri + + + + Move &right + Pindah ke &kanan + + + + Rename &channel + Ganti nama &saluran + + + + R&emove channel + H&apus saluran + + + + Remove &unused channels + Hapus &saluran yang tak terpakai + + + + FxMixer + + + Master + Master + + + + + + FX %1 + FX %1 + + + + Volume + Volume + + + + Mute + Bisu + + + + Solo + Solo + + + + FxMixerView + + + FX-Mixer + FX-Mixer + + + + FX Fader %1 + FX Pemudar %1 + + + + Mute + Bisu + + + + Mute this FX channel + Bisukan saluran FX ini + + + + Solo + Solo + + + + Solo FX channel + Saluran FX Solo + + + + FxRoute + + + + Amount to send from channel %1 to channel %2 + Jumlah untuk kirim dari saluran %1 ke saluran %2 + + + + GigInstrument + + + Bank + Bank + + + + Patch + Patch + + + + Gain + Gain + + + + GigInstrumentView + + + Open other GIG file + Buka berkas GIG lainnya + + + + Click here to open another GIG file + klik disini untuk membuka berkas GIG lainnya + + + + Choose the patch + Pilih patch + + + + Click here to change which patch of the GIG file to use + Klik di sini untuk mengubah patch dari berkas GIG yang akan digunakan + + + + + Change which instrument of the GIG file is being played + Ubah instrumen berkas GIG mana yang sedang dimainkan + + + + Which GIG file is currently being used + Berkas GIG mana yang saat ini digunakan + + + + Which patch of the GIG file is currently being used + Patch berkas GIG yang sedang digunakan + + + + Gain + GainGain + + + + Factor to multiply samples by + + + + + Open GIG file + Buka berkas GIG + + + + GIG Files (*.gig) + Berkas GIG (*.gig) + + + + GuiApplication + + + Working directory + Direktori kerja + + + + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. + Direktori kerja LMMS %1 tidak ada. Buat sekarang? Anda dapat mengganti direktori nanti via Edit -> Pengaturan + + + + Preparing UI + Menyiapkan UI + + + + Preparing song editor + Menyiapkan editor lagu + + + + Preparing mixer + Menyiapkan mixer + + + + Preparing controller rack + Menyiapkan rak kontroler + + + + Preparing project notes + Menyiapkan not proyek + + + + Preparing beat/bassline editor + Menyiapkan edior ketukan/bassline + + + + Preparing piano roll + Menyiapkan rol piano + + + + Preparing automation editor + Menyiapkan editor otomasi + + + + InstrumentFunctionArpeggio + + + Arpeggio + Arpeggio + + + + Arpeggio type + Tipe arpeggio + + + + Arpeggio range + Jarak arpeggio + + + + Cycle steps + Langkah siklus + + + + Skip rate + Lewati nilai + + + + Miss rate + Tingkat miss + + + + Arpeggio time + Waktu arpeggio + + + + Arpeggio gate + Gate arpeggio + + + + Arpeggio direction + Arah arpeggio + + + + Arpeggio mode + Mode arpeggio + + + + Up + Atas + + + + Down + Bawah + + + + Up and down + Atas dan bawah + + + + Down and up + Bawah dan atas + + + + Random + Acak + + + + Free + Bebas + + + + Sort + Sortir + + + + Sync + Selaras + + + + InstrumentFunctionArpeggioView + + + ARPEGGIO + ARPEGGIO + + + + An arpeggio is a method playing (especially plucked) instruments, which makes the music much livelier. The strings of such instruments (e.g. harps) are plucked like chords. The only difference is that this is done in a sequential order, so the notes are not played at the same time. Typical arpeggios are major or minor triads, but there are a lot of other possible chords, you can select. + + + + + RANGE + JARAK + + + + Arpeggio range: + Jarak arpeggio: + + + + octave(s) + Oktaf + + + + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. + + + + + CYCLE + SIKLUS + + + + Cycle notes: + Siklus nada: + + + + note(s) + not + + + + Jumps over n steps in the arpeggio and cycles around if we're over the note range. If the total note range is evenly divisible by the number of steps jumped over you will get stuck in a shorter arpeggio or even on one note. + + + + + SKIP + LEWAT + + + + Skip rate: + Lewati nilai: + + + + + + % + % + + + + The skip function will make the arpeggiator pause one step randomly. From its start in full counter clockwise position and no effect it will gradually progress to full amnesia at maximum setting. + + + + + MISS + + + + + Miss rate: + + + + + The miss function will make the arpeggiator miss the intended note. + + + + + TIME + WAKTU + + + + Arpeggio time: + Waktu arpeggio: + + + + ms + md + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + + + + + GATE + LAWANG + + + + Arpeggio gate: + + + + + Use this knob for setting the arpeggio gate. The arpeggio gate specifies the percent of a whole arpeggio-tone that should be played. With this you can make cool staccato arpeggios. + + + + + Chord: + Chord: + + + + Direction: + Arah: + + + + Mode: + Mode: + + + + InstrumentFunctionNoteStacking + + + octave + oktaf + + + + + Major + Mayor + + + + Majb5 + Mayb5 + + + + minor + minor + + + + minb5 + minb5 + + + + sus2 + sus2 + + + + sus4 + sus4 + + + + aug + aug + + + + augsus4 + augsus4 + + + + tri + tri + + + + 6 + 6 + + + + 6sus4 + 6sus4 + + + + 6add9 + 6add9 + + + + m6 + m6 + + + + m6add9 + m6add9 + + + + 7 + 7 + + + + 7sus4 + 7sus4 + + + + 7#5 + 7#5 + + + + 7b5 + 7b5 + + + + 7#9 + 7#9 + + + + 7b9 + 7b9 + + + + 7#5#9 + 7#5#9 + + + + 7#5b9 + 7#5b9 + + + + 7b5b9 + 7b5b9 + + + + 7add11 + 7add11 + + + + 7add13 + 7add13 + + + + 7#11 + 7#11 + + + + Maj7 + May7 + + + + Maj7b5 + May7b5 + + + + Maj7#5 + May7#5 + + + + Maj7#11 + May7#11 + + + + Maj7add13 + May7add13 + + + + m7 + m7 + + + + m7b5 + m7b5 + + + + m7b9 + m7b9 + + + + m7add11 + m7add11 + + + + m7add13 + m7add13 + + + + m-Maj7 + m-May7 + + + + m-Maj7add11 + m-May7add11 + + + + m-Maj7add13 + m-May7add13 + + + + 9 + 9 + + + + 9sus4 + 9sus4 + + + + add9 + add9 + + + + 9#5 + 9#5 + + + + 9b5 + 9b5 + + + + 9#11 + 9#11 + + + + 9b13 + 9b13 + + + + Maj9 + Maj9 + + + + Maj9sus4 + May9sus4 + + + + Maj9#5 + May9#5 + + + + Maj9#11 + May9#11 + + + + m9 + m9 + + + + madd9 + madd9 + + + + m9b5 + m9b5 + + + + m9-Maj7 + m9-Maj7 + + + + 11 + 11 + + + + 11b9 + 11b9 + + + + Maj11 + May11 + + + + m11 + m11 + + + + m-Maj11 + m-May11 + + + + 13 + 13 + + + + 13#9 + 13#9 + + + + 13b9 + 13b9 + + + + 13b5b9 + 13b5b9 + + + + Maj13 + May13 + + + + m13 + m13 + + + + m-Maj13 + m-May13 + + + + Harmonic minor + Harmonic minor + + + + Melodic minor + Melodic minor + + + + Whole tone + Whole tone + + + + Diminished + Diminished + + + + Major pentatonic + Pentatonik mayor + + + + Minor pentatonic + Pentatonik minor + + + + Jap in sen + Jap in sen + + + + Major bebop + Bebop Mayor + + + + Dominant bebop + Dominan bebop + + + + Blues + Blues + + + + Arabic + Arabic + + + + Enigmatic + Enigmatic + + + + Neopolitan + Neopolitan + + + + Neopolitan minor + Neopolitan minor + + + + Hungarian minor + Hungarian minor + + + + Dorian + Dorian + + + + Phrygian + + + + + Lydian + Lydian + + + + Mixolydian + Mixolydian + + + + Aeolian + Aeolian + + + + Locrian + Locrian + + + + Minor + Minor + + + + Chromatic + Chromatic + + + + Half-Whole Diminished + Half-Whole Diminished + + + + 5 + 5 + + + + Phrygian dominant + Dominan frigia + + + + Persian + Persia + + + + Chords + Chord + + + + Chord type + Tipe Chord + + + + Chord range + Jarak Chord + + + + InstrumentFunctionNoteStackingView + + + STACKING + + + + + Chord: + Chord: + + + + RANGE + JARAK + + + + Chord range: + Jarak chord: + + + + octave(s) + Oktaf(beberapa) + + + + Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. + + + + + InstrumentMidiIOView + + + ENABLE MIDI INPUT + AKTIFKAN MASUKAN MIDI + + + + + CHANNEL + SALURAN + + + + + VELOCITY + + + + + ENABLE MIDI OUTPUT + AKTIFKAN KELUARAN MIDI + + + + PROGRAM + PROGRAM + + + + NOTE + CATATAN + + + + MIDI devices to receive MIDI events from + Perangkat MIDI untuk menerima event MIDI dari + + + + MIDI devices to send MIDI events to + Perangkat MIDI untuk kirim event MIDI ke + + + + CUSTOM BASE VELOCITY + + + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + + + + + BASE VELOCITY + + + + + InstrumentMiscView + + + MASTER PITCH + MASTER PITCH + + + + Enables the use of Master Pitch + Aktifkan penggunaan Master Pitch + + + + InstrumentSoundShaping + + + VOLUME + VOLUME + + + + Volume + Volume + + + + + CUTOFF + + + + + + Cutoff frequency + Frekuensi cutoff + + + + RESO + RESO + + + + Resonance + Resonansi + + + + Envelopes/LFOs + + + + + Filter type + Tipe filter + + + + Q/Resonance + + + + + LowPass + LowPass + + + + HiPass + HiPass + + + + BandPass csg + BandPass csg + + + + BandPass czpg + BandPass czpg + + + + Notch + Notch + + + + Allpass + Allpass + + + + Moog + Moog + + + + 2x LowPass + 2x LowPass + + + + RC LowPass 12dB + RC LowPass 12dB + + + + RC BandPass 12dB + RC BandPass 12dB + + + + RC HighPass 12dB + RC HighPass 12dB + + + + RC LowPass 24dB + RC LowPass 24dB + + + + RC BandPass 24dB + RC BandPass 24dB + + + + RC HighPass 24dB + RC HighPass 24dB + + + + Vocal Formant Filter + Filter Formant Vokal + + + + 2x Moog + 2x Moog + + + + SV LowPass + SV LowPass + + + + SV BandPass + SV BandPass + + + + SV HighPass + SV HighPass + + + + SV Notch + SV Notch + + + + Fast Formant + Formant Cepat + + + + Tripole + Tripol + + + + InstrumentSoundShapingView + + + TARGET + SASARAN + + + + These tabs contain envelopes. They're very important for modifying a sound, in that they are almost always necessary for substractive synthesis. For example if you have a volume envelope, you can set when the sound should have a specific volume. If you want to create some soft strings then your sound has to fade in and out very softly. This can be done by setting large attack and release times. It's the same for other envelope targets like panning, cutoff frequency for the used filter and so on. Just monkey around with it! You can really make cool sounds out of a saw-wave with just some envelopes...! + + + + + FILTER + FILTER + + + + Here you can select the built-in filter you want to use for this instrument-track. Filters are very important for changing the characteristics of a sound. + + + + + FREQ + FREK + + + + cutoff frequency: + frekuensi cutoff: + + + + Hz + Hz + + + + Use this knob for setting the cutoff frequency for the selected filter. The cutoff frequency specifies the frequency for cutting the signal by a filter. For example a lowpass-filter cuts all frequencies above the cutoff frequency. A highpass-filter cuts all frequencies below cutoff frequency, and so on... + + + + + RESO + RESO + + + + Resonance: + Resonansi: + + + + Use this knob for setting Q/Resonance for the selected filter. Q/Resonance tells the filter how much it should amplify frequencies near Cutoff-frequency. + + + + + Envelopes, LFOs and filters are not supported by the current instrument. + + + + + InstrumentTrack + + + With this knob you can set the volume of the opened channel. + + + + + + unnamed_track + trek_tak_bernama + + + + Base note + Not dasar + + + + Volume + Volume + + + + + Panning + Keseimbangan + + + + Pitch + Pitch + + + + Pitch range + Jarak pitch + + + + FX channel + Saluran FX + + + + Master Pitch + + + + + + Default preset + Preset default + + + + InstrumentTrackView + + + Volume + Volume + + + + + Volume: + Volume: + + + + VOL + VOL + + + + Panning + Keseimbangan + + + + Panning: + Keseimbangan: + + + + PAN + PAN + + + + MIDI + MIDI + + + + Input + Masukan + + + + Output + Keluaran + + + + FX %1: %2 + FX %1: %2 + + + + InstrumentTrackWindow + + + GENERAL SETTINGS + PENGATURAN UMUM + + + + Use these controls to view and edit the next/previous track in the song editor. + Gunakan kontrol ini untuk melihat dan mengubah trek berikutnya / sebelumnya di editor lagu. + + + + Instrument volume + Volume instrumen + + + + Volume: + Volume: + + + + VOL + VOL + + + + Panning + Keseimbangan + + + + Panning: + Keseimbangan: + + + + PAN + PAN + + + + Pitch + Pitch + + + + Pitch: + Pitch: + + + + cents + sen + + + + PITCH + + + + + Pitch range (semitones) + + + + + RANGE + JARAK + + + + FX channel + Saluran FX + + + + FX + FX + + + + Save current instrument track settings in a preset file + Simpan pengaturan trek instrumen saat ini kedalam berkas preset + + + + Click here, if you want to save current instrument track settings in a preset file. Later you can load this preset by double-clicking it in the preset-browser. + Klik disini jika Anda ingin menyimpan pengaturan trek instrumen saat ini kedalam berkas preset. Nantinya Anda dapat memuat preset ini dengan mengklik dua kali pada preset-browser. + + + + SAVE + SIMPAN + + + + Envelope, filter & LFO + + + + + Chord stacking & arpeggio + + + + + Effects + Efek + + + + MIDI settings + Pengaturan MIDI + + + + Miscellaneous + Serba aneka + + + + Save preset + Simpan preset + + + + XML preset file (*.xpf) + Berkas preset XML (*.xpf) + + + + Plugin + Plugin + + + + Knob + + + Set linear + Atur linier + + + + Set logarithmic + Atur logaritmik + + + + Please enter a new value between -96.0 dBFS and 6.0 dBFS: + Silakan masukan nilai baru antara -96.0 dBFS dan 6.0 dBFS: + + + + Please enter a new value between %1 and %2: + Silakan masukan nilai baru antara %1 dan %2: + + + + LadspaControl + + + Link channels + Hubungkan saluran + + + + LadspaControlDialog + + + Link Channels + Hubungkan Saluran + + + + Channel + Saluran + + + + LadspaControlView + + + Link channels + Hubungkan saluran + + + + Value: + Nilai: + + + + Sorry, no help available. + Maaf, tidak ada bantuan tersedia. + + + + LadspaEffect + + + Unknown LADSPA plugin %1 requested. + Plugin LADSPA yang tidak diketahui %1 diminta. + + + + LcdSpinBox + + + Please enter a new value between %1 and %2: + Silakan masukan nilai baru antara %1 dan %2: + + + + LeftRightNav + + + + + Previous + Sebelumnya + + + + + + Next + Selanjutnya + + + + Previous (%1) + Sebelumnya (%1) + + + + Next (%1) + Selanjutnya (%1) + + + + LfoController + + + LFO Controller + Kontroler LFO + + + + Base value + Nilai dasar + + + + Oscillator speed + Kecepatan osilator + + + + Oscillator amount + Jumlah osilator + + + + Oscillator phase + Tahap osilator + + + + Oscillator waveform + Bentuk gelombang osilator + + + + Frequency Multiplier + + + + + LfoControllerDialog + + + LFO + LFO + + + + LFO Controller + Kontroler LFO + + + + BASE + DASAR + + + + Base amount: + Jumlah dasar: + + + + todo + untuk-dilakukan + + + + SPD + SPD + + + + LFO-speed: + Kecepatan-LFO: + + + + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + Gunakan kenop ini untuk mengatur kecepatan LFO. Semakin besar nilai maka semakin cepat LFO berosilasi dan semakin cepat efeknya. + + + + AMNT + JMLH + + + + Modulation amount: + Jumlah modulasi: + + + + Use this knob for setting modulation amount of the LFO. The bigger this value, the more the connected control (e.g. volume or cutoff-frequency) will be influenced by the LFO. + + + + + PHS + PHS + + + + Phase offset: + + + + + degrees + derajat + + + + With this knob you can set the phase offset of the LFO. That means you can move the point within an oscillation where the oscillator begins to oscillate. For example if you have a sine-wave and have a phase-offset of 180 degrees the wave will first go down. It's the same with a square-wave. + + + + + Click here for a sine-wave. + Klik disini untuk gelombang-sinus. + + + + Click here for a triangle-wave. + Klik disini untuk gelombang-segitiga. + + + + Click here for a saw-wave. + Klik disini untuk gelombang gergaji. + + + + Click here for a square-wave. + Klik disini untuk gelombang-kotak. + + + + Click here for a moog saw-wave. + + + + + Click here for an exponential wave. + Klik disini untuk gelombang eksponensial. + + + + Click here for white-noise. + Klik disini untuk kebisingan-putih. + + + + Click here for a user-defined shape. +Double click to pick a file. + + + + + LmmsCore + + + Generating wavetables + Membuat wavetables + + + + Initializing data structures + Inisialisasi struktur data + + + + Opening audio and midi devices + Membuka audio dan perangkat midi + + + + Launching mixer threads + Meluncurkan thread mixer + + + + MainWindow + + + Configuration file + Berkas konfigurasi + + + + Error while parsing configuration file at line %1:%2: %3 + Kesalahan saat mengurai berkas konfigurasi pada baris %1:%2 %3 + + + + Could not open file + Tidak bisa membuka berkas + + + + Could not open file %1 for writing. +Please make sure you have write permission to the file and the directory containing the file and try again! + Tidak bisa membuka berkas %1 + + + + Project recovery + Pemulihan proyek + + + + There is a recovery file present. It looks like the last session did not end properly or another instance of LMMS is already running. Do you want to recover the project of this session? + + + + + + + Recover + Pulihkan + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + Memulihkan berkas. Jangan menjalankan beberapa instansi LMMS saat Anda melakukan ini. + + + + + + Discard + Buang + + + + Launch a default session and delete the restored files. This is not reversible. + Jalankan sesi default dan hapus berkas yang dipulihkan. Ini tidak reversibel. + + + + Version %1 + Versi %1 + + + + Preparing plugin browser + Menyiapkan penjelajah plugin + + + + Preparing file browsers + Menyiapkan penjelajah berkas + + + + My Projects + Proyek Saya + + + + My Samples + Sampel Saya + + + + My Presets + Preset Saya + + + + My Home + Rumah Saya + + + + Root directory + Direktori root + + + + Volumes + Volume + + + + My Computer + Komputer Saya + + + + Loading background artwork + Memuat karya seni latar belakang + + + + &File + &Berkas + + + + &New + &Baru + + + + New from template + Baru dari template + + + + &Open... + &Buka + + + + &Recently Opened Projects + &Proyek yang Baru Dibuka + + + + &Save + &Simpan + + + + Save &As... + Simpan &Sebagai... + + + + Save as New &Version + Simpan sebagai &Versi yang baru + + + + Save as default template + Simpan sebagai template default + + + + Import... + Impor... + + + + E&xport... + E&kspor + + + + E&xport Tracks... + E&kspor trek... + + + + Export &MIDI... + Ekspor &MIDI... + + + + &Quit + &Keluar + + + + &Edit + &Edit + + + + Undo + Undo + + + + Redo + Redo + + + + Settings + Pengaturan + + + + &View + &Tampilan + + + + &Tools + &Alat + + + + &Help + &Bantuan + + + + Online Help + Bantuan Daring + + + + Help + Bantuan + + + + What's This? + Apa Ini? + + + + About + Ihwal + + + + Create new project + Buat proyek baru + + + + Create new project from template + Buat proyek baru dari template + + + + Open existing project + Buka proyek yang sudah ada + + + + Recently opened projects + Proyek yang Baru Dibuka + + + + Save current project + Simpan proyek saat ini + + + + Export current project + Ekspor proyek saat ini + + + + What's this? + Apa ini? + + + + Toggle metronome + Toggle metronom + + + + Show/hide Song-Editor + Tampilkan/sembunyikan Editor-Lagu + + + + By pressing this button, you can show or hide the Song-Editor. With the help of the Song-Editor you can edit song-playlist and specify when which track should be played. You can also insert and move samples (e.g. rap samples) directly into the playlist. + + + + + Show/hide Beat+Bassline Editor + Tampilkan/sembunyikan Editor Bassline+Ketukan + + + + By pressing this button, you can show or hide the Beat+Bassline Editor. The Beat+Bassline Editor is needed for creating beats, and for opening, adding, and removing channels, and for cutting, copying and pasting beat and bassline-patterns, and for other things like that. + + + + + Show/hide Piano-Roll + Tampilkan/sembunyikan Rol-Piano + + + + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. + Klik disini untuk menampilkan atau menyembunyikan Rol-Piano. Dengan bantuan Rol-Piano Anda dapat mengubah melodu dengan mudah. + + + + Show/hide Automation Editor + Tampilkan/sembunyikan Editor Otomasi + + + + Click here to show or hide the Automation Editor. With the help of the Automation Editor you can edit dynamic values in an easy way. + + + + + Show/hide FX Mixer + Tampilkan/sembunyikan FX Mixer + + + + Click here to show or hide the FX Mixer. The FX Mixer is a very powerful tool for managing effects for your song. You can insert effects into different effect-channels. + Klik disini untuk menampilkan atau menyembunyikan FX Mixer. FX Mixer adalah alat yang sangat ampuh untuk mengelola efek untuk lagu Anda. Anda bisa memasukkan efek ke saluran efek yang berbeda. + + + + Show/hide project notes + Tampilkan/sembunyikan not proyek + + + + Click here to show or hide the project notes window. In this window you can put down your project notes. + + + + + Show/hide controller rack + Tampilkan/sembunyikan rak kontroler + + + + Untitled + Tak berjudul + + + + Recover session. Please save your work! + Sesi pemulihan. Tolong simpan pekerjaanmu! + + + + LMMS %1 + LMMS %1 + + + + Recovered project not saved + Proyek yang dipulihkan tidak disimpan + + + + This project was recovered from the previous session. It is currently unsaved and will be lost if you don't save it. Do you want to save it now? + Proyek ini dipulihkan dari sesi sebelumnya. Saat ini belum disimpan dan akan hilang jika Anda tidak menyimpannya. Apakah Anda ingin menyimpannya sekarang? + + + + Project not saved + Proyek tidak disimpan + + + + The current project was modified since last saving. Do you want to save it now? + Proyek saat ini sudah dimodifikasi sejak penyimpanan terakhir. Apakah anda ingin menyimpannya sekarang? + + + + Open Project + Buka Proyek + + + + LMMS (*.mmp *.mmpz) + LMMS (*.mmp *.mmpz) + + + + Save Project + Simpan Proyek + + + + LMMS Project + Proyek LMMS + + + + LMMS Project Template + Proyek Template LMMS + + + + Save project template + Simpan template proyek + + + + Overwrite default template? + Timpa template default? + + + + This will overwrite your current default template. + Ini akan menimpa template default Anda saat ini. + + + + Help not available + Bantuan tidak tersedia + + + + Currently there's no help available in LMMS. +Please visit http://lmms.sf.net/wiki for documentation on LMMS. + Sasat ini belum ada bantuan tersedia di LMMS. +Silakan kunjungi http://lmms.sf.net/wiki untuk dokumentasi LMMS. + + + + Song Editor + Editor Lagu + + + + Beat+Bassline Editor + Editor Bassline+ketukan + + + + Piano Roll + Rol Piano + + + + Automation Editor + Editor Otomasi + + + + FX Mixer + FX Mixer + + + + Project Notes + Catatan Proyek + + + + Controller Rack + Kontroler rak + + + + Volume as dBFS + Volume sebagai dBFS + + + + Smooth scroll + Gulung halus + + + + Enable note labels in piano roll + Aktifkan label not di rol piano + + + + MeterDialog + + + + Meter Numerator + + + + + + Meter Denominator + + + + + TIME SIG + + + + + MeterModel + + + Numerator + + + + + Denominator + + + + + MidiController + + + MIDI Controller + Kontroler MIDI + + + + unnamed_midi_controller + kontroler_midi_tanpa_nama + + + + MidiImport + + + + Setup incomplete + Pemasangan tidak lengkap + + + + You do not have set up a default soundfont in the settings dialog (Edit->Settings). Therefore no sound will be played back after importing this MIDI file. You should download a General MIDI soundfont, specify it in settings dialog and try again. + Anda tidak menyetel pemutar soundfont default pada dialog pengaturan (Edit->Pengaturan). Oleh karena itu tidak ada suara yang akan diputar setelah mengimpor berkas MIDI ini. Anda harus mengunduh MIDI soundfont yang umum, tentukan di dialog pengaturan lalu coba lagi. + + + + You did not compile LMMS with support for SoundFont2 player, which is used to add default sound to imported MIDI files. Therefore no sound will be played back after importing this MIDI file. + Anda tidak mengkompilasi LMMS dengan dukungan pemutar SoundFont2, yang digunakan untuk menambah suara default ke berkas MIDI yang diimpor. Oleh karena itu tidak ada suara yang akan diputer setelah mengimpor berkas MIDI ini. + + + + Track + Trek + + + + MidiJack + + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + Server JACK lumpuh + + + + The JACK server seems to be shuted down. + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) + + + + + MidiPort + + + Input channel + Saluran Masukan + + + + Output channel + Saluran keluaran + + + + Input controller + Kontroler masukan + + + + Output controller + Kontroler keluaran + + + + Fixed input velocity + + + + + Fixed output velocity + + + + + Fixed output note + + + + + Output MIDI program + Program MIDI keluaran + + + + Base velocity + Kecepatan dasar + + + + Receive MIDI-events + Terima aktifitas-MIDI + + + + Send MIDI-events + Kirim aktifitas-MIDI + + + + MidiSetupWidget + + + DEVICE + PERANGKAT + + + + MonstroInstrument + + + Osc 1 Volume + Volume Osc 1 + + + + Osc 1 Panning + Keseimbangan Osc 1 + + + + Osc 1 Coarse detune + + + + + Osc 1 Fine detune left + + + + + Osc 1 Fine detune right + + + + + Osc 1 Stereo phase offset + + + + + Osc 1 Pulse width + + + + + Osc 1 Sync send on rise + + + + + Osc 1 Sync send on fall + + + + + Osc 2 Volume + Volume Osc 2 + + + + Osc 2 Panning + Kesimbangan Osc 2 + + + + Osc 2 Coarse detune + + + + + Osc 2 Fine detune left + + + + + Osc 2 Fine detune right + + + + + Osc 2 Stereo phase offset + + + + + Osc 2 Waveform + + + + + Osc 2 Sync Hard + + + + + Osc 2 Sync Reverse + + + + + Osc 3 Volume + Volume Osc 3 + + + + Osc 3 Panning + Keseimbangan Osc 3 + + + + Osc 3 Coarse detune + + + + + Osc 3 Stereo phase offset + + + + + Osc 3 Sub-oscillator mix + + + + + Osc 3 Waveform 1 + + + + + Osc 3 Waveform 2 + + + + + Osc 3 Sync Hard + + + + + Osc 3 Sync Reverse + + + + + LFO 1 Waveform + Betuk gelombang LFO 1 + + + + LFO 1 Attack + Attack LFO 1 + + + + LFO 1 Rate + Nilai LFO 1 + + + + LFO 1 Phase + Phase LFO 1 + + + + LFO 2 Waveform + Betuk gelombang LFO 2 + + + + LFO 2 Attack + Attack LFO 2 + + + + LFO 2 Rate + Nilai LFO 2 + + + + LFO 2 Phase + Phase LFO 2 + + + + Env 1 Pre-delay + Prapenundaan Env 1 + + + + Env 1 Attack + Attack Env 1 + + + + Env 1 Hold + + + + + Env 1 Decay + + + + + Env 1 Sustain + + + + + Env 1 Release + + + + + Env 1 Slope + + + + + Env 2 Pre-delay + + + + + Env 2 Attack + + + + + Env 2 Hold + + + + + Env 2 Decay + + + + + Env 2 Sustain + + + + + Env 2 Release + + + + + Env 2 Slope + + + + + Osc2-3 modulation + + + + + Selected view + Tampilan yang dipilih + + + + Vol1-Env1 + Vol1-Env1 + + + + Vol1-Env2 + Vol1-Env2 + + + + Vol1-LFO1 + Vol1-LFO1 + + + + Vol1-LFO2 + Vol1-LFO2 + + + + Vol2-Env1 + Vol2-Env1 + + + + Vol2-Env2 + Vol2-Env2 + + + + Vol2-LFO1 + Vol2-LFO1 + + + + Vol2-LFO2 + Vol2-LFO2 + + + + Vol3-Env1 + Vol3-Env1 + + + + Vol3-Env2 + Vol3-Env2 + + + + Vol3-LFO1 + Vol3-LFO1 + + + + Vol3-LFO2 + Vol3-LFO2 + + + + Phs1-Env1 + Phs1-Env1 + + + + Phs1-Env2 + Phs1-Env2 + + + + Phs1-LFO1 + Phs1-LFO1 + + + + Phs1-LFO2 + Phs1-LFO2 + + + + Phs2-Env1 + Phs2-Env1 + + + + Phs2-Env2 + Phs2-Env2 + + + + Phs2-LFO1 + Phs2-LFO1 + + + + Phs2-LFO2 + Phs2-LFO2 + + + + Phs3-Env1 + Phs3-Env1 + + + + Phs3-Env2 + Phs3-Env2 + + + + Phs3-LFO1 + Phs3-LFO1 + + + + Phs3-LFO2 + Phs3-LFO2 + + + + Pit1-Env1 + Pit1-Env1 + + + + Pit1-Env2 + Pit1-Env2 + + + + Pit1-LFO1 + Pit1-LFO1 + + + + Pit1-LFO2 + Pit1-LFO2 + + + + Pit2-Env1 + Pit2-Env1 + + + + Pit2-Env2 + Pit2-Env2 + + + + Pit2-LFO1 + Pit2-LFO1 + + + + Pit2-LFO2 + Pit2-LFO2 + + + + Pit3-Env1 + Pit3-Env1 + + + + Pit3-Env2 + Pit3-Env2 + + + + Pit3-LFO1 + Pit3-LFO1 + + + + Pit3-LFO2 + Pit3-LFO2 + + + + PW1-Env1 + PW1-Env1 + + + + PW1-Env2 + PW1-Env2 + + + + PW1-LFO1 + PW1-LFO1 + + + + PW1-LFO2 + PW1-LFO2 + + + + Sub3-Env1 + Sub3-Env1 + + + + Sub3-Env2 + Sub3-Env2 + + + + Sub3-LFO1 + Sub3-LFO1 + + + + Sub3-LFO2 + Sub3-LFO2 + + + + + Sine wave + Gelombang sinus + + + + Bandlimited Triangle wave + + + + + Bandlimited Saw wave + + + + + Bandlimited Ramp wave + + + + + Bandlimited Square wave + + + + + Bandlimited Moog saw wave + + + + + + Soft square wave + Gelombang kotak halus + + + + Absolute sine wave + Gelombang sinus absolut + + + + + Exponential wave + + + + + White noise + Kebisingan putih + + + + Digital Triangle wave + Gelombang Segitiga digital + + + + Digital Saw wave + Gelombang Gergaji digital + + + + Digital Ramp wave + + + + + Digital Square wave + Gelombang Kotak digital + + + + Digital Moog saw wave + + + + + Triangle wave + Gelombang segitiga + + + + Saw wave + Gelombang gergaji + + + + Ramp wave + + + + + Square wave + Gelombang kotak + + + + Moog saw wave + + + + + Abs. sine wave + + + + + Random + Acak + + + + Random smooth + Halus acak + + + + MonstroView + + + Operators view + Tampilan operator + + + + The Operators view contains all the operators. These include both audible operators (oscillators) and inaudible operators, or modulators: Low-frequency oscillators and Envelopes. + +Knobs and other widgets in the Operators view have their own what's this -texts, so you can get more specific help for them that way. + + + + + Matrix view + Tampilan matrix + + + + The Matrix view contains the modulation matrix. Here you can define the modulation relationships between the various operators: Each audible operator (oscillators 1-3) has 3-4 properties that can be modulated by any of the modulators. Using more modulations consumes more CPU power. + +The view is divided to modulation targets, grouped by the target oscillator. Available targets are volume, pitch, phase, pulse width and sub-osc ratio. Note: some targets are specific to one oscillator only. + +Each modulation target has 4 knobs, one for each modulator. By default the knobs are at 0, which means no modulation. Turning a knob to 1 causes that modulator to affect the modulation target as much as possible. Turning it to -1 does the same, but the modulation is inversed. + + + + + + + Volume + Volume + + + + + + + Panning + Keseimbangan + + + + + + Coarse detune + Detune kasar + + + + + + semitones + + + + + + Finetune left + + + + + + + + cents + sen + + + + + Finetune right + + + + + + + Stereo phase offset + + + + + + + + + deg + + + + + Pulse width + + + + + Send sync on pulse rise + + + + + Send sync on pulse fall + + + + + Hard sync oscillator 2 + + + + + Reverse sync oscillator 2 + + + + + Sub-osc mix + + + + + Hard sync oscillator 3 + + + + + Reverse sync oscillator 3 + + + + + + + + Attack + Attack + + + + + Rate + Nilai + + + + + Phase + + + + + + Pre-delay + + + + + + Hold + Tahan + + + + + Decay + Tahan + + + + + Sustain + Tahan + + + + + Release + Release + + + + + Slope + + + + + Mix Osc2 with Osc3 + + + + + Modulate amplitude of Osc3 with Osc2 + + + + + Modulate frequency of Osc3 with Osc2 + + + + + Modulate phase of Osc3 with Osc2 + + + + + The CRS knob changes the tuning of oscillator 1 in semitone steps. + + + + + The CRS knob changes the tuning of oscillator 2 in semitone steps. + + + + + The CRS knob changes the tuning of oscillator 3 in semitone steps. + + + + + + + + FTL and FTR change the finetuning of the oscillator for left and right channels respectively. These can add stereo-detuning to the oscillator which widens the stereo image and causes an illusion of space. + + + + + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. + + + + + The PW knob controls the pulse width, also known as duty cycle, of oscillator 1. Oscillator 1 is a digital pulse wave oscillator, it doesn't produce bandlimited output, which means that you can use it as an audible oscillator but it will cause aliasing. You can also use it as an inaudible source of a sync signal, which can be used to synchronize oscillators 2 and 3. + + + + + Send Sync on Rise: When enabled, the Sync signal is sent every time the state of oscillator 1 changes from low to high, ie. when the amplitude changes from -1 to 1. Oscillator 1's pitch, phase and pulse width may affect the timing of syncs, but its volume has no effect on them. Sync signals are sent independently for both left and right channels. + + + + + Send Sync on Fall: When enabled, the Sync signal is sent every time the state of oscillator 1 changes from high to low, ie. when the amplitude changes from 1 to -1. Oscillator 1's pitch, phase and pulse width may affect the timing of syncs, but its volume has no effect on them. Sync signals are sent independently for both left and right channels. + + + + + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. + + + + + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. + + + + + Choose waveform for oscillator 2. + Pilih bentuk gelombang untuk osilator 2. + + + + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + + + + + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + + + + + The SUB knob changes the mixing ratio of the two sub-oscs of oscillator 3. Each sub-osc can be set to produce a different waveform, and oscillator 3 can smoothly interpolate between them. All incoming modulations to oscillator 3 are applied to both sub-oscs/waveforms in the exact same way. + + + + + In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. + +Mix mode means no modulation: the outputs of the oscillators are simply mixed together. + + + + + In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. + +AM means amplitude modulation: Oscillator 3's amplitude (volume) is modulated by oscillator 2. + + + + + In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. + +FM means frequency modulation: Oscillator 3's frequency (pitch) is modulated by oscillator 2. The frequency modulation is implemented as phase modulation, which gives a more stable overall pitch than "pure" frequency modulation. + + + + + In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. + +PM means phase modulation: Oscillator 3's phase is modulated by oscillator 2. It differs from frequency modulation in that the phase changes are not cumulative. + + + + + Select the waveform for LFO 1. +"Random" and "Random smooth" are special waveforms: they produce random output, where the rate of the LFO controls how often the state of the LFO changes. The smooth version interpolates between these states with cosine interpolation. These random modes can be used to give "life" to your presets - add some of that analog unpredictability... + + + + + Select the waveform for LFO 2. +"Random" and "Random smooth" are special waveforms: they produce random output, where the rate of the LFO controls how often the state of the LFO changes. The smooth version interpolates between these states with cosine interpolation. These random modes can be used to give "life" to your presets - add some of that analog unpredictability... + + + + + + Attack causes the LFO to come on gradually from the start of the note. + + + + + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. + + + + + + PHS controls the phase offset of the LFO. + + + + + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. + + + + + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. + + + + + + HOLD controls how long the envelope stays at peak after the attack phase. + + + + + + DEC, or decay, controls how fast the envelope falls off from its peak, measured in milliseconds it would take to go from peak to zero. The actual decay may be shorter if sustain is used. + + + + + + SUS, or sustain, controls the sustain level of the envelope. The decay phase will not go below this level as long as the note is held. + + + + + + REL, or release, controls how long the release is for the note, measured in how long it would take to fall from peak to zero. Actual release may be shorter, depending on at what phase the note is released. + + + + + + The slope knob controls the curve or shape of the envelope. A value of 0 creates straight rises and falls. Negative values create curves that start slowly, peak quickly and fall of slowly again. Positive values create curves that start and end quickly, and stay longer near the peaks. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount + + + + + MultitapEchoControlDialog + + + Length + Panjang + + + + Step length: + + + + + Dry + + + + + Dry Gain: + + + + + Stages + + + + + Lowpass stages: + + + + + Swap inputs + Tukar masukan + + + + Swap left and right input channel for reflections + Tukar masukan kiri dan kanan saluran untuk refleksi + + + + NesInstrument + + + Channel 1 Coarse detune + + + + + Channel 1 Volume + Volume Saluran 1 + + + + Channel 1 Envelope length + + + + + Channel 1 Duty cycle + + + + + Channel 1 Sweep amount + + + + + Channel 1 Sweep rate + + + + + Channel 2 Coarse detune + + + + + Channel 2 Volume + Volume Saluran 2 + + + + Channel 2 Envelope length + + + + + Channel 2 Duty cycle + + + + + Channel 2 Sweep amount + + + + + Channel 2 Sweep rate + + + + + Channel 3 Coarse detune + + + + + Channel 3 Volume + Volume Saluran 3 + + + + Channel 4 Volume + Volume Saluran 4 + + + + Channel 4 Envelope length + + + + + Channel 4 Noise frequency + + + + + Channel 4 Noise frequency sweep + + + + + Master volume + Volume master + + + + Vibrato + Getaran + + + + NesInstrumentView + + + + + + Volume + Volume + + + + + + + Coarse detune + Detune kasar + + + + + + Envelope length + Panjang sampul + + + + Enable channel 1 + Aktifkan saluran 1 + + + + Enable envelope 1 + Aktifkan sampul 1 + + + + Enable envelope 1 loop + Akftifkan envelop pengulangan 1 + + + + Enable sweep 1 + + + + + + Sweep amount + + + + + + Sweep rate + + + + + + 12.5% Duty cycle + Siklus tugas 12,5% + + + + + 25% Duty cycle + Siklus tugas 25% + + + + + 50% Duty cycle + Siklus tugas 50% + + + + + 75% Duty cycle + Siklus tugas 75% + + + + Enable channel 2 + Aktifkan saluran 2 + + + + Enable envelope 2 + Aktifkan sampul 2 + + + + Enable envelope 2 loop + Akftifkan envelop pengulangan 2 + + + + Enable sweep 2 + + + + + Enable channel 3 + Aktifkan saluran 3 + + + + Noise Frequency + Frekuensi Riuh + + + + Frequency sweep + + + + + Enable channel 4 + Aktifkan saluran 4 + + + + Enable envelope 4 + Aktifkan sampul 4 + + + + Enable envelope 4 loop + Akftifkan envelop pengulangan 4 + + + + Quantize noise frequency when using note frequency + + + + + Use note frequency for noise + Gunakan frekuensi not untuk riuh + + + + Noise mode + Mode derau + + + + Master Volume + Volume Master + + + + Vibrato + Getaran + + + + OscillatorObject + + + Osc %1 waveform + Bentuk gelombang Osc %1 + + + + Osc %1 harmonic + + + + + + Osc %1 volume + Volume Osc %1 + + + + + Osc %1 panning + Keseimbangan Osc %1 + + + + + Osc %1 fine detuning left + + + + + Osc %1 coarse detuning + + + + + Osc %1 fine detuning right + + + + + Osc %1 phase-offset + + + + + Osc %1 stereo phase-detuning + + + + + Osc %1 wave shape + bentuk gelombang Osc %1 + + + + Modulation type %1 + Tipe modulasi %1 + + + + PatchesDialog + + + Qsynth: Channel Preset + + + + + Bank selector + Pemilih bank + + + + Bank + Bank + + + + Program selector + Pemilih program + + + + Patch + Patch + + + + Name + Nama + + + + OK + OK + + + + Cancel + Batal + + + + PatmanView + + + Open other patch + Buka patch lain + + + + Click here to open another patch-file. Loop and Tune settings are not reset. + Klik disini untuk membuka file patch lainnya. Pengaturan Pengulangan dan Langgam tidak diatur ulang. + + + + Loop + Pengulangan + + + + Loop mode + Mode pengulangan + + + + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + Di sini Anda bisa mengaktifkan mode Pengulangan. Jika diaktifkan, PatMan akan menggunakan informasi pengulangan yang tersedia dalam file. + + + + Tune + Nada + + + + Tune mode + Mode nada + + + + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + Disini kamu bisa mengaktifkan/menonaktifkan mode Nada. Jika diaktifkan, PatMan akan mengatur sampel agar cocok dengan frekuensi not. + + + + No file selected + Tidak ada berkas dipilih + + + + Open patch file + Buka berkas patch + + + + Patch-Files (*.pat) + Berkas-Patch (*.pat) + + + + PatternView + + + use mouse wheel to set velocity of a step + Gunakan roda tetikus untuk mengatur kecepatan langkah + + + + double-click to open in Piano Roll + Klik dua kali untuk membuka di Rol Piano + + + + Open in piano-roll + Buka di rol-piano + + + + Clear all notes + Bersihkan semua not + + + + Reset name + Reset nama + + + + Change name + Ganti nama + + + + Add steps + Tambah langkah + + + + Remove steps + Hapus langkah + + + + Clone Steps + Klon langkah + + + + PeakController + + + Peak Controller + + + + + Peak Controller Bug + + + + + Due to a bug in older version of LMMS, the peak controllers may not be connect properly. Please ensure that peak controllers are connected properly and re-save this file. Sorry for any inconvenience caused. + Karena bug pada versi lama LMMS, pengendali puncak mungkin tidak terhubung dengan benar. Pastikan pengendali puncak terhubung dengan benar dan simpan kembali berkas ini. Maaf atas ketidaknyamanan yang terjadi. + + + + PeakControllerDialog + + + PEAK + + + + + LFO Controller + Kontroler LFO + + + + PeakControllerEffectControlDialog + + + BASE + DASAR + + + + Base amount: + Jumlah dasar: + + + + AMNT + JMLH + + + + Modulation amount: + Jumlah modulasi: + + + + MULT + + + + + Amount Multiplicator: + + + + + ATCK + + + + + Attack: + Attack: + + + + DCAY + + + + + Release: + Release: + + + + TRSH + + + + + Treshold: + + + + + PeakControllerEffectControls + + + Base value + Nilai dasar + + + + Modulation amount + + + + + Attack + Attack + + + + Release + Release + + + + Treshold + + + + + Mute output + + + + + Abs Value + Nilai Abs + + + + Amount Multiplicator + + + + + PianoRoll + + + Note Velocity + + + + + Note Panning + Keseimbangan Not + + + + Mark/unmark current semitone + + + + + Mark/unmark all corresponding octave semitones + Tandai / hapus tanda semua semitone oktaf yang sesuai + + + + Mark current scale + + + + + Mark current chord + + + + + Unmark all + Hapus tanda semua + + + + Select all notes on this key + Pilih semua not pada kunci ini + + + + Note lock + + + + + Last note + + + + + No scale + + + + + No chord + + + + + Velocity: %1% + Kecepatan: %1% + + + + Panning: %1% left + Menyeimbangkan: %1% kiri + + + + Panning: %1% right + Menyeimbangkan: %1% kanan + + + + Panning: center + Menyeimbangkan: tengah + + + + Please open a pattern by double-clicking on it! + Buka pola dengan mengklik dua kali di atasnya! + + + + + Please enter a new value between %1 and %2: + Silakan masukan nilai baru antara %1 dan %2: + + + + PianoRollWindow + + + Play/pause current pattern (Space) + Putar/jeda pola saat ini (Spasi) + + + + Record notes from MIDI-device/channel-piano + Rekam not dari perangkat-MIDI/channel-piano + + + + Record notes from MIDI-device/channel-piano while playing song or BB track + Rekam not dari perangkat-MIDI/channel-piano sambil memutar lagu atau trek BB + + + + Stop playing of current pattern (Space) + Berhenti memutar pola sekarang (Spasi) + + + + Click here to play the current pattern. This is useful while editing it. The pattern is automatically looped when its end is reached. + Klik di sini untuk memainkan pola saat ini. Ini berguna saat mengeditnya. Pola diulang secara otomatis saat ujungnya tercapai. + + + + Click here to record notes from a MIDI-device or the virtual test-piano of the according channel-window to the current pattern. When recording all notes you play will be written to this pattern and you can play and edit them afterwards. + Klik di sini untuk merekam not dari perangkat MIDI atau virtual test-piano dari jendela saluran yang sesuai dengan pola saat ini. Saat merekam semua not yang Anda mainkan akan dituliskan ke pola ini dan Anda dapat memutar dan mengubahnya setelahnya. + + + + Click here to record notes from a MIDI-device or the virtual test-piano of the according channel-window to the current pattern. When recording all notes you play will be written to this pattern and you will hear the song or BB track in the background. + Klik di sini untuk merekam not dari perangkat MIDI atau virtual test-piano dari jendela saluran yang sesuai dengan pola saat ini. Saat merekam semua not yang Anda mainkan akan dituliskan ke pola ini dan Anda akan mendengar lagu atau trek BB di latar belakang. + + + + Click here to stop playback of current pattern. + Klik disini untuk berhenti memutar pola saat ini. + + + + Edit actions + Ubah aksi + + + + Draw mode (Shift+D) + mode Menggambar (Shift+D) + + + + Erase mode (Shift+E) + Mode penghapus (Shift+E) + + + + Select mode (Shift+S) + Mode pilih (Shift+S) + + + + Click here and draw mode will be activated. In this mode you can add, resize and move notes. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. In this mode, hold %1 to temporarily go into select mode. + Klik di sini dan mode gambar akan diaktifkan. Dalam mode ini Anda bisa menambahkan, mengubah ukuran dan memindahkan not. Ini adalah mode default yang sering digunakan. Anda juga dapat menekan 'Shift+D' pada keyboard untuk mengaktifkan mode ini. Tekan %1 untuk masuk ke mode pilih secara sementara. + + + + Click here and erase mode will be activated. In this mode you can erase notes. You can also press 'Shift+E' on your keyboard to activate this mode. + + + + + Click here and select mode will be activated. In this mode you can select notes. Alternatively, you can hold %1 in draw mode to temporarily use select mode. + + + + + Pitch Bend mode (Shift+T) + + + + + Click here and Pitch Bend mode will be activated. In this mode you can click a note to open its automation detuning. You can utilize this to slide notes from one to another. You can also press 'Shift+T' on your keyboard to activate this mode. + + + + + Quantize + Kuantitas + + + + Copy paste controls + Kontrol salin tempel + + + + Cut selected notes (%1+X) + Potong not terpilih (%1+X) + + + + Copy selected notes (%1+C) + Salin not terpilih (%1+C) + + + + Paste notes from clipboard (%1+V) + Tempel not dari papan klip (%1+V) + + + + Click here and the selected notes will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. + + + + + Click here and the selected notes will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. + + + + + Click here and the notes from the clipboard will be pasted at the first visible measure. + Klik di sini dan catatan dari papan klip akan disisipkan pada ukuran pertama yang terlihat. + + + + Timeline controls + Kontrol linimasa + + + + Zoom and note controls + Kontrol not dan zoom + + + + This controls the magnification of an axis. It can be helpful to choose magnification for a specific task. For ordinary editing, the magnification should be fitted to your smallest notes. + + + + + The 'Q' stands for quantization, and controls the grid size notes and control points snap to. With smaller quantization values, you can draw shorter notes in Piano Roll, and more exact control points in the Automation Editor. + + + + + This lets you select the length of new notes. 'Last Note' means that LMMS will use the note length of the note you last edited + + + + + The feature is directly connected to the context-menu on the virtual keyboard, to the left in Piano Roll. After you have chosen the scale you want in this drop-down menu, you can right click on a desired key in the virtual keyboard, and then choose 'Mark current Scale'. LMMS will highlight all notes that belongs to the chosen scale, and in the key you have selected! + + + + + Let you select a chord which LMMS then can draw or highlight.You can find the most common chords in this drop-down menu. After you have selected a chord, click anywhere to place the chord, and right click on the virtual keyboard to open context menu and highlight the chord. To return to single note placement, you need to choose 'No chord' in this drop-down menu. + + + + + + Piano-Roll - %1 + Rol-Piano - %1 + + + + + Piano-Roll - no pattern + Rol-Piano - tiada pola + + + + PianoView + + + Base note + Not dasar + + + + Plugin + + + Plugin not found + Plugin tidak ditemukan + + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + Plugin "%1" tidak ditemukan atau tidak bisa dimuat! +Alasan: "%2" + + + + Error while loading plugin + Gagal ketika memuat plugin + + + + Failed to load plugin "%1"! + Gagal untuk memuat plugin "%1"! + + + + PluginBrowser + + + Instrument Plugins + Plugin Instrumen + + + + Instrument browser + Penjelajah instrumen + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + Seret instrumen ke Editor-Lagu,Editor Ketukan+Bassline atau ke trek instrumen yang ada. + + + + PluginFactory + + + Plugin not found. + Plugin tidak ditemukan. + + + + LMMS plugin %1 does not have a plugin descriptor named %2! + Plugin LMMS %1 tidak memiliki deskriptor plugin bernama %2! + + + + ProjectNotes + + + Project Notes + Catatan Proyek + + + + Enter project notes here + + + + + Edit Actions + Ubah Aksi + + + + &Undo + &Undo + + + + %1+Z + %1+Z + + + + &Redo + &Redo + + + + %1+Y + %1+Y + + + + &Copy + &Salin + + + + %1+C + %1+C + + + + Cu&t + Po&tong + + + + %1+X + %1+X + + + + &Paste + &Tempel + + + + %1+V + %1+V + + + + Format Actions + Aksi Format + + + + &Bold + &Tebal + + + + %1+B + %1+B + + + + &Italic + &Miring + + + + %1+I + %1+I + + + + &Underline + &Garis bawah + + + + %1+U + %1+U + + + + &Left + &Kiri + + + + %1+L + %1+L + + + + C&enter + Te&ngah + + + + %1+E + %1+E + + + + &Right + &Kanan + + + + %1+R + %1+R + + + + &Justify + &Ratakan + + + + %1+J + %1+J + + + + &Color... + &Warna + + + + ProjectRenderer + + + WAV-File (*.wav) + Berkas-WAV (*.wav) + + + + Compressed OGG-File (*.ogg) + Berkas-OGG terkompresi (*.ogg) + + + + Compressed MP3-File (*.mp3) + + + + + QWidget + + + + + Name: + Nama: + + + + + Maker: + Pembuat: + + + + + Copyright: + Hak cipta: + + + + + Requires Real Time: + Membutuhkan Real Time: + + + + + + + + + Yes + Ya + + + + + + + + + No + Tidak + + + + + Real Time Capable: + Kemampuan Real Time: + + + + + In Place Broken: + + + + + + Channels In: + Saluran Masukan: + + + + + Channels Out: + Saluran Keluaran: + + + + File: %1 + Berkas: %1 + + + + File: + Berkas: + + + + RenameDialog + + + Rename... + Ganti nama... + + + + ReverbSCControlDialog + + + Input + Masukan + + + + Input Gain: + Gain Masuk: + + + + Size + Ukuran + + + + Size: + Ukuran: + + + + Color + Warna + + + + Color: + Warna: + + + + Output + Keluaran + + + + Output Gain: + Gain Keluaran: + + + + ReverbSCControls + + + Input Gain + Gain Masukan + + + + Size + Ukuran + + + + Color + Warna + + + + Output Gain + Gain Keluaran + + + + SampleBuffer + + + Fail to open file + Gagal untuk membuka berkas + + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + Berkas suara dibatasi ukuran hingga %1 MB dan waktu pemutaran %2 menit + + + + Open audio file + Buka berkas suara + + + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + Semua Berkas-Suara (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Berkas-Wave (*.wav) + + + + OGG-Files (*.ogg) + Berkas-OGG (*.ogg) + + + + DrumSynth-Files (*.ds) + Berkas-DrumSynth (*.ds) + + + + FLAC-Files (*.flac) + Berkas-FLAC (*.flac) + + + + SPEEX-Files (*.spx) + Berkas-SPEEX (*.spx) + + + + VOC-Files (*.voc) + Berkas-VOC (*.voc) + + + + AIFF-Files (*.aif *.aiff) + Berkas-AIFF (*.aif *.aiff) + + + + AU-Files (*.au) + Berkas-AU (*.au) + + + + RAW-Files (*.raw) + Berkas-RAW (*.raw) + + + + SampleTCOView + + + double-click to select sample + Klik dua kali untuk memilih sampel + + + + Delete (middle mousebutton) + Hapus (tombol tengah mouse) + + + + Cut + Potong + + + + Copy + Salin + + + + Paste + Tempel + + + + Mute/unmute (<%1> + middle click) + Bisukan/suarakan (<%1> + middle click) + + + + SampleTrack + + + Volume + Volume + + + + + Panning + Keseimbangan + + + + + Sample track + Trek sampel + + + + SampleTrackView + + + Track volume + Volume trek + + + + Channel volume: + Volume channel: + + + + VOL + VOL + + + + Panning + Keseimbangan + + + + Panning: + Keseimbangan: + + + + PAN + SEIMBANG + + + + SetupDialog + + + Setup LMMS + Atur LMMS + + + + + General settings + Pengaturan umum + + + + BUFFER SIZE + UKURAN BUFFER + + + + + Reset to default-value + Setel ulang ke nilai default + + + + MISC + + + + + Enable tooltips + Aktifkan tooltips + + + + Show restart warning after changing settings + Tampilkan peringatan mulai ulang setelah mengganti pengaturan + + + + Display volume as dBFS + Tampilkan volume sebagai dBFS + + + + Compress project files per default + Kompres berkas proyek per default + + + + One instrument track window mode + Mode jendela satu trek instrumen + + + + HQ-mode for output audio-device + mode-HQ untuk keluaran perangkat-audio + + + + Compact track buttons + Tombol trek yang kompak + + + + Sync VST plugins to host playback + Selaraskan plugin VST ke pemutaran host + + + + Enable note labels in piano roll + Aktifkan label not di rol piano + + + + Enable waveform display by default + Aktifkan tampilan gelombang grafik sebagai default + + + + Keep effects running even without input + Biarkan efek berjalan walaupun tanpa masukan + + + + Create backup file when saving a project + Buat berkas backup ketika menyimpan proyek + + + + Reopen last project on start + Buka kembali proyek terakhir saat memulai + + + + Use built-in NaN handler + + + + + PLUGIN EMBEDDING + + + + + No embedding + Tidak disematkan + + + + Embed using Qt API + Disematkan menggunakan API Qt + + + + Embed using native Win32 API + Disematkan menggunakan API Win32 asli + + + + Embed using XEmbed protocol + Disematkan menggunakan protokol XEmbed + + + + LANGUAGE + BAHASA + + + + + Paths + + + + + Directories + Direktori + + + + LMMS working directory + Direktori kerja LMMS + + + + Themes directory + Direktori tema + + + + Background artwork + Latar belakang karya seni + + + + VST-plugin directory + Direktori VST-plugin + + + + GIG directory + Direktori GIG + + + + SF2 directory + Direktori SF2 + + + + LADSPA plugin directories + Direktori plugin LADSPA + + + + STK rawwave directory + Direktori STK rawwave + + + + Default Soundfont File + Berkas Soundfont default + + + + + Performance settings + Pengaturan performa + + + + Auto save + Simpan otomatis + + + + Enable auto-save + Aktifkan simpan otomatis + + + + Allow auto-save while playing + Izinkan simpan-otomatis ketika bermain + + + + UI effects vs. performance + Efek UI vs. performa + + + + Smooth scroll in Song Editor + Gulung halus di Editor Lagu + + + + Show playback cursor in AudioFileProcessor + + + + + + Audio settings + Pengaturan suara + + + + AUDIO INTERFACE + INTERFACE SUARA + + + + + MIDI settings + Pengaturan MIDI + + + + MIDI INTERFACE + INTERFACE MIDI + + + + OK + OK + + + + Cancel + Batal + + + + Restart LMMS + Mulai Ulang LMMS + + + + Please note that most changes won't take effect until you restart LMMS! + Harap dicatat bahwa sebagian besar perubahan tidak akan berpengaruh sampai Anda memulai-ulang LMMS! + + + + Frames: %1 +Latency: %2 ms + Bingkai: %1 +Latensi: %2 md + + + + Here you can setup the internal buffer-size used by LMMS. Smaller values result in a lower latency but also may cause unusable sound or bad performance, especially on older computers or systems with a non-realtime kernel. + + + + + Choose LMMS working directory + Pilih direktori kerja LMMS + + + + Choose your GIG directory + Pilih direktor GIG anda + + + + Choose your SF2 directory + Pilih direktor SF2 anda + + + + Choose your VST-plugin directory + Pilih direktori VST-Plugin Anda + + + + Choose artwork-theme directory + Pilih direktori tema karya seni + + + + Choose LADSPA plugin directory + Pilih direktori plugin LADSPA + + + + Choose STK rawwave directory + Pilih direktori STK rawwave + + + + Choose default SoundFont + Pilih Soundfont default + + + + Choose background artwork + Pilih karya seni latar belakang + + + + minutes + menit + + + + minute + menit + + + + Disabled + Dinonaktifkan + + + + Auto-save interval: %1 + Waktu jeda simpan otomatis: %1 + + + + Set the time between automatic backup to %1. +Remember to also save your project manually. You can choose to disable saving while playing, something some older systems find difficult. + Tetapkan waktu antara pencadangan otomatis ke% 1. +Ingat juga untuk menyimpan proyek Anda secara manual. Anda dapat memilih untuk menonaktifkan penyimpanan saat bermain, beberapa sistem yang lebih tua sulit ditemukan. + + + + Here you can select your preferred audio-interface. Depending on the configuration of your system during compilation time you can choose between ALSA, JACK, OSS and more. Below you see a box which offers controls to setup the selected audio-interface. + + + + + Here you can select your preferred MIDI-interface. Depending on the configuration of your system during compilation time you can choose between ALSA, OSS and more. Below you see a box which offers controls to setup the selected MIDI-interface. + + + + + Song + + + Tempo + Tempo + + + + Master volume + Volume master + + + + Master pitch + Master pitch + + + + LMMS Error report + Laporan kesalahan LMMS + + + + Project saved + Proyek disimpan + + + + The project %1 is now saved. + Proyek %1 telah disimpan. + + + + Project NOT saved. + Proyek TIDAK disimpan. + + + + The project %1 was not saved! + Proyek %1 tidak disimpan! + + + + Import file + Impor berkas + + + + MIDI sequences + Rangkaian MIDI + + + + Hydrogen projects + Proyek hidrogen + + + + All file types + Semua tipe berkas + + + + + Empty project + Proyek kosong + + + + + This project is empty so exporting makes no sense. Please put some items into Song Editor first! + Proyek ini kosong jadi mengekspor itu tidak masuk akal. Pertama silakan masukan beberapa item ke Editor Lagu! + + + + Select directory for writing exported tracks... + Pilih direktori untuk menulis trek yang diekspor... + + + + + untitled + tak berjudul + + + + + Select file for project-export... + Pilih berkas untuk ekspor-proyek... + + + + Save project + Simpan proyek + + + + MIDI File (*.mid) + Berkas MIDI (*.mid) + + + + The following errors occured while loading: + Kesalahan muncul saat memuat: + + + + SongEditor + + + Could not open file + Tidak bisa membuka berkas + + + + Could not open file %1. You probably have no permissions to read this file. + Please make sure to have at least read permissions to the file and try again. + Tidak bisa membuka berkas %1. Anda mungkin tidak memiliki izin untuk membaca berkas ini. +Setidaknya pastikan Anda memiliki izini baca kepada berkas tersebut lalu coba lagi. + + + + Could not write file + Tidak bisa menulis berkas + + + + Could not open %1 for writing. You probably are not permitted to write to this file. Please make sure you have write-access to the file and try again. + Tidak bisa membuka %1 untuk menulis. Anda mungkin tidak diperbolehkan untuk menulis ke berkas ini. Pastikan anda memiliki akses baca kepada berkas tersebut lalu coba lagi. + + + + Error in file + Kesalahan dalam berkas + + + + The file %1 seems to contain errors and therefore can't be loaded. + Berkas %1 sepertinya menganduh kesalahan dan oleh karena itu tidak bisa dimuat. + + + + Version difference + Perbedaan Versi + + + + This %1 was created with LMMS %2. + %1 ini telah dibuat oleh LMMS %2. + + + + template + template + + + + project + proyek + + + + Tempo + Tempo + + + + TEMPO/BPM + TEMPO/KPM + + + + tempo of song + tempo lagu + + + + The tempo of a song is specified in beats per minute (BPM). If you want to change the tempo of your song, change this value. Every measure has four beats, so the tempo in BPM specifies, how many measures / 4 should be played within a minute (or how many measures should be played within four minutes). + + + + + High quality mode + Mode kualitas tinggi + + + + + Master volume + Volume master + + + + master volume + volume master + + + + + Master pitch + Master pitch + + + + master pitch + master pitch + + + + Value: %1% + Nilai: %1% + + + + Value: %1 semitones + Nilai: %1 semitone + + + + SongEditorWindow + + + Song-Editor + Editor-Lagu + + + + Play song (Space) + Putar lagu (Spasi) + + + + Record samples from Audio-device + Rekam sampel dari perangkat-Audio + + + + Record samples from Audio-device while playing song or BB track + Rekam sampel dari perangkat-Audio saat memutar lagu atau trek BB + + + + Stop song (Space) + Hentikan lagu (Spasi) + + + + Click here, if you want to play your whole song. Playing will be started at the song-position-marker (green). You can also move it while playing. + Klik disini jika anda ingin memutar seluruh lagu Anda. Pemutaran akan dimulai pada tanda-posisi-lagu (hijau). Anda juga bisa memindahkannya saat memutar. + + + + Click here, if you want to stop playing of your song. The song-position-marker will be set to the start of your song. + + + + + Track actions + Aksi trek + + + + Add beat/bassline + Tambah ketukan/bassline + + + + Add sample-track + Tambah Trek-sampel + + + + Add automation-track + Tambah trek-otomasi + + + + Edit actions + Ubah aksi + + + + Draw mode + Mode gambar + + + + Edit mode (select and move) + Mode Edit (pilih dan pindah) + + + + Timeline controls + Kontrol timeline + + + + Zoom controls + Kontrol Zum + + + + SpectrumAnalyzerControlDialog + + + Linear spectrum + + + + + Linear Y axis + + + + + SpectrumAnalyzerControls + + + Linear spectrum + + + + + Linear Y axis + + + + + Channel mode + Mode saluran + + + + SubWindow + + + Close + Tutup + + + + Maximize + Maksimalkan + + + + Restore + Kembalikan + + + + TabWidget + + + + Settings for %1 + Pengaturan untuk %1 + + + + TempoSyncKnob + + + + Tempo Sync + Selaraskan Tempo + + + + No Sync + + + + + Eight beats + Delapan ketukan + + + + Whole note + Seluruh not + + + + Half note + Setengah not + + + + Quarter note + Seperempat not + + + + 8th note + not 8 + + + + 16th note + not 16 + + + + 32nd note + not 32 + + + + Custom... + Kustom... + + + + Custom + Kustom + + + + Synced to Eight Beats + + + + + Synced to Whole Note + + + + + Synced to Half Note + + + + + Synced to Quarter Note + + + + + Synced to 8th Note + + + + + Synced to 16th Note + + + + + Synced to 32nd Note + + + + + TimeDisplayWidget + + + click to change time units + klik untuk mengganti unit waktu + + + + MIN + MIN + + + + SEC + DTK + + + + MSEC + MDTK + + + + BAR + BAR + + + + BEAT + KETUKAN + + + + TICK + TIK + + + + TimeLineWidget + + + Enable/disable auto-scrolling + Aktifkan/nonaktifkan skrol-otomatis + + + + Enable/disable loop-points + Aktifkan / nonaktifkan titik-pengulangan + + + + After stopping go back to begin + Setelah berhenti kembali ke awal + + + + After stopping go back to position at which playing was started + Setelah berhenti kembali ke posisi dimana pemutaran dimulai + + + + After stopping keep position + Jaga posisi setelah berhenti + + + + + Hint + Petunjuk + + + + Press <%1> to disable magnetic loop points. + Tekan <%1> untuk menonaktifkan titik pengulangan magnetik. + + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + Tahan <Shift> untuk memindahkan titik pengulangan awal; Tekan <%1> untuk menonaktifkan titik pengulangan magnetik. + + + + Track + + + Mute + Bisu + + + + Solo + Solo + + + + TrackContainer + + + Couldn't import file + Tidak bisa mengimpor berkas + + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + Tidak bisa mencari filter untuk mengimpor berkas %1. +Anda seharusnya mengubah berkas ini menjadi format yang didukung oleh LMMS menggunakan perangkat lunak lain. + + + + Couldn't open file + Tidak bisa membuka berkas + + + + Couldn't open file %1 for reading. +Please make sure you have read-permission to the file and the directory containing the file and try again! + Tidak bisa membuka berkas %1 untuk dibaca. +Pastikan anda memiliki izin baca untuk berkas ini dan direktori yang mengandung berkas ini dan coba lagi! + + + + Loading project... + Memuat proyek... + + + + + Cancel + Batal + + + + + Please wait... + Mohon tunggu... + + + + Loading cancelled + + + + + Project loading was cancelled. + + + + + Loading Track %1 (%2/Total %3) + Memuat Trek %1 (%2/Total %3) + + + + Importing MIDI-file... + Mengimpor berkas-MIDI... + + + + TrackContentObject + + + Mute + Bisu + + + + TrackContentObjectView + + + Current position + Posisi saat ini + + + + + Hint + Petunjuk + + + + Press <%1> and drag to make a copy. + Tekan <%1> dan seret untuk membuat salinan. + + + + Current length + Panjang saat ini + + + + Press <%1> for free resizing. + Tekan <%1> untuk merubah ukuran secara bebas. + + + + + %1:%2 (%3:%4 to %5:%6) + %1:%2 (%3:%4 to %5:%6) + + + + Delete (middle mousebutton) + Hapus (tombol tengah mouse) + + + + Cut + Potong + + + + Copy + Salin + + + + Paste + Tempel + + + + Mute/unmute (<%1> + middle click) + Bisukan/suarakan (<%1> + middle click) + + + + TrackOperationsWidget + + + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. + + + + + Actions for this track + Aksi untuk trek ini + + + + Mute + Bisu + + + + + Solo + Solo + + + + Mute this track + Bisukan trek ini + + + + Clone this track + Klon trek ini + + + + Remove this track + Hapus trek ini + + + + Clear this track + Bersihkan trek ini + + + + FX %1: %2 + FX %1: %2 + + + + Assign to new FX Channel + Tetapkan ke Saluran FX baru + + + + Turn all recording on + Hidupkan semua rekaman + + + + Turn all recording off + Matikan semua rekaman + + + + TripleOscillatorView + + + Use phase modulation for modulating oscillator 1 with oscillator 2 + + + + + Use amplitude modulation for modulating oscillator 1 with oscillator 2 + + + + + Mix output of oscillator 1 & 2 + Campurkan keluaran dari osilator 1 & 2 + + + + Synchronize oscillator 1 with oscillator 2 + + + + + Use frequency modulation for modulating oscillator 1 with oscillator 2 + + + + + Use phase modulation for modulating oscillator 2 with oscillator 3 + + + + + Use amplitude modulation for modulating oscillator 2 with oscillator 3 + + + + + Mix output of oscillator 2 & 3 + Campurkan keluaran dari osilator 2 & 3 + + + + Synchronize oscillator 2 with oscillator 3 + Selaraskan osilator 2 dengan osilator 3 + + + + Use frequency modulation for modulating oscillator 2 with oscillator 3 + + + + + Osc %1 volume: + Volume Osc %1: + + + + With this knob you can set the volume of oscillator %1. When setting a value of 0 the oscillator is turned off. Otherwise you can hear the oscillator as loud as you set it here. + + + + + Osc %1 panning: + Keseimbangan Osc %1: + + + + With this knob you can set the panning of the oscillator %1. A value of -100 means 100% left and a value of 100 moves oscillator-output right. + + + + + Osc %1 coarse detuning: + + + + + semitones + semitone + + + + With this knob you can set the coarse detuning of oscillator %1. You can detune the oscillator 24 semitones (2 octaves) up and down. This is useful for creating sounds with a chord. + + + + + Osc %1 fine detuning left: + + + + + + cents + sen + + + + With this knob you can set the fine detuning of oscillator %1 for the left channel. The fine-detuning is ranged between -100 cents and +100 cents. This is useful for creating "fat" sounds. + + + + + Osc %1 fine detuning right: + + + + + With this knob you can set the fine detuning of oscillator %1 for the right channel. The fine-detuning is ranged between -100 cents and +100 cents. This is useful for creating "fat" sounds. + + + + + Osc %1 phase-offset: + + + + + + degrees + derajat + + + + With this knob you can set the phase-offset of oscillator %1. That means you can move the point within an oscillation where the oscillator begins to oscillate. For example if you have a sine-wave and have a phase-offset of 180 degrees the wave will first go down. It's the same with a square-wave. + + + + + Osc %1 stereo phase-detuning: + + + + + With this knob you can set the stereo phase-detuning of oscillator %1. The stereo phase-detuning specifies the size of the difference between the phase-offset of left and right channel. This is very good for creating wide stereo sounds. + + + + + Use a sine-wave for current oscillator. + Gunakan gelombang sinus untuk osilator saat ini. + + + + Use a triangle-wave for current oscillator. + Gunakan gelombang segitiga untuk osilator saat ini. + + + + Use a saw-wave for current oscillator. + Gunakan gelombang gergaji untuk osilator saat ini. + + + + Use a square-wave for current oscillator. + Gunakan gelombang kotak untuk osilator saat ini. + + + + Use a moog-like saw-wave for current oscillator. + + + + + Use an exponential wave for current oscillator. + + + + + Use white-noise for current oscillator. + Gunakan derau putih untuk osilator saat ini. + + + + Use a user-defined waveform for current oscillator. + Gunakan gelombang yang ditetapkan pengguna untuk osilator saat ini. + + + + VersionedSaveDialog + + + Increment version number + Tingkatkan versi nomor + + + + Decrement version number + Turunkan versi nomor + + + + already exists. Do you want to replace it? + sudah ada. Apakah anda ingin menimpanya? + + + + VestigeInstrumentView + + + Open other VST-plugin + Buka plugin-VST lain + + + + Click here, if you want to open another VST-plugin. After clicking on this button, a file-open-dialog appears and you can select your file. + Klik disini, Jika Anda ingin membuka plugin VST lain. Setelah mengklik tombol ini, dialog buka-berkas muncul dan Anda dapat memilih berkas Anda. + + + + Control VST-plugin from LMMS host + Kendalikan VST-plugin dari host LMMS + + + + Click here, if you want to control VST-plugin from host. + Klik disini, jika anda ingin mengendalikan VST-plugin dari host. + + + + Open VST-plugin preset + Buka preset VST-plugin + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Klik disini, jika anda infin membuka preset VST-plugin *.fxp, *.fxb lain. + + + + Previous (-) + Sebelumnya (-) + + + + + Click here, if you want to switch to another VST-plugin preset program. + Klik disini, jika anda ingin mengganti ke program preset plugin VST lain. + + + + Save preset + Simpan preset + + + + Click here, if you want to save current VST-plugin preset program. + Klik disini, jika anda ingin menyimpan preset program VST-plugin saat ini. + + + + Next (+) + Selanjutnya (+) + + + + Click here to select presets that are currently loaded in VST. + Klik disini untuk memilih preset yang saat ini dimuat di VST. + + + + Show/hide GUI + Tampilkan/sembunyikan GUI + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Klik di sini untuk menampilkan atau menyembunyikan tampilan antarmuka pengguna (GUI) plugin VST Anda. + + + + Turn off all notes + Matikan semua not + + + + Open VST-plugin + Buka plugin-VST + + + + DLL-files (*.dll) + Berkas-DLL (*.dll) + + + + EXE-files (*.exe) + berkas-EXE (*.exe) + + + + No VST-plugin loaded + Tidak ada VST-plugin dimuat + + + + Preset + Preset + + + + by + oleh + + + + - VST plugin control + - kontrol VST plugin + + + + VisualizationWidget + + + click to enable/disable visualization of master-output + klik disini untuk mengaktifkan/menonaktifkan visualisasi dari keluaran master + + + + Click to enable + klik untuk mengaktifkan + + + + VstEffectControlDialog + + + Show/hide + Tampilkan/sembunyikan + + + + Control VST-plugin from LMMS host + Kendalikan VST-plugin dari host LMMS + + + + Click here, if you want to control VST-plugin from host. + Klik disini, jika anda ingin mengendalikan VST-plugin dari host. + + + + Open VST-plugin preset + Buka preset VST-plugin + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Klik disini, jika anda infin membuka preset VST-plugin *.fxp, *.fxb lain. + + + + Previous (-) + Sebelumnya (-) + + + + + Click here, if you want to switch to another VST-plugin preset program. + Klik disini, jika anda ingin mengganti ke program preset plugin VST lain. + + + + Next (+) + Selanjutnya (+) + + + + Click here to select presets that are currently loaded in VST. + Klik disini untuk memilih preset yang saat ini dimuat di VST. + + + + Save preset + Simpan preset + + + + Click here, if you want to save current VST-plugin preset program. + Klik disini, jika anda ingin menyimpan preset program VST-plugin saat ini. + + + + + Effect by: + Efek oleh: + + + + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> + + + + VstPlugin + + + + The VST plugin %1 could not be loaded. + VST plugin %1 tidak dapat dimuat. + + + + Open Preset + Buka Preset + + + + + Vst Plugin Preset (*.fxp *.fxb) + Preset Vst Plugin (*.fxp *.fxb) + + + + : default + : default + + + + " + " + + + + ' + ' + + + + Save Preset + Simpan Preset + + + + .fxp + .fxp + + + + .FXP + .FXP + + + + .FXB + .FXB + + + + .fxb + .fxb + + + + Loading plugin + Memuat plugin + + + + Please wait while loading VST plugin... + Mohon tunggu, sedang memuat VST plugin... + + + + WatsynInstrument + + + Volume A1 + Volume A1 + + + + Volume A2 + Volume A2 + + + + Volume B1 + Volume B1 + + + + Volume B2 + Volume B2 + + + + Panning A1 + Keseimbangan A1 + + + + Panning A2 + Keseimbangan A2 + + + + Panning B1 + Keseimbangan B1 + + + + Panning B2 + Keseimbangan B2 + + + + Freq. multiplier A1 + + + + + Freq. multiplier A2 + + + + + Freq. multiplier B1 + + + + + Freq. multiplier B2 + + + + + Left detune A1 + + + + + Left detune A2 + + + + + Left detune B1 + + + + + Left detune B2 + + + + + Right detune A1 + + + + + Right detune A2 + Detune A2 kanan + + + + Right detune B1 + Detune B1 Kanan + + + + Right detune B2 + Detune B2 kanan + + + + A-B Mix + A-B Mix + + + + A-B Mix envelope amount + + + + + A-B Mix envelope attack + + + + + A-B Mix envelope hold + + + + + A-B Mix envelope decay + + + + + A1-B2 Crosstalk + + + + + A2-A1 modulation + Modulasi A2-A1 + + + + B2-B1 modulation + Modulasi B2-B1 + + + + Selected graph + Grafik yang dipilih + + + + WatsynView + + + + + + Volume + Volume + + + + + + + + Panning + Keseimbangan + + + + + + + Freq. multiplier + + + + + + + + Left detune + + + + + + + + + + + + cents + sen + + + + + + + Right detune + + + + + A-B Mix + A-B Mix + + + + Mix envelope amount + + + + + Mix envelope attack + + + + + Mix envelope hold + + + + + Mix envelope decay + + + + + Crosstalk + + + + + Select oscillator A1 + Pilih osilator A1 + + + + Select oscillator A2 + Pilih osilator A2 + + + + Select oscillator B1 + Pilih osilator B1 + + + + Select oscillator B2 + Pilih osilator B2 + + + + Mix output of A2 to A1 + Campurkan keluaran dari A2 ke A1 + + + + Modulate amplitude of A1 with output of A2 + + + + + Ring-modulate A1 and A2 + Cincin modulasi A1 dan A2 + + + + Modulate phase of A1 with output of A2 + + + + + Mix output of B2 to B1 + Gabung keluaran dari B2 ke B1 + + + + Modulate amplitude of B1 with output of B2 + Modulasikan amplitudo dari B1 dengan keluaran B2 + + + + Ring-modulate B1 and B2 + Cincin modulasi B1 dan B2 + + + + Modulate phase of B1 with output of B2 + + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + Gambar bentuk gelombang kamu sendiri dengan menyeret tetikus kamu di grafik ini. + + + + Load waveform + Muat gelombang grafik + + + + Click to load a waveform from a sample file + Klik untuk memuat bentuk gelombang dari berkas sampel + + + + Phase left + + + + + Click to shift phase by -15 degrees + + + + + Phase right + + + + + Click to shift phase by +15 degrees + + + + + Normalize + Normalisasi + + + + Click to normalize + Klik untuk normalisasi + + + + Invert + Balik + + + + Click to invert + Klik untuk dibalikan + + + + Smooth + Halus + + + + Click to smooth + Klik untuk menghaluskan + + + + Sine wave + Gelombang sinus + + + + Click for sine wave + Klik untuk gelombang sinus + + + + + Triangle wave + Gelombang segitiga + + + + Click for triangle wave + Klik untuk gelombang segitiga + + + + Click for saw wave + Klik untuk gelombang gergaji + + + + Square wave + Gelombang kotak + + + + Click for square wave + Klik untuk gelombang kotak + + + + ZynAddSubFxInstrument + + + Portamento + + + + + Filter Frequency + + + + + Filter Resonance + + + + + Bandwidth + Lebar pita + + + + FM Gain + Gain FM + + + + Resonance Center Frequency + + + + + Resonance Bandwidth + + + + + Forward MIDI Control Change Events + + + + + ZynAddSubFxView + + + Portamento: + Portamento: + + + + PORT + PORT + + + + Filter Frequency: + Frekuensi Filter: + + + + FREQ + FREK + + + + Filter Resonance: + Resonansi Filter: + + + + RES + RES + + + + Bandwidth: + Lebar pita: + + + + BW + LP + + + + FM Gain: + FM Gain: + + + + FM GAIN + FM GAIN + + + + Resonance center frequency: + Frekuensi resonansi tengah: + + + + RES CF + + + + + Resonance bandwidth: + + + + + RES BW + + + + + Forward MIDI Control Changes + + + + + Show GUI + Tampilkan GUI + + + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Klik disini untuk menampilkan atau menyembunyikan antarmuka pengguna grafis (GUI) dari ZynAddSubFX. + + + + audioFileProcessor + + + Amplify + + + + + Start of sample + Awal dari sampel + + + + End of sample + Akhir dar sampel + + + + Loopback point + Titik loopback + + + + Reverse sample + Balikan sampel + + + + Loop mode + Mode pengulangan + + + + Stutter + + + + + Interpolation mode + + + + + None + Tidak ada + + + + Linear + + + + + Sinc + + + + + Sample not found: %1 + Sampel tidak ditemukan: %1 + + + + bitInvader + + + Samplelength + Panjangsampel + + + + bitInvaderView + + + Sample Length + Panjang Sampel + + + + Draw your own waveform here by dragging your mouse on this graph. + Gambar bentuk gelombang kamu sendiri dengan menyeret tetikus kamu di grafik ini. + + + + Sine wave + Gelombang sinus + + + + Click for a sine-wave. + + + + + Triangle wave + Gelombang segitiga + + + + Click here for a triangle-wave. + Klik disini untuk gelombang-segitiga. + + + + Saw wave + Gelombang gergaji + + + + Click here for a saw-wave. + Klik disini untuk gelombang gergaji. + + + + Square wave + Gelombang kotak + + + + Click here for a square-wave. + Klik disini untuk gelombang-kotak. + + + + White noise wave + Gelombang riuh + + + + Click here for white-noise. + Klik disini untuk kebisingan-putih. + + + + User defined wave + Gelombang yang didefinisikan pengguna + + + + Click here for a user-defined shape. + + + + + Smooth + Halus + + + + Click here to smooth waveform. + Klik disini untuk menghaluskan grafik gelombang. + + + + Interpolation + Interpolasi + + + + Normalize + Normalisasi + + + + dynProcControlDialog + + + INPUT + MASUKAN + + + + Input gain: + Gain masukan: + + + + OUTPUT + KELUARAN + + + + Output gain: + Gait keluaran: + + + + ATTACK + + + + + Peak attack time: + + + + + RELEASE + + + + + Peak release time: + + + + + Reset waveform + Reset grafik gelombang + + + + Click here to reset the wavegraph back to default + Klik disini untuk mereset gelombang grafik ke default + + + + Smooth waveform + Gelombang halus + + + + Click here to apply smoothing to wavegraph + Klik disini untuk menerapkan kehalusan ke grafik gelombang + + + + Increase wavegraph amplitude by 1dB + + + + + Click here to increase wavegraph amplitude by 1dB + Klik disini untuk meningkatkan amplitudo Grafik gelombang dengan 1dB + + + + Decrease wavegraph amplitude by 1dB + + + + + Click here to decrease wavegraph amplitude by 1dB + Klik disini untuk mengurangi amplitudo wavegraf dengan 1dB + + + + Stereomode Maximum + + + + + Process based on the maximum of both stereo channels + + + + + Stereomode Average + + + + + Process based on the average of both stereo channels + + + + + Stereomode Unlinked + + + + + Process each stereo channel independently + + + + + dynProcControls + + + Input gain + Gain masukan + + + + Output gain + Gain keluaran + + + + Attack time + + + + + Release time + + + + + Stereo mode + Mode stereo + + + + fxLineLcdSpinBox + + + Assign to: + + + + + New FX Channel + Saluran FX Baru + + + + graphModel + + + Graph + Grafik + + + + kickerInstrument + + + Start frequency + Frekuensi mulai + + + + End frequency + Frekuensi akhir + + + + Length + Panjang + + + + Distortion Start + Distorsi Mulai + + + + Distortion End + Distorsi Akhir + + + + Gain + Gain + + + + Envelope Slope + + + + + Noise + Derau + + + + Click + Klik + + + + Frequency Slope + + + + + Start from note + Mulai dari not + + + + End to note + Berakhir ke not + + + + kickerInstrumentView + + + Start frequency: + Frekuensi mulai: + + + + End frequency: + Frekuensi akhir: + + + + Frequency Slope: + + + + + Gain: + Gain: + + + + Envelope Length: + + + + + Envelope Slope: + + + + + Click: + Klik: + + + + Noise: + Derau: + + + + Distortion Start: + Distorsi Mulai: + + + + Distortion End: + Distorsi Akhir: + + + + ladspaBrowserView + + + + Available Effects + Efek tersedia + + + + + Unavailable Effects + Efek tak tersedia + + + + + Instruments + Instrumen + + + + + Analysis Tools + Alat Analisis + + + + + Don't know + Tidak tahu + + + + This dialog displays information on all of the LADSPA plugins LMMS was able to locate. The plugins are divided into five categories based upon an interpretation of the port types and names. + +Available Effects are those that can be used by LMMS. In order for LMMS to be able to use an effect, it must, first and foremost, be an effect, which is to say, it has to have both input channels and output channels. LMMS identifies an input channel as an audio rate port containing 'in' in the name. Output channels are identified by the letters 'out'. Furthermore, the effect must have the same number of inputs and outputs and be real time capable. + +Unavailable Effects are those that were identified as effects, but either didn't have the same number of input and output channels or weren't real time capable. + +Instruments are plugins for which only output channels were identified. + +Analysis Tools are plugins for which only input channels were identified. + +Don't Knows are plugins for which no input or output channels were identified. + +Double clicking any of the plugins will bring up information on the ports. + + + + + Type: + Tipe: + + + + ladspaDescription + + + Plugins + Plugin + + + + Description + Deskripsi + + + + ladspaPortDialog + + + Ports + + + + + Name + Nama + + + + Rate + Nilai + + + + Direction + Arah + + + + Type + Tipe + + + + Min < Default < Max + Min < Default < Maks + + + + Logarithmic + Logaritmik + + + + SR Dependent + + + + + Audio + Audio + + + + Control + Kontrol + + + + Input + Masukan + + + + Output + Keluaran + + + + Toggled + + + + + Integer + Integer + + + + Float + Float + + + + + Yes + Ya + + + + lb302Synth + + + VCF Cutoff Frequency + + + + + VCF Resonance + Resonansi VCF + + + + VCF Envelope Mod + + + + + VCF Envelope Decay + + + + + Distortion + Distorsi + + + + Waveform + Grafik gelombang + + + + Slide Decay + + + + + Slide + + + + + Accent + Aksen + + + + Dead + Mati + + + + 24dB/oct Filter + Filter 24dB/oct + + + + lb302SynthView + + + Cutoff Freq: + Frek Cutoff: + + + + Resonance: + Resonansi: + + + + Env Mod: + Env Mod: + + + + Decay: + Decay: + + + + 303-es-que, 24dB/octave, 3 pole filter + + + + + Slide Decay: + + + + + DIST: + + + + + Saw wave + Gelombang gergaji + + + + Click here for a saw-wave. + Klik disini untuk gelombang gergaji. + + + + Triangle wave + Gelombang segitiga + + + + Click here for a triangle-wave. + Klik disini untuk gelombang-segitiga. + + + + Square wave + Gelombang kotak + + + + Click here for a square-wave. + Klik disini untuk gelombang-kotak. + + + + Rounded square wave + Gelombang persegi bulat + + + + Click here for a square-wave with a rounded end. + + + + + Moog wave + + + + + Click here for a moog-like wave. + + + + + Sine wave + Gelombang sinus + + + + Click for a sine-wave. + + + + + + White noise wave + Gelombang riuh + + + + Click here for an exponential wave. + Klik disini untuk gelombang eksponensial. + + + + Click here for white-noise. + Klik disini untuk kebisingan-putih. + + + + Bandlimited saw wave + + + + + Click here for bandlimited saw wave. + + + + + Bandlimited square wave + + + + + Click here for bandlimited square wave. + + + + + Bandlimited triangle wave + + + + + Click here for bandlimited triangle wave. + + + + + Bandlimited moog saw wave + + + + + Click here for bandlimited moog saw wave. + + + + + malletsInstrument + + + Hardness + Kekerasan + + + + Position + Posisi + + + + Vibrato Gain + + + + + Vibrato Freq + + + + + Stick Mix + + + + + Modulator + Modulator + + + + Crossfade + + + + + LFO Speed + Kecepatan LFO + + + + LFO Depth + Kedalaman LFO + + + + ADSR + ADSR + + + + Pressure + Tekanan + + + + Motion + + + + + Speed + Kecepatan + + + + Bowed + + + + + Spread + + + + + Marimba + Marimba + + + + Vibraphone + Vibraphone + + + + Agogo + + + + + Wood1 + + + + + Reso + Reso + + + + Wood2 + + + + + Beats + Ketukan + + + + Two Fixed + + + + + Clump + + + + + Tubular Bells + + + + + Uniform Bar + + + + + Tuned Bar + + + + + Glass + + + + + Tibetan Bowl + + + + + malletsInstrumentView + + + Instrument + Instrumen + + + + Spread + + + + + Spread: + + + + + Missing files + Berkas yang hilang + + + + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! + + + + + Hardness + Kekerasan + + + + Hardness: + + + + + Position + Posisi + + + + Position: + Posisi: + + + + Vib Gain + + + + + Vib Gain: + + + + + Vib Freq + + + + + Vib Freq: + + + + + Stick Mix + + + + + Stick Mix: + + + + + Modulator + Modulator + + + + Modulator: + + + + + Crossfade + + + + + Crossfade: + + + + + LFO Speed + Kecepatan LFO + + + + LFO Speed: + Kecepatan LFO: + + + + LFO Depth + Kedalaman LFO + + + + LFO Depth: + Kedalaman LFO: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Tekanan + + + + Pressure: + Tekanan: + + + + Speed + Kecepatan + + + + Speed: + Kecepatan: + + + + manageVSTEffectView + + + - VST parameter control + - VST kontrol parameter + + + + VST Sync + + + + + Click here if you want to synchronize all parameters with VST plugin. + Klik disini jika Anda ingin menyelaraskan semua parameter dengan plugin VST. + + + + + Automated + Diotomasi + + + + Click here if you want to display automated parameters only. + Klik disini jika Anda ingin menampilkan parameter terotomasi saja. + + + + Close + Tutup + + + + Close VST effect knob-controller window. + Tutup jendela efek VST pengatur-kenop. + + + + manageVestigeInstrumentView + + + + - VST plugin control + - kontrol VST plugin + + + + VST Sync + + + + + Click here if you want to synchronize all parameters with VST plugin. + Klik disini jika Anda ingin menyelaraskan semua parameter dengan plugin VST. + + + + + Automated + Diotomasi + + + + Click here if you want to display automated parameters only. + Klik disini jika Anda ingin menampilkan parameter terotomasi saja. + + + + Close + Tutup + + + + Close VST plugin knob-controller window. + Tutup jendela plugin VST pengatur-kenop. + + + + opl2instrument + + + Patch + Patch + + + + Op 1 Attack + Attack Op 1 + + + + Op 1 Decay + Decay Op 1 + + + + Op 1 Sustain + Sustain Op 1 + + + + Op 1 Release + Release Op 1 + + + + Op 1 Level + Level Op 1 + + + + Op 1 Level Scaling + Level Scaling Op 1 + + + + Op 1 Frequency Multiple + + + + + Op 1 Feedback + Timbal Balik Op 1 + + + + Op 1 Key Scaling Rate + + + + + Op 1 Percussive Envelope + + + + + Op 1 Tremolo + + + + + Op 1 Vibrato + + + + + Op 1 Waveform + + + + + Op 2 Attack + + + + + Op 2 Decay + + + + + Op 2 Sustain + + + + + Op 2 Release + + + + + Op 2 Level + + + + + Op 2 Level Scaling + + + + + Op 2 Frequency Multiple + + + + + Op 2 Key Scaling Rate + + + + + Op 2 Percussive Envelope + + + + + Op 2 Tremolo + + + + + Op 2 Vibrato + + + + + Op 2 Waveform + + + + + FM + FM + + + + Vibrato Depth + + + + + Tremolo Depth + + + + + opl2instrumentView + + + + Attack + Attack + + + + + Decay + Decay + + + + + Release + Release + + + + + Frequency multiplier + + + + + organicInstrument + + + Distortion + Distorsi + + + + Volume + Volume + + + + + organicInstrumentView + + + Distortion: + Distorsi: + + + + The distortion knob adds distortion to the output of the instrument. + Kenop distorsi menambahkan distorsi ke keluaran instrumen. + + + + Volume: + Volume: + + + + The volume knob controls the volume of the output of the instrument. It is cumulative with the instrument window's volume control. + + + + + Randomise + + + + + The randomize button randomizes all knobs except the harmonics,main volume and distortion knobs. + + + + + + Osc %1 waveform: + Bentuk Gelombang Osc %1: + + + + Osc %1 volume: + Volume Osc %1: + + + + Osc %1 panning: + Keseimbangan Osc %1: + + + + Osc %1 stereo detuning + + + + + cents + sen + + + + Osc %1 harmonic: + + + + + papuInstrument + + + Sweep time + + + + + Sweep direction + + + + + Sweep RtShift amount + + + + + + Wave Pattern Duty + + + + + Channel 1 volume + Volume Saluran 1 + + + + + + Volume sweep direction + + + + + + + Length of each step in sweep + + + + + Channel 2 volume + Volume Saluran 2 + + + + Channel 3 volume + Volume Saluran 3 + + + + Channel 4 volume + Volume Saluran 4 + + + + Shift Register width + + + + + Right Output level + Tingkat Keluaran kanan + + + + Left Output level + Tingkat Keluaran kiri + + + + Channel 1 to SO2 (Left) + Saluran 1 ke SO2 (Kiri) + + + + Channel 2 to SO2 (Left) + Saluran 2 ke SO2 (Kiri) + + + + Channel 3 to SO2 (Left) + Saluran 3 ke SO2 (Kiri) + + + + Channel 4 to SO2 (Left) + Saluran 4 ke SO2 (Kiri) + + + + Channel 1 to SO1 (Right) + Saluran 1 ke SO1 (Kanan) + + + + Channel 2 to SO1 (Right) + Saluran 2 ke SO1 (Kanan) + + + + Channel 3 to SO1 (Right) + Saluran 3 ke SO1 (Kanan) + + + + Channel 4 to SO1 (Right) + Saluran 4 ke SO1 (Kanan) + + + + Treble + Trebel + + + + Bass + Bass + + + + papuInstrumentView + + + Sweep Time: + + + + + Sweep Time + + + + + The amount of increase or decrease in frequency + Besarnya kenaikan atau penurunan frekuensi + + + + Sweep RtShift amount: + + + + + Sweep RtShift amount + + + + + The rate at which increase or decrease in frequency occurs + + + + + + Wave pattern duty: + + + + + Wave Pattern Duty + + + + + + The duty cycle is the ratio of the duration (time) that a signal is ON versus the total period of the signal. + + + + + + Square Channel 1 Volume: + + + + + Square Channel 1 Volume + + + + + + + Length of each step in sweep: + + + + + + + Length of each step in sweep + + + + + + + The delay between step change + + + + + Wave pattern duty + + + + + Square Channel 2 Volume: + + + + + + Square Channel 2 Volume + + + + + Wave Channel Volume: + + + + + + Wave Channel Volume + + + + + Noise Channel Volume: + + + + + + Noise Channel Volume + + + + + SO1 Volume (Right): + Volume SO1 (Kanan): + + + + SO1 Volume (Right) + Volume SO1 (Kanan) + + + + SO2 Volume (Left): + Volume SO2 (Kiri): + + + + SO2 Volume (Left) + Volume SO2 (Kiri) + + + + Treble: + Trebel: + + + + Treble + Trebel + + + + Bass: + Bass: + + + + Bass + Bass + + + + Sweep Direction + + + + + + + + + Volume Sweep Direction + + + + + Shift Register Width + + + + + Channel1 to SO1 (Right) + Saluran1 ke SO1 (Kanan) + + + + Channel2 to SO1 (Right) + Saluran2 ke SO1 (Kanan) + + + + Channel3 to SO1 (Right) + Saluran3 ke SO1 (Kanan) + + + + Channel4 to SO1 (Right) + Saluran4 ke SO1 (Kanan) + + + + Channel1 to SO2 (Left) + Saluran1 ke SO2 (Kiri) + + + + Channel2 to SO2 (Left) + Saluran2 ke SO2 (Kiri) + + + + Channel3 to SO2 (Left) + Saluran3 ke SO2 (Kiri) + + + + Channel4 to SO2 (Left) + Saluran4 ke SO2 (Kiri) + + + + Wave Pattern + Pola Gelombang + + + + Draw the wave here + + + + + patchesDialog + + + Qsynth: Channel Preset + + + + + Bank selector + Pemilih bank + + + + Bank + Bank + + + + Program selector + Pemilih program + + + + Patch + Patch + + + + Name + Nama + + + + OK + OK + + + + Cancel + Batal + + + + pluginBrowser + + + no description + tiada deskripsi + + + + A native amplifier plugin + Plugin amplifier native + + + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Sampler sederhana dengan macam-macam pengaturan untuk menggunakan sampel. (cnth. drum) dalam sebuah trek instrumen + + + + Boost your bass the fast and simple way + Tingkatkan bass Anda dengan cara cepat dan sederhana + + + + Customizable wavetable synthesizer + Synthesizer wavetable yang dapat disesuaikan + + + + An oversampling bitcrusher + + + + + Carla Patchbay Instrument + Instrumen Carla Patchbay + + + + Carla Rack Instrument + Rak Instrumen Carla + + + + A 4-band Crossover Equalizer + + + + + A native delay plugin + + + + + A Dual filter plugin + + + + + plugin for processing dynamics in a flexible way + plugin untuk memproses dynamics dengan cara yang fleksibel + + + + A native eq plugin + Plugin eq bawaan + + + + A native flanger plugin + + + + + Player for GIG files + Pemutar untuk berkas GIG + + + + Filter for importing Hydrogen files into LMMS + Filter untuk mengimpor berkas Hydrogen ke LMMS + + + + Versatile drum synthesizer + Synthesizer drum serbaguna + + + + List installed LADSPA plugins + Daftar plugin LADSPA yang terpasang + + + + plugin for using arbitrary LADSPA-effects inside LMMS. + Plugin untuk menggunakan efek LADSPA yang sewenang-wenang di dalam LMMS. + + + + Incomplete monophonic imitation tb303 + + + + + Filter for exporting MIDI-files from LMMS + Filter untuk mengekspor berkas MIDI dari LMMS + + + + Filter for importing MIDI-files into LMMS + Filter untuk mengimpor berkas MIDI ke LMMS + + + + Monstrous 3-oscillator synth with modulation matrix + + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + Synthesizer seperti NES + + + + 2-operator FM Synth + 2-operator FM Synth + + + + Additive Synthesizer for organ-like sounds + + + + + Emulation of GameBoy (TM) APU + Emulasi APU GameBoy (TM) + + + + GUS-compatible patch instrument + + + + + Plugin for controlling knobs with sound peaks + Plugin untuk mengendalikan kenop dengan puncak suara + + + + Reverb algorithm by Sean Costello + + + + + Player for SoundFont files + Pemutar untuk berkas SoundFont + + + + LMMS port of sfxr + + + + + Emulation of the MOS6581 and MOS8580 SID. +This chip was used in the Commodore 64 computer. + Emulasi SID MOS6581 dan MOS8580. +Chip yang digunakan pada komputer Commodore 64. + + + + Graphical spectrum analyzer plugin + Plugin analisa spektrum grafis + + + + Plugin for enhancing stereo separation of a stereo input file + + + + + Plugin for freely manipulating stereo output + + + + + Tuneful things to bang on + Hal-hal yang menyenangkan untuk ajep-ajep + + + + Three powerful oscillators you can modulate in several ways + + + + + VST-host for using VST(i)-plugins within LMMS + + + + + Vibrating string modeler + Menggetarkan modeler string + + + + plugin for using arbitrary VST effects inside LMMS. + Plugin untuk menggunakan efek VST yang sewenang-wenang di dalam LMMS. + + + + 4-oscillator modulatable wavetable synth + + + + + plugin for waveshaping + plugin untuk pembentukan gelombang + + + + Embedded ZynAddSubFX + Tertanam ZynAddSubFX + + + + sf2Instrument + + + Bank + Bank + + + + Patch + Patch + + + + Gain + Gain + + + + Reverb + + + + + Reverb Roomsize + + + + + Reverb Damping + + + + + Reverb Width + + + + + Reverb Level + + + + + Chorus + + + + + Chorus Lines + + + + + Chorus Level + + + + + Chorus Speed + + + + + Chorus Depth + + + + + A soundfont %1 could not be loaded. + Soundfont %1 tidak dapat dimuat. + + + + sf2InstrumentView + + + Open other SoundFont file + Buka berkas SoundFont lain + + + + Click here to open another SF2 file + Klik disini untuk membuka berkas SF2 lain + + + + Choose the patch + Pilih patch + + + + Gain + GainGain + + + + Apply reverb (if supported) + Aktifkan gema (jika didukung) + + + + This button enables the reverb effect. This is useful for cool effects, but only works on files that support it. + + + + + Reverb Roomsize: + + + + + Reverb Damping: + + + + + Reverb Width: + + + + + Reverb Level: + + + + + Apply chorus (if supported) + + + + + This button enables the chorus effect. This is useful for cool echo effects, but only works on files that support it. + + + + + Chorus Lines: + + + + + Chorus Level: + + + + + Chorus Speed: + + + + + Chorus Depth: + + + + + Open SoundFont file + Buka berkas SoundFont + + + + SoundFont2 Files (*.sf2) + Berkas SoundFont2 (*.sf2) + + + + sfxrInstrument + + + Wave Form + Bentuk Gelombang + + + + sidInstrument + + + Cutoff + Cutoff + + + + Resonance + Resonansi + + + + Filter type + Tipe filter + + + + Voice 3 off + + + + + Volume + Volume + + + + + Chip model + Model chip + + + + sidInstrumentView + + + Volume: + Volume: + + + + Resonance: + Resonansi: + + + + + Cutoff frequency: + Frekuensi cutoff: + + + + High-Pass filter + Filter High-Pass + + + + Band-Pass filter + Filter Band-Pass + + + + Low-Pass filter + Filter Low-Pass + + + + Voice3 Off + + + + + MOS6581 SID + MOS6581 SID + + + + MOS8580 SID + MOS8580 SID + + + + + Attack: + Attack: + + + + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + + + + + + Decay: + Decay: + + + + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + + + + + Sustain: + Sustain: + + + + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + + + + + + Release: + Release: + + + + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. + + + + + + Pulse Width: + + + + + The Pulse Width resolution allows the width to be smoothly swept with no discernable stepping. The Pulse waveform on Oscillator %1 must be selected to have any audible effect. + + + + + Coarse: + + + + + The Coarse detuning allows to detune Voice %1 one octave up or down. + + + + + Pulse Wave + + + + + Triangle Wave + + + + + SawTooth + + + + + Noise + Derau + + + + Sync + Selaras + + + + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. + + + + + Ring-Mod + + + + + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. + + + + + Filtered + + + + + When Filtered is on, Voice %1 will be processed through the Filter. When Filtered is off, Voice %1 appears directly at the output, and the Filter has no effect on it. + + + + + Test + Tes + + + + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. + + + + + stereoEnhancerControlDialog + + + WIDE + LEBAR + + + + Width: + Lebar: + + + + stereoEnhancerControls + + + Width + Lebar + + + + stereoMatrixControlDialog + + + Left to Left Vol: + Vol Kiri ke Kiri: + + + + Left to Right Vol: + Vol Kiri ke Kanan: + + + + Right to Left Vol: + Vol Kanan ke Kiri: + + + + Right to Right Vol: + Vol Kanan ke Kanan: + + + + stereoMatrixControls + + + Left to Left + Kiri ke Kiri + + + + Left to Right + Kiri ke Kanan + + + + Right to Left + Kanan ke Kiri + + + + Right to Right + Kanan ke Kanan + + + + vestigeInstrument + + + Loading plugin + Memuat plugin + + + + Please wait while loading VST-plugin... + Mohon tunggu, memuat VST-plugin... + + + + vibed + + + String %1 volume + Volume string %1 + + + + String %1 stiffness + + + + + Pick %1 position + + + + + Pickup %1 position + + + + + Pan %1 + Keseimbangan %1 + + + + Detune %1 + + + + + Fuzziness %1 + Kekaburan %1 + + + + Length %1 + Panjang %1 + + + + Impulse %1 + Impuls %1 + + + + Octave %1 + Oktaf %1 + + + + vibedView + + + Volume: + Volume: + + + + The 'V' knob sets the volume of the selected string. + Tombol 'V' mengatur volume dari string yang dipilih. + + + + String stiffness: + + + + + The 'S' knob sets the stiffness of the selected string. The stiffness of the string affects how long the string will ring out. The lower the setting, the longer the string will ring. + + + + + Pick position: + Posisi petik: + + + + The 'P' knob sets the position where the selected string will be 'picked'. The lower the setting the closer the pick is to the bridge. + + + + + Pickup position: + Posisi pickup: + + + + The 'PU' knob sets the position where the vibrations will be monitored for the selected string. The lower the setting, the closer the pickup is to the bridge. + + + + + Pan: + Keseimbangan: + + + + The Pan knob determines the location of the selected string in the stereo field. + Tombol keseimbangan menentukan lokasi string yang dipilih di bidang stereo. + + + + Detune: + + + + + The Detune knob modifies the pitch of the selected string. Settings less than zero will cause the string to sound flat. Settings greater than zero will cause the string to sound sharp. + + + + + Fuzziness: + Kekaburan: + + + + The Slap knob adds a bit of fuzz to the selected string which is most apparent during the attack, though it can also be used to make the string sound more 'metallic'. + + + + + Length: + Panjang: + + + + The Length knob sets the length of the selected string. Longer strings will both ring longer and sound brighter, however, they will also eat up more CPU cycles. + + + + + Impulse or initial state + + + + + The 'Imp' selector determines whether the waveform in the graph is to be treated as an impulse imparted to the string by the pick or the initial state of the string. + + + + + Octave + Oktaf + + + + The Octave selector is used to choose which harmonic of the note the string will ring at. For example, '-2' means the string will ring two octaves below the fundamental, 'F' means the string will ring at the fundamental, and '6' means the string will ring six octaves above the fundamental. + + + + + Impulse Editor + Editor Impuls + + + + The waveform editor provides control over the initial state or impulse that is used to start the string vibrating. The buttons to the right of the graph will initialize the waveform to the selected type. The '?' button will load a waveform from a file--only the first 128 samples will be loaded. + +The waveform can also be drawn in the graph. + +The 'S' button will smooth the waveform. + +The 'N' button will normalize the waveform. + + + + + Vibed models up to nine independently vibrating strings. The 'String' selector allows you to choose which string is being edited. The 'Imp' selector chooses whether the graph represents an impulse or the initial state of the string. The 'Octave' selector chooses which harmonic the string should vibrate at. + +The graph allows you to control the initial state or impulse used to set the string in motion. + +The 'V' knob controls the volume. The 'S' knob controls the string's stiffness. The 'P' knob controls the pick position. The 'PU' knob controls the pickup position. + +'Pan' and 'Detune' hopefully don't need explanation. The 'Slap' knob adds a bit of fuzz to the sound of the string. + +The 'Length' knob controls the length of the string. + +The LED in the lower right corner of the waveform editor determines whether the string is active in the current instrument. + + + + + Enable waveform + Aktifkan gelombang grafik + + + + Click here to enable/disable waveform. + Klik disini untuk mengaktifkan/menonaktifkan gelombang graifk. + + + + String + Deretan + + + + The String selector is used to choose which string the controls are editing. A Vibed instrument can contain up to nine independently vibrating strings. The LED in the lower right corner of the waveform editor indicates whether the selected string is active. + + + + + Sine wave + Gelombang sinus + + + + Use a sine-wave for current oscillator. + Gunakan gelombang sinus untuk osilator saat ini. + + + + Triangle wave + Gelombang segitiga + + + + Use a triangle-wave for current oscillator. + Gunakan gelombang segitiga untuk osilator saat ini. + + + + Saw wave + Gelombang gergaji + + + + Use a saw-wave for current oscillator. + Gunakan gelombang gergaji untuk osilator saat ini. + + + + Square wave + Gelombang kotak + + + + Use a square-wave for current oscillator. + Gunakan gelombang kotak untuk osilator saat ini. + + + + White noise wave + Gelombang riuh + + + + Use white-noise for current oscillator. + Gunakan derau putih untuk osilator saat ini. + + + + User defined wave + Gelombang yang didefinisikan pengguna + + + + Use a user-defined waveform for current oscillator. + Gunakan gelombang yang ditetapkan pengguna untuk osilator saat ini. + + + + Smooth + Halus + + + + Click here to smooth waveform. + Klik disini untuk menghaluskan grafik gelombang. + + + + Normalize + Normalisasi + + + + Click here to normalize waveform. + Klik disini untuk menormalisasi gelombang. + + + + voiceObject + + + Voice %1 pulse width + Lebar nadi Suara %1 + + + + Voice %1 attack + Serangan suara %1 + + + + Voice %1 decay + Kerusakan suara %1 + + + + Voice %1 sustain + Penopang suara %1 + + + + Voice %1 release + Pelepasan suara %1 + + + + Voice %1 coarse detuning + Detuning kasar suara %1 + + + + Voice %1 wave shape + Bentuk gelombang suara %1 + + + + Voice %1 sync + Sinkron suara %1 + + + + Voice %1 ring modulate + Modulasi nada suara %1 + + + + Voice %1 filtered + Suara %1 difilter + + + + Voice %1 test + Tes suara %1 + + + + waveShaperControlDialog + + + INPUT + MASUKAN + + + + Input gain: + Gain masukan: + + + + OUTPUT + KELUARAN + + + + Output gain: + Gait keluaran: + + + + Reset waveform + Reset grafik gelombang + + + + Click here to reset the wavegraph back to default + Klik disini untuk mereset gelombang grafik ke default + + + + Smooth waveform + Gelombang halus + + + + Click here to apply smoothing to wavegraph + Klik disini untuk menerapkan kehalusan ke grafik gelombang + + + + Increase graph amplitude by 1dB + Tingkatkan grafik amplitudo sebanyak 1dB + + + + Click here to increase wavegraph amplitude by 1dB + Klik disini untuk meningkatkan amplitudo Grafik gelombang dengan 1dB + + + + Decrease graph amplitude by 1dB + Turunkan grafik aplitudo sebanyak 1dB + + + + Click here to decrease wavegraph amplitude by 1dB + Klik disini untuk mengurangi amplitudo wavegraf dengan 1dB + + + + Clip input + Klip masukan + + + + Clip input signal to 0dB + Klip sinyal masukan ke 0dB + + + + waveShaperControls + + + Input gain + Gain masukan + + + + Output gain + Gain keluaran + + + \ No newline at end of file From 97e738aa421f3cbd9c623a3e67e97f0f6391b537 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 19 Feb 2019 10:51:43 +0900 Subject: [PATCH 59/79] AppImage: bundle JACK fallback library correctly --- cmake/linux/package_linux.sh.in | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 9ff251e51..36b4b3ed5 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -175,10 +175,16 @@ rm -f "${APPDIR}/usr/lib/libwine.so.1" # Use system-provided carla rm -f "${APPDIR}usr/lib/"libcarla*.so -# Move jack out of LD_LIBRARY_PATH +# Remove bundled jack in LD_LIBRARY_PATH if exists if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then + rm "${APPDIR}/usr/lib/libjack.so.0" +fi + +# Bundle jack out of LD_LIBRARY_PATH +JACK_LIB=$(ldd "${APPDIR}/usr/bin/lmms" | sed -n 's/\tlibjack\.so\.0 => \(.\+\) (0x[0-9a-f]\+)/\1/p') +if [ -e "$JACK_LIB" ]; then mkdir -p "${APPDIR}usr/lib/lmms/optional/" - mv "${APPDIR}/usr/lib/libjack.so.0" "${APPDIR}usr/lib/lmms/optional/" + cp "$JACK_LIB" "${APPDIR}usr/lib/lmms/optional/" fi # Point the AppRun to the shim launcher From 55eb831507250b236de80e63d376083dde0b3ae1 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 19 Feb 2019 10:53:42 +0900 Subject: [PATCH 60/79] Bump version to 1.2.0-rc8 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fa83f854..e204a644a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ SET(PROJECT_COPYRIGHT "2008-${PROJECT_YEAR} ${PROJECT_AUTHOR}") SET(VERSION_MAJOR "1") SET(VERSION_MINOR "2") SET(VERSION_RELEASE "0") -SET(VERSION_STAGE "rc7") +SET(VERSION_STAGE "rc8") SET(VERSION_BUILD "0") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") IF(VERSION_STAGE) From 18d478782c97f0b290afec39d606a8334841dc68 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 19 Feb 2019 21:02:02 +0900 Subject: [PATCH 61/79] Fix path to the LMMS binary in AppImage build script --- cmake/linux/package_linux.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 36b4b3ed5..ee0389749 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -181,7 +181,7 @@ if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then fi # Bundle jack out of LD_LIBRARY_PATH -JACK_LIB=$(ldd "${APPDIR}/usr/bin/lmms" | sed -n 's/\tlibjack\.so\.0 => \(.\+\) (0x[0-9a-f]\+)/\1/p') +JACK_LIB=$(ldd "${APPDIR}/usr/bin/lmms.real" | sed -n 's/\tlibjack\.so\.0 => \(.\+\) (0x[0-9a-f]\+)/\1/p') if [ -e "$JACK_LIB" ]; then mkdir -p "${APPDIR}usr/lib/lmms/optional/" cp "$JACK_LIB" "${APPDIR}usr/lib/lmms/optional/" From e7720cc8cb878fb33fa31b1339ad1ffcdd93f00c Mon Sep 17 00:00:00 2001 From: makepost Date: Thu, 14 Feb 2019 03:36:54 +0200 Subject: [PATCH 62/79] lmms_math: Fix build with musl When deciding to polyfill glibc features, check if the standard library claims to be glibc, instead of enumerating platforms in the condition. Unlike master branch which in de3b344 changes math function calls to standard, stable-1.2 keeps their glibc names and fails to build on Linux with another libc such as musl. --- include/lmms_math.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/lmms_math.h b/include/lmms_math.h index ccf5fbf62..ad09117d4 100644 --- a/include/lmms_math.h +++ b/include/lmms_math.h @@ -34,7 +34,7 @@ #include using namespace std; -#if defined (LMMS_BUILD_WIN32) || defined (LMMS_BUILD_APPLE) || defined(LMMS_BUILD_HAIKU) || defined (__FreeBSD__) || defined(__OpenBSD__) +#ifndef __GLIBC__ #ifndef isnanf #define isnanf(x) isnan(x) #endif From 0e77947793eecc073b820b1d5b9e4210bf2afcb3 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 3 Mar 2019 14:44:19 +0100 Subject: [PATCH 63/79] Fix failing build due to missing include Fix the build of MixHelpers.cpp which fails due to a missing include of cstdio (printf is not defined). --- src/core/MixHelpers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index 7ff8dea1e..cdbf079d3 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -26,6 +26,8 @@ #include "lmms_math.h" #include "ValueBuffer.h" +#include + static bool s_NaNHandler; From 6b194558758010aa7fc8f128151f9f0b269113d3 Mon Sep 17 00:00:00 2001 From: justnope <46006588+justnope@users.noreply.github.com> Date: Thu, 7 Mar 2019 11:55:12 +0100 Subject: [PATCH 64/79] Install 32-bit RemoteVstPlugin to a separate directory (#4797) --- plugins/vst_base/RemoteVstPlugin32.cmake | 55 ++++++++++++++++-------- plugins/vst_base/VstPlugin.cpp | 2 +- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index fa8255afe..3c0ef0e28 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -1,32 +1,39 @@ IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) + IF(MSVC) + SET(VCPKG_ROOT "${CMAKE_FIND_ROOT_PATH}") + INSTALL(FILES "${VCPKG_ROOT}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + ELSE(MSVC) + INSTALL(FILES "${MINGW_PREFIX}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${MINGW_PREFIX}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + ENDIF(MSVC) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSEIF(LMMS_BUILD_WIN64 AND MSVC) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) - IF(NOT CMAKE_GENERATOR_32) - IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) - SET(CMAKE_GENERATOR_32 "Visual Studio 14 2015") - SET(MSVC_YEAR 2015) - ELSEIF(MSVC_VER VERSION_EQUAL 19.10 OR MSVC_VER VERSION_EQUAL 19.10) + IF(NOT CMAKE_GENERATOR_32) + IF(MSVC_VER VERSION_GREATER 19.10 OR MSVC_VER VERSION_EQUAL 19.10) SET(CMAKE_GENERATOR_32 "Visual Studio 15 2017") SET(MSVC_YEAR 2017) + ELSEIF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) + SET(CMAKE_GENERATOR_32 "Visual Studio 14 2015") + SET(MSVC_YEAR 2015) ELSE() MESSAGE(SEND_WARNING "Can't build RemoteVstPlugin32, unknown MSVC version ${MSVC_VER} and no CMAKE_GENERATOR_32 set") RETURN() ENDIF() ENDIF() - IF(NOT QT_32_PREFIX AND NOT USING_VCPKG) + IF(NOT QT_32_PREFIX) GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") ENDIF() - IF(NOT QT_32_PREFIX) - MESSAGE(WARNING "Can't build RemoteVstPlugin32, QT_32_PREFIX not set") - RETURN() - ELSEIF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) - MESSAGE(WARNING "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") - RETURN() + #TODO: qt5 installed using vcpkg: I don't know how to detect if the user built the x86 version of qt5 from here. At least not cleanly. + #So for the moment, we'll allow the built. + IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) + MESSAGE(WARNING "No Qt 32 bit installation found at ${QT_32_PREFIX}. If you're using VCPKG you can ignore this message if you've built x86-windows version of qt5") ENDIF() ExternalProject_Add(RemoteVstPlugin32 @@ -38,6 +45,17 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) + + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + + #TODO: find a solution when not using vcpkg for qt + SET(VCPKG_ROOT_32 "${CMAKE_FIND_ROOT_PATH}/../x86-windows") + + INSTALL(FILES "${VCPKG_ROOT_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/pcre2-16.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/double-conversion.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/qt5core.dll" DESTINATION "${PLUGIN_DIR}/32") + ELSEIF(LMMS_BUILD_LINUX) # Use winegcc ExternalProject_Add(RemoteVstPlugin32 @@ -47,6 +65,9 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_COMPILER=${WINEGCC}" "-DCMAKE_CXX_FLAGS=-m32" ) + + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") + ELSEIF(CMAKE_TOOLCHAIN_FILE_32) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" @@ -55,13 +76,11 @@ ELSEIF(CMAKE_TOOLCHAIN_FILE_32) "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_32}" "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE_32}" ) + INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSE() - message(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") + MESSAGE(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") RETURN() ENDIF() -IF(LMMS_BUILD_LINUX) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") -ELSEIF(LMMS_BUILD_WIN32) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}") -ENDIF() diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 5138a58a6..2e69802b2 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -152,7 +152,7 @@ VstPlugin::VstPlugin( const QString & _plugin ) : tryLoad( "RemoteVstPlugin64" ); break; case PE::MachineType::i386: - tryLoad( "RemoteVstPlugin32" ); + tryLoad( "32/RemoteVstPlugin32" ); break; default: m_failed = true; From 9ea2611fa78a8323ee0808325ca08ead9de23708 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 9 Mar 2019 20:47:30 +0900 Subject: [PATCH 65/79] Fix loading 32bit VSTs on Linux Fix a regression in #4797 --- plugins/vst_base/RemoteVstPlugin32.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index 3c0ef0e28..07bed93b6 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -66,7 +66,7 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_FLAGS=-m32" ) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32") ELSEIF(CMAKE_TOOLCHAIN_FILE_32) ExternalProject_Add(RemoteVstPlugin32 From 9148ce1b6f7e3183483b79c6a1a95b515e7f9ab6 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 10 Mar 2019 12:10:04 +0900 Subject: [PATCH 66/79] Fix loading 32bit VSTs when loading LMMS in the build directory Fix another regression in #4797 --- cmake/linux/package_linux.sh.in | 2 +- plugins/vst_base/RemoteVstPlugin/CMakeLists.txt | 1 + plugins/vst_base/RemoteVstPlugin32.cmake | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 2cefe73c6..2eff0f264 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -142,7 +142,7 @@ fi # Move executables so linuxdeployqt can find them ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx" -VSTLIB32="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so" +VSTLIB32="${APPDIR}usr/lib/lmms/32/RemoteVstPlugin32.exe.so" VSTLIB64="${APPDIR}usr/lib/lmms/RemoteVstPlugin64.exe.so" ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx" diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index 2a9f84076..59dd19a0a 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -18,6 +18,7 @@ if(IS_WIN64 OR CMAKE_SIZEOF_VOID_P EQUAL 8) set(BITNESS 64) else() set(BITNESS 32) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/32") endif() FOREACH( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index 07bed93b6..507042148 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -8,7 +8,7 @@ IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) INSTALL(FILES "${MINGW_PREFIX}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") INSTALL(FILES "${MINGW_PREFIX}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") ENDIF(MSVC) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSEIF(LMMS_BUILD_WIN64 AND MSVC) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) @@ -46,7 +46,7 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") #TODO: find a solution when not using vcpkg for qt SET(VCPKG_ROOT_32 "${CMAKE_FIND_ROOT_PATH}/../x86-windows") @@ -66,7 +66,7 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_FLAGS=-m32" ) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32") ELSEIF(CMAKE_TOOLCHAIN_FILE_32) ExternalProject_Add(RemoteVstPlugin32 @@ -78,7 +78,7 @@ ELSEIF(CMAKE_TOOLCHAIN_FILE_32) ) INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSE() MESSAGE(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") RETURN() From 9a91848b3667c7944bf1145dadd35f0f227a10e2 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 67/79] Fix CONTRIBUTORS override --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37da8f414..4ac6bf133 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,7 +45,7 @@ INCLUDE(GenQrc) ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc "${CMAKE_SOURCE_DIR}/doc/AUTHORS" "${CMAKE_SOURCE_DIR}/LICENSE.txt" - "${CMAKE_BINARY_DIR}/CONTRIBUTORS" + "${CONTRIBUTORS}" ) # Paths relative to lmms executable From 92805685b115778e5c74af2843e748fbb9c56ac0 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 68/79] Debian integration: update build dependencies It was wrongly done in 231a8407e8b7422f47c3b0f8d2d807b667c75c24. --- .travis/linux.debian-sid.script.sh | 5 +---- debian/control | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh index a75a9f844..7f489031b 100755 --- a/.travis/linux.debian-sid.script.sh +++ b/.travis/linux.debian-sid.script.sh @@ -21,14 +21,11 @@ fi if [ ! -e "$BASETGZ.stamp" ] then mkdir -p "$HOME/pbuilder-bases" - # debootstrap fails to resolve dependencies which are virtual packages - # e.g. perl-openssl-abi-1.1 provided by perl-openssl-defaults, needed for building SWH - # See also: https://bugs.launchpad.net/ubuntu/+source/debootstrap/+bug/86536 sudo pbuilder --create --basetgz "$BASETGZ" --mirror $MIRROR \ --distribution sid --architecture $TARGET_ARCH \ --debootstrapopts --variant=buildd \ --debootstrapopts --keyring=$KEYRING \ - --debootstrapopts --include=perl,libxml2-utils,libxml-perl,liblist-moreutils-perl,perl-openssl-defaults + --debootstrapopts --include=perl touch "$BASETGZ.stamp" else sudo pbuilder --update --basetgz "$BASETGZ" diff --git a/debian/control b/debian/control index 0997676c9..10f99c2a4 100644 --- a/debian/control +++ b/debian/control @@ -17,6 +17,7 @@ Build-Depends: libfluidsynth-dev, libgig-dev, libjack-jackd2-dev, + liblist-moreutils-perl, libmp3lame-dev, libpulse-dev, libqt5x11extras5-dev, @@ -29,10 +30,12 @@ Build-Depends: libvorbis-dev, libxcb-keysyms1-dev, libxcb-util0-dev, + libxml-perl, + libxml2-utils, portaudio19-dev, qtbase5-private-dev, qttools5-dev, - wine32-tools [i386] + wine64-tools [amd64] | wine32-tools [i386] Standards-Version: 4.2.1.4 Homepage: http://lmms.io/ Vcs-Browser: https://salsa.debian.org/debian-edu-pkg-team/lmms.git From 97502a14aca2887fc618473bf02125df1151a41d Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 69/79] Debian: don't bundle CALF LADSPA library separately anymore It's LMMS specific now --- debian/calf-ladspa.install | 1 - debian/control | 18 ++---------------- debian/lmms-bin.install | 5 +---- 3 files changed, 3 insertions(+), 21 deletions(-) delete mode 100644 debian/calf-ladspa.install diff --git a/debian/calf-ladspa.install b/debian/calf-ladspa.install deleted file mode 100644 index c25e49dbc..000000000 --- a/debian/calf-ladspa.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/lmms/ladspa/calf.so usr/lib/ladspa diff --git a/debian/control b/debian/control index 10f99c2a4..65b87e6d3 100644 --- a/debian/control +++ b/debian/control @@ -44,7 +44,7 @@ Package: lmms-bin Architecture: any Depends: lmms-common (>= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, stk -Recommends: calf-ladspa, tap-plugins, caps, +Recommends: tap-plugins, caps, lmms-vst-server:i386 (>= ${source:Version}) Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm, ladspa-plugin @@ -66,7 +66,7 @@ Description: Linux Multimedia Studio - minimal installation Package: lmms Architecture: any -Depends: calf-ladspa, lmms-bin, ${misc:Depends} +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 @@ -105,17 +105,3 @@ Depends: wine32, wine, ${shlibs:Depends}, ${misc:Depends} Recommends: lmms-bin:any Description: Linux Multimedia Studio - VST server This package contains a helper application that loads VST plugins. - -Package: calf-ladspa -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Replaces: calf-plugins (<< 0.0.19) -Provides: ladspa-plugin -Description: Linux Multimedia Studio - Calf LADSPA plugins - Calf is a pack of audio plugins - effects and instruments. The goal is to - create a set of plugins using decent algorithms and parameter settings, - available in a form which is compatible with as many open source applications - as possible. - . - These plugins are distributed as part of Linux Multimedia Studio, but may be - used by other applications. diff --git a/debian/lmms-bin.install b/debian/lmms-bin.install index 5d19a3103..229fa02e3 100644 --- a/debian/lmms-bin.install +++ b/debian/lmms-bin.install @@ -1,7 +1,4 @@ usr/bin/lmms -usr/lib/*/lmms/ladspa/[a-b]* -usr/lib/*/lmms/ladspa/caps.so -usr/lib/*/lmms/ladspa/c[b-z]* -usr/lib/*/lmms/ladspa/[d-z]* +usr/lib/*/lmms/ladspa/* usr/lib/*/lmms/lib* usr/lib/*/lmms/RemoteZynAddSubFx From af40c764efbf0d29e2d6df1c38f19bb325ee509c Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 70/79] Better Wine detection and support * Support more Wine packagings * Allow building 64-bit RemoteVstPlugin using 32-bit Wine tools if possible * Provide suitable library paths for creating AppImages --- cmake/linux/package_linux.sh.in | 4 +- cmake/modules/FindWine.cmake | 117 +++++++++++++++++++++++-------- cmake/modules/winegcc_wrapper.in | 8 +++ 3 files changed, 98 insertions(+), 31 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 2eff0f264..bd164bd6a 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -134,10 +134,10 @@ export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH # Handle wine linking if [ -d "@WINE_32_LIBRARY_DIR@" ]; then - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_32_LIBRARY_DIR@:@WINE_32_LIBRARY_DIR@wine/ + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_32_LIBRARY_DIRS@ fi if [ -d "@WINE_64_LIBRARY_DIR@" ]; then - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_64_LIBRARY_DIR@:@WINE_64_LIBRARY_DIR@wine/ + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_64_LIBRARY_DIRS@ fi # Move executables so linuxdeployqt can find them diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index 225d6a824..50bf54edb 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -7,46 +7,89 @@ # WINE_DEFINITIONS - Compiler switches required for using wine # +MACRO(_findwine_find_flags output expression result) + STRING(REPLACE " " ";" WINEBUILD_FLAGS "${output}") + FOREACH(FLAG ${WINEBUILD_FLAGS}) + IF("${FLAG}" MATCHES "${expression}") + SET(${result} "${FLAG}") + ENDIF() + ENDFOREACH() +ENDMACRO() + LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging /usr/lib/wine/) - -FIND_PATH(WINE_INCLUDE_DIR wine/exception.h PATH_SUFFIXES wine) FIND_PROGRAM(WINE_CXX NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable - PATHS /usr/lib/wine) + PATHS /usr/lib/wine +) FIND_PROGRAM(WINE_BUILD NAMES winebuild) +# Detect wine paths and handle linking problems +IF(WINE_CXX) + EXEC_PROGRAM(${WINE_CXX} ARGS "-m32 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_32) + EXEC_PROGRAM(${WINE_CXX} ARGS "-m64 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_64) + _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC) + _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR) + _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32) + _findwine_find_flags("${WINEBUILD_OUTPUT_64}" "libwinecrt0\\.a.*" WINECRT_64) + STRING(REGEX REPLACE "^-isystem" "" WINE_INCLUDE_HINT "${WINEGCC_INCLUDE_DIR}") + STRING(REGEX REPLACE "/wine/windows$" "" WINE_INCLUDE_HINT "${WINE_INCLUDE_HINT}") + STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_32_LIBRARY_DIR "${WINECRT_32}") + STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_64_LIBRARY_DIR "${WINECRT_64}") + + IF(BUGGED_WINEGCC) + MESSAGE(WARNING "Your winegcc is unusable due to https://bugs.winehq.org/show_bug.cgi?id=46293,\n + Consider either upgrading or downgrading wine.") + RETURN() + ENDIF() + IF(WINE_32_LIBRARY_DIR STREQUAL WINE_64_LIBRARY_DIR) + MESSAGE(STATUS "Old winegcc detected, trying to use workaround linking") + # Fix library search directory according to the target bitness + IF(WINE_32_LIBRARY_DIR MATCHES "/lib/(x86_64|i386)-") + # Debian systems + STRING(REPLACE "/lib/x86_64-" "/lib/i386-" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}") + STRING(REPLACE "/lib/i386-" "/lib/x86_64-" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/(lib|lib64)/wine/$") + # WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) + STRING(REGEX REPLACE "/lib64/wine/$" "/lib/wine/" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}") + STRING(REGEX REPLACE "/lib/wine/$" "/lib64/wine/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib32/.*/wine/") + # Systems with old multilib layout + STRING(REPLACE "/lib32/" "/lib/" WINE_64_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}") + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib64/.*/wine/") + # We need to test if the corresponding 64bit library directory is lib or lib32 + STRING(REPLACE "/lib64/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}") + STRING(REPLACE "/lib64/" "/lib/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ENDIF() + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib/.*/wine/") + # Test if this directory is for 32bit or 64bit + STRING(REPLACE "/lib/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}") + SET(WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + STRING(REPLACE "/lib/" "/lib64/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ENDIF() + ELSE() + MESSAGE(WARNING "Can't detect wine installation layout. You may get some build errors.") + ENDIF() + SET(WINE_LIBRARY_FIX "${WINE_32_LIBRARY_DIR} and ${WINE_64_LIBRARY_DIR}") + ENDIF() +ENDIF() + +FIND_PATH(WINE_INCLUDE_DIR wine/exception.h + HINTS "${WINE_INCLUDE_HINT}" +) SET(_ARCHITECTURE ${CMAKE_LIBRARY_ARCHITECTURE}) -FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine) +FIND_LIBRARY(WINE_LIBRARY NAMES wine + PATH_SUFFIXES wine i386-linux-gnu/wine + HINTS "${WINE_32_LIBRARY_DIR}" "${WINE_64_LIBRARY_DIR}" +) SET(CMAKE_LIBRARY_ARCHITECTURE ${_ARCHITECTURE}) SET(WINE_INCLUDE_DIRS ${WINE_INCLUDE_DIR} ) -SET(WINE_LIBRARIES ${WINE_LIBRARY} ) - -# Handle wine linking problems -EXEC_PROGRAM(${WINE_CXX} ARGS "-v -m32 /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT) -STRING(REPLACE " " ";" WINEBUILD_FLAGS "${WINEBUILD_OUTPUT}") - -FOREACH(FLAG ${WINEBUILD_FLAGS}) - IF("${FLAG}" MATCHES "libwinecrt0.a.*") - STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" FLAG "${FLAG}") - - SET(WINE_64_LIBRARY_DIR "${FLAG}/") - - # Debian systems - STRING(REPLACE "/lib/x86_64-" "/lib/i386-" FLAG "${FLAG}") - # Fedora systems - STRING(REPLACE "/lib/lib64" "/lib/i386" FLAG "${FLAG}") - # Gentoo systems - STRING(REPLACE "/lib/wine-" "/lib32/wine-" FLAG "${FLAG}") - # WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) - STRING(REGEX REPLACE "/lib64$" "/lib" FLAG "${FLAG}") - - SET(WINE_32_LIBRARY_DIR "${FLAG}/") - ENDIF() -ENDFOREACH() +SET(WINE_LIBRARIES ${WINE_LIBRARY}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_INCLUDE_DIRS) @@ -54,7 +97,23 @@ find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_ mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD) IF(WINE_32_LIBRARY_DIR) - SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}wine/ -L${WINE_32_LIBRARY_DIR}") + IF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib") + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../") + SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}/..") + ELSE() + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}") + SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}") + ENDIF() +ENDIF() + +IF(WINE_64_LIBRARY_DIR) + IF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib") + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../") + SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}/..") + ELSE() + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR}") + SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}") + ENDIF() ENDIF() # Create winegcc wrapper diff --git a/cmake/modules/winegcc_wrapper.in b/cmake/modules/winegcc_wrapper.in index d7d680be2..32d65dd68 100755 --- a/cmake/modules/winegcc_wrapper.in +++ b/cmake/modules/winegcc_wrapper.in @@ -22,6 +22,9 @@ while [ $# -gt 0 ]; do -m32) win32=true ;; + -m64) + win64=true + ;; *) ;; @@ -47,6 +50,11 @@ if [ "$win32" = true ] && [ "$no_link" != true ]; then extra_args="$extra_args @WINE_32_FLAGS@" fi +# Apply -m64 library fix if necessary +if [ "$win64" = true ] && [ "$no_link" != true ]; then + extra_args="$extra_args @WINE_64_FLAGS@" +fi + # Run winegcc export WINEBUILD=@WINE_BUILD@ @WINE_CXX@ $extra_args $args From 8c4514ff209de5ddc71a67acd2a0216227d641dc Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 71/79] Check if winegcc works before building RemoteVstPlugin --- cmake/modules/CheckWineGcc.cmake | 27 ++++++++++++++++++++++++ plugins/vst_base/RemoteVstPlugin32.cmake | 6 ++++++ plugins/vst_base/RemoteVstPlugin64.cmake | 6 ++++++ 3 files changed, 39 insertions(+) create mode 100644 cmake/modules/CheckWineGcc.cmake diff --git a/cmake/modules/CheckWineGcc.cmake b/cmake/modules/CheckWineGcc.cmake new file mode 100644 index 000000000..2956198d8 --- /dev/null +++ b/cmake/modules/CheckWineGcc.cmake @@ -0,0 +1,27 @@ +INCLUDE(CheckCXXSourceCompiles) + +FUNCTION(CheckWineGcc BITNESS WINEGCC_EXECUTABLE RESULT) + FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx" " + #include + #define USE_WS_PREFIX + #include + int main(int argc, const char* argv[]) { + return 0; + } + ") + EXECUTE_PROCESS(COMMAND ${WINEGCC_EXECUTABLE} "-m${BITNESS}" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx" + "-o" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test" + OUTPUT_QUIET ERROR_QUIET + RESULT_VARIABLE WINEGCC_RESULT + ) + FILE(REMOVE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.exe.so" + ) + IF(WINEGCC_RESULT EQUAL 0) + SET(${RESULT} True PARENT_SCOPE) + ELSE() + SET(${RESULT} False PARENT_SCOPE) + ENDIF() +ENDFUNCTION() diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index 507042148..9a8f04529 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -58,6 +58,12 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) ELSEIF(LMMS_BUILD_LINUX) # Use winegcc + INCLUDE(CheckWineGcc) + CheckWineGcc(32 "${WINEGCC}" WINEGCC_WORKING) + IF(NOT WINEGCC_WORKING) + MESSAGE(WARNING "winegcc fails to complie 32-bit binaries, please make sure you have 32-bit GCC libraries") + RETURN() + ENDIF() ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS diff --git a/plugins/vst_base/RemoteVstPlugin64.cmake b/plugins/vst_base/RemoteVstPlugin64.cmake index f802bc4b9..4b02bf8ab 100644 --- a/plugins/vst_base/RemoteVstPlugin64.cmake +++ b/plugins/vst_base/RemoteVstPlugin64.cmake @@ -2,6 +2,12 @@ IF(LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}") ELSEIF(LMMS_BUILD_LINUX) + INCLUDE(CheckWineGcc) + CheckWineGcc(64 "${WINEGCC}" WINEGCC_WORKING) + IF(NOT WINEGCC_WORKING) + MESSAGE(WARNING "winegcc fails to compile 64-bit binaries, please make sure you have 64-bit GCC libraries") + RETURN() + ENDIF() ExternalProject_Add(RemoteVstPlugin64 "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS From ae4e40de97d4e4e544166f6988b02c40e70fdb2c Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 72/79] Modify VST build systems to make debian integration work correctly --- CMakeLists.txt | 3 ++- cmake/modules/winegcc_wrapper.in | 3 +++ debian/control | 8 ++++---- debian/lmms-vst-server.install | 2 +- debian/rules | 14 ++++++++++---- plugins/vst_base/CMakeLists.txt | 16 ++++++++++------ plugins/vst_base/VstPlugin.cpp | 4 ++-- plugins/vst_base/vstbase/CMakeLists.txt | 3 +++ 8 files changed, 35 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 777245268..36ad7f148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,8 @@ OPTION(WANT_STK "Include Stk (Synthesis Toolkit) support" ON) OPTION(WANT_SWH "Include Steve Harris's LADSPA plugins" ON) OPTION(WANT_TAP "Include Tom's Audio Processing LADSPA plugins" ON) OPTION(WANT_VST "Include VST support" ON) -OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF) +OPTION(WANT_VST_32 "Include 32-bit VST support" ON) +OPTION(WANT_VST_64 "Include 64-bit VST support" ON) OPTION(WANT_WINMM "Include WinMM MIDI support" OFF) OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF) diff --git a/cmake/modules/winegcc_wrapper.in b/cmake/modules/winegcc_wrapper.in index 32d65dd68..d32aec664 100755 --- a/cmake/modules/winegcc_wrapper.in +++ b/cmake/modules/winegcc_wrapper.in @@ -45,6 +45,9 @@ fi # by FindWine.cmake extra_args="-I@WINE_INCLUDE_DIR@ -I@WINE_INCLUDE_DIR@/wine/windows" +# Apply manually specified flags +extra_args="$extra_args @WINE_CXX_FLAGS@" + # Apply -m32 library fix if necessary if [ "$win32" = true ] && [ "$no_link" != true ]; then extra_args="$extra_args @WINE_32_FLAGS@" diff --git a/debian/control b/debian/control index 65b87e6d3..463353df0 100644 --- a/debian/control +++ b/debian/control @@ -45,7 +45,8 @@ Architecture: any Depends: lmms-common (>= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, stk Recommends: tap-plugins, caps, - lmms-vst-server:i386 (>= ${source:Version}) + lmms-vst-server:i386 (>= ${source:Version}), + lmms-vst-server:amd64 (>= ${source:Version}) Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm, ladspa-plugin Replaces: lmms-common (<< 1.0.0-1) @@ -99,9 +100,8 @@ Description: Linux Multimedia Studio - common files and some example projects. Package: lmms-vst-server -Architecture: i386 -# Order matters to avoid wine64 -Depends: wine32, wine, ${shlibs:Depends}, ${misc:Depends} +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/lmms-vst-server.install b/debian/lmms-vst-server.install index 1b520479d..60efaed7b 100644 --- a/debian/lmms-vst-server.install +++ b/debian/lmms-vst-server.install @@ -1 +1 @@ -usr/lib/*/lmms/RemoteVstPlugin* +usr/lib/*/lmms/{32/,}RemoteVstPlugin* diff --git a/debian/rules b/debian/rules index 5e8345845..aed094c22 100755 --- a/debian/rules +++ b/debian/rules @@ -6,6 +6,7 @@ DH_CMAKE_BUILD_DIR=obj -${DEB_BUILD_GNU_TYPE} DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) +DEB_HOST_ARCH_BIT ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_BITS) CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DFORCE_VERSION=internal \ -DWANT_QT5=1 @@ -13,13 +14,18 @@ ifneq ($(DEB_HOST_ARCH_OS),linux) CMAKE_OPTS+= -DWANT_ALSA=0 endif -ifeq ($(DEB_HOST_ARCH),i386) +ifeq ($(DEB_HOST_ARCH),amd64) export PATH := $(PATH):/usr/lib/wine WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine -CMAKE_OPTS+= -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH) +CMAKE_OPTS+= -DWANT_VST_32=OFF -DREMOTE_VST_PLUGIN_FILEPATH_32=../../i386-linux-gnu/lmms/32/RemoteVstPlugin32 \ + -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH) +else ifeq ($(DEB_HOST_ARCH),i386) +export PATH := $(PATH):/usr/lib/wine +WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine +CMAKE_OPTS+= -DWANT_VST_64=OFF -DREMOTE_VST_PLUGIN_FILEPATH_64=../../x86_64-linux-gnu/lmms/RemoteVstPlugin64 \ + -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH) else -CMAKE_OPTS+= -DWANT_VST_NOWINE=1 \ - -DREMOTE_VST_PLUGIN_FILEPATH=../../i386-linux-gnu/lmms/RemoteVstPlugin +CMAKE_OPTS+= -DWANT_VST=OFF endif # Define NDEBUG. This helps with reproducible builds. diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 314d5fc18..44ed0dcb3 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -5,11 +5,11 @@ ENDIF() INCLUDE(BuildPlugin) INCLUDE(ExternalProject) -ADD_SUBDIRECTORY(vstbase) +# These variables are not meant to be used normally, except packaging +SET(REMOTE_VST_PLUGIN_FILEPATH_32 "32/RemoteVstPlugin32" CACHE STRING "Relative file path to RemoteVstPlugin32") +SET(REMOTE_VST_PLUGIN_FILEPATH_64 "RemoteVstPlugin64" CACHE STRING "Relative file path to RemoteVstPlugin64") -IF(LMMS_BUILD_LINUX AND WANT_VST_NOWINE) - RETURN() -ENDIF() +ADD_SUBDIRECTORY(vstbase) SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) @@ -29,6 +29,10 @@ SET(EXTERNALPROJECT_CMAKE_ARGS ) # build 32 bit version of RemoteVstPlugin -INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake") +IF(WANT_VST_32) + INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake") +ENDIF() # build 64 bit version of RemoteVstPlugin -INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake") +IF(WANT_VST_64) + INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake") +ENDIF() diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 2e69802b2..7dbeee5a6 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -149,10 +149,10 @@ VstPlugin::VstPlugin( const QString & _plugin ) : switch(machineType) { case PE::MachineType::amd64: - tryLoad( "RemoteVstPlugin64" ); + tryLoad( REMOTE_VST_PLUGIN_FILEPATH_64 ); // Default: RemoteVstPlugin64 break; case PE::MachineType::i386: - tryLoad( "32/RemoteVstPlugin32" ); + tryLoad( REMOTE_VST_PLUGIN_FILEPATH_32 ); // Default: 32/RemoteVstPlugin32 break; default: m_failed = true; diff --git a/plugins/vst_base/vstbase/CMakeLists.txt b/plugins/vst_base/vstbase/CMakeLists.txt index 28c09edb3..bd5f98b56 100644 --- a/plugins/vst_base/vstbase/CMakeLists.txt +++ b/plugins/vst_base/vstbase/CMakeLists.txt @@ -1,3 +1,6 @@ +ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH_32="${REMOTE_VST_PLUGIN_FILEPATH_32}") +ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH_64="${REMOTE_VST_PLUGIN_FILEPATH_64}") + BUILD_PLUGIN(vstbase ../vst_base.cpp ../VstPlugin.cpp ../VstPlugin.h ../communication.h MOCFILES ../VstPlugin.h From 5eb6b138aa7f1c8ffa884c7d81d49a1850559f54 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 73/79] Allow creating AppImages on systems newer than linuxdeployqt officially supports Note that the additional -unsupported-allow-new-glibc switch may result in an AppImage which is unusable on old systems. --- cmake/linux/package_linux.sh.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index bd164bd6a..e6d79185e 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -172,8 +172,10 @@ executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale # Bundle both qt and non-qt dependencies into appimage format echo -e "\nBundling and relinking system dependencies..." echo -e ">>>>> linuxdeployqt" > "$LOGFILE" +# FIXME: -unsupported-allow-new-glibc may result in an AppImage which is unusable on old systems. + # shellcheck disable=SC2086 -"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1 +"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -unsupported-allow-new-glibc -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1 success "Bundled and relinked dependencies" # Link to original location so lmms can find them From 61c3f87ee677fc1ae390ef036709f296fee64c64 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 17:06:39 +0900 Subject: [PATCH 74/79] Support FX Mixer for sample tracks and add controls to sample track window (#3866) This work is based on https://github.com/LMMS/lmms/pull/3632 by @grejppi. --- include/FxLineLcdSpinBox.h | 53 ++++ include/InstrumentTrack.h | 3 +- include/SampleTrack.h | 101 +++++++- include/Track.h | 4 + src/core/FxMixer.cpp | 31 ++- src/core/Track.cpp | 21 +- src/gui/CMakeLists.txt | 1 + src/gui/FxMixerView.cpp | 7 + src/gui/widgets/FxLineLcdSpinBox.cpp | 66 +++++ src/tracks/InstrumentTrack.cpp | 50 +--- src/tracks/SampleTrack.cpp | 362 ++++++++++++++++++++++++--- 11 files changed, 614 insertions(+), 85 deletions(-) create mode 100644 include/FxLineLcdSpinBox.h create mode 100644 src/gui/widgets/FxLineLcdSpinBox.cpp diff --git a/include/FxLineLcdSpinBox.h b/include/FxLineLcdSpinBox.h new file mode 100644 index 000000000..fa001b2bb --- /dev/null +++ b/include/FxLineLcdSpinBox.h @@ -0,0 +1,53 @@ +/* + * FxLineLcdSpinBox.h - a specialization of LcdSpnBox for setting FX channels + * + * 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 FX_LINE_LCD_SPIN_BOX_H +#define FX_LINE_LCD_SPIN_BOX_H + +#include "LcdSpinBox.h" + +class TrackView; + + +class FxLineLcdSpinBox : public LcdSpinBox +{ + Q_OBJECT +public: + FxLineLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = NULL) : + LcdSpinBox(numDigits, parent, name), m_tv(tv) + {} + virtual ~FxLineLcdSpinBox() {} + + void setTrackView(TrackView * tv); + +protected: + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void contextMenuEvent(QContextMenuEvent* event); + +private: + TrackView * m_tv; + +}; + +#endif diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index fb12e825a..42d7910b9 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -52,6 +52,7 @@ class InstrumentTrackWindow; class InstrumentMidiIOView; class InstrumentMiscView; class Knob; +class FxLineLcdSpinBox; class LcdSpinBox; class LeftRightNav; class midiPortMenu; @@ -440,7 +441,7 @@ private: QLabel * m_pitchLabel; LcdSpinBox* m_pitchRangeSpinBox; QLabel * m_pitchRangeLabel; - LcdSpinBox * m_effectChannelNumber; + FxLineLcdSpinBox * m_effectChannelNumber; diff --git a/include/SampleTrack.h b/include/SampleTrack.h index decf52f3f..ccb5a020e 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -26,13 +26,19 @@ #define SAMPLE_TRACK_H #include +#include #include "AudioPort.h" +#include "FxMixer.h" +#include "FxLineLcdSpinBox.h" #include "Track.h" class EffectRackView; class Knob; class SampleBuffer; +class SampleTrackWindow; +class TrackLabelButton; +class QLineEdit; class SampleTCO : public TrackContentObject @@ -140,6 +146,11 @@ public: QDomElement & _parent ); virtual void loadTrackSpecificSettings( const QDomElement & _this ); + inline IntModel * effectChannelModel() + { + return &m_effectChannelModel; + } + inline AudioPort * audioPort() { return &m_audioPort; @@ -153,15 +164,18 @@ public: public slots: void updateTcos(); void setPlayingTcos( bool isPlaying ); + void updateEffectChannel(); private: FloatModel m_volumeModel; FloatModel m_panningModel; + IntModel m_effectChannelModel; AudioPort m_audioPort; friend class SampleTrackView; + friend class SampleTrackWindow; } ; @@ -174,6 +188,24 @@ public: SampleTrackView( SampleTrack* Track, TrackContainerView* tcv ); virtual ~SampleTrackView(); + SampleTrackWindow * getSampleTrackWindow() + { + return m_window; + } + + SampleTrack * model() + { + return castModel(); + } + + const SampleTrack * model() const + { + return castModel(); + } + + + virtual QMenu * createFxMenu( QString title, QString newFxLabel ); + public slots: void showEffects(); @@ -187,12 +219,77 @@ protected: } +private slots: + void assignFxLine( int channelIndex ); + void createFxLine(); + + private: - EffectRackView * m_effectRack; - QWidget * m_effWindow; + SampleTrackWindow * m_window; Knob * m_volumeKnob; Knob * m_panningKnob; + TrackLabelButton * m_tlb; + + + friend class SampleTrackWindow; + +} ; + + + +class SampleTrackWindow : public QWidget, public ModelView, public SerializingObjectHook +{ + Q_OBJECT +public: + SampleTrackWindow(SampleTrackView * tv); + virtual ~SampleTrackWindow(); + + SampleTrack * model() + { + return castModel(); + } + + const SampleTrack * model() const + { + return castModel(); + } + + void setSampleTrackView(SampleTrackView * tv); + + SampleTrackView *sampleTrackView() + { + return m_stv; + } + + +public slots: + void textChanged(const QString & new_name); + void toggleVisibility(bool on); + void updateName(); + + +protected: + // capture close-events for toggling sample-track-button + virtual void closeEvent(QCloseEvent * ce); + + virtual void saveSettings(QDomDocument & doc, QDomElement & element); + virtual void loadSettings(const QDomElement & element); + +private: + virtual void modelChanged(); + + SampleTrack * m_track; + SampleTrackView * m_stv; + + // widgets on the top of an sample-track-window + QLineEdit * m_nameLineEdit; + Knob * m_volumeKnob; + Knob * m_panningKnob; + FxLineLcdSpinBox * m_effectChannelNumber; + + EffectRackView * m_effectRack; + } ; diff --git a/include/Track.h b/include/Track.h index 302dcb5cc..f7f71de13 100644 --- a/include/Track.h +++ b/include/Track.h @@ -675,6 +675,10 @@ public: virtual void update(); + // Create a menu for assigning/creating channels for this track + // Currently instrument track and sample track supports it + virtual QMenu * createFxMenu(QString title, QString newFxLabel); + public slots: virtual bool close(); diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 0e5f200d6..032090bf1 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -32,6 +32,7 @@ #include "Song.h" #include "InstrumentTrack.h" +#include "SampleTrack.h" #include "BBTrackContainer.h" FxRoute::FxRoute( FxChannel * from, FxChannel * to, float amount ) : @@ -305,6 +306,22 @@ void FxMixer::deleteChannel( int index ) inst->effectChannelModel()->setValue(val-1); } } + else if( t->type() == Track::SampleTrack ) + { + SampleTrack* strk = dynamic_cast( t ); + int val = strk->effectChannelModel()->value(0); + if( val == index ) + { + // we are deleting this track's fx send + // send to master + strk->effectChannelModel()->setValue(0); + } + else if( val > index ) + { + // subtract 1 to make up for the missing channel + strk->effectChannelModel()->setValue(val-1); + } + } } FxChannel * ch = m_fxChannels[index]; @@ -379,6 +396,19 @@ void FxMixer::moveChannelLeft( int index ) inst->effectChannelModel()->setValue(a); } } + else if( trackList[i]->type() == Track::SampleTrack ) + { + SampleTrack * strk = (SampleTrack *) trackList[i]; + int val = strk->effectChannelModel()->value(0); + if( val == a ) + { + strk->effectChannelModel()->setValue(b); + } + else if( val == b ) + { + strk->effectChannelModel()->setValue(a); + } + } } } @@ -780,4 +810,3 @@ void FxMixer::validateChannelName( int index, int oldIndex ) m_fxChannels[index]->m_name = tr( "FX %1" ).arg( index ); } } - diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 5e6758fde..6c38711c4 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1924,13 +1924,15 @@ void TrackOperationsWidget::updateMenu() { toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) ); } - if( InstrumentTrackView * trackView = dynamic_cast( m_trackView ) ) + if (QMenu *fxMenu = m_trackView->createFxMenu(tr("FX %1: %2"), tr("Assign to new FX Channel"))) { - QMenu *fxMenu = trackView->createFxMenu( tr( "FX %1: %2" ), tr( "Assign to new FX Channel" )); toMenu->addMenu(fxMenu); + } + if (InstrumentTrackView * trackView = dynamic_cast(m_trackView)) + { toMenu->addSeparator(); - toMenu->addMenu( trackView->midiMenu() ); + toMenu->addMenu(trackView->midiMenu()); } if( dynamic_cast( m_trackView ) ) { @@ -2677,6 +2679,19 @@ void TrackView::update() +/*! \brief Create a menu for assigning/creating channels for this track. + * + */ +QMenu * TrackView::createFxMenu(QString title, QString newFxLabel) +{ + Q_UNUSED(title) + Q_UNUSED(newFxLabel) + return NULL; +} + + + + /*! \brief Close this track View. * */ diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index d5ff64612..f17ef105f 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -56,6 +56,7 @@ SET(LMMS_SRCS gui/widgets/FadeButton.cpp gui/widgets/Fader.cpp gui/widgets/FxLine.cpp + gui/widgets/FxLineLcdSpinBox.cpp gui/widgets/Graph.cpp gui/widgets/GroupBox.cpp gui/widgets/InstrumentFunctionViews.cpp diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 440e37d10..0a6a54866 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -47,6 +47,7 @@ #include "Mixer.h" #include "gui_templates.h" #include "InstrumentTrack.h" +#include "SampleTrack.h" #include "Song.h" #include "BBTrackContainer.h" @@ -251,6 +252,12 @@ void FxMixerView::updateMaxChannelSelector() inst->effectChannelModel()->setRange(0, m_fxChannelViews.size()-1,1); } + else if( trackList[i]->type() == Track::SampleTrack ) + { + SampleTrack * strk = (SampleTrack *) trackList[i]; + strk->effectChannelModel()->setRange(0, + m_fxChannelViews.size()-1,1); + } } } } diff --git a/src/gui/widgets/FxLineLcdSpinBox.cpp b/src/gui/widgets/FxLineLcdSpinBox.cpp new file mode 100644 index 000000000..bfe4a9637 --- /dev/null +++ b/src/gui/widgets/FxLineLcdSpinBox.cpp @@ -0,0 +1,66 @@ +/* + * FxLineLcdSpinBox.cpp - a specialization of LcdSpnBox for setting FX channels + * + * 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. + * + */ + +#include "FxLineLcdSpinBox.h" + +#include "CaptionMenu.h" +#include "FxMixerView.h" +#include "GuiApplication.h" +#include "Track.h" + +void FxLineLcdSpinBox::setTrackView(TrackView * tv) +{ + m_tv = tv; +} + +void FxLineLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event) +{ + gui->fxMixerView()->setCurrentFxLine(model()->value()); + + gui->fxMixerView()->parentWidget()->show(); + gui->fxMixerView()->show();// show fxMixer window + gui->fxMixerView()->setFocus();// set focus to fxMixer window + //engine::getFxMixerView()->raise(); +} + +void FxLineLcdSpinBox::contextMenuEvent(QContextMenuEvent* event) +{ + // for the case, the user clicked right while pressing left mouse- + // button, the context-menu appears while mouse-cursor is still hidden + // and it isn't shown again until user does something which causes + // an QApplication::restoreOverrideCursor()-call... + mouseReleaseEvent(nullptr); + + QPointer contextMenu = new CaptionMenu(model()->displayName(), this); + + if (QMenu *fxMenu = m_tv->createFxMenu( + tr("Assign to:"), tr("New FX Channel"))) + { + contextMenu->addMenu(fxMenu); + + contextMenu->addSeparator(); + } + addDefaultActions(contextMenu); + contextMenu->exec(QCursor::pos()); +} diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index a927e8aad..1dc0642d6 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -47,6 +47,7 @@ #include "EffectRackView.h" #include "embed.h" #include "FileBrowser.h" +#include "FxLineLcdSpinBox.h" #include "FxMixer.h" #include "FxMixerView.h" #include "GuiApplication.h" @@ -1249,52 +1250,6 @@ QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel) -class fxLineLcdSpinBox : public LcdSpinBox -{ - Q_OBJECT - public: - fxLineLcdSpinBox( int _num_digits, QWidget * _parent, - const QString & _name ) : - LcdSpinBox( _num_digits, _parent, _name ) {} - - protected: - virtual void mouseDoubleClickEvent ( QMouseEvent * _me ) - { - gui->fxMixerView()->setCurrentFxLine( model()->value() ); - - gui->fxMixerView()->parentWidget()->show(); - gui->fxMixerView()->show();// show fxMixer window - gui->fxMixerView()->setFocus();// set focus to fxMixer window - //engine::getFxMixerView()->raise(); - } - - virtual void contextMenuEvent( QContextMenuEvent* event ) - { - // for the case, the user clicked right while pressing left mouse- - // button, the context-menu appears while mouse-cursor is still hidden - // and it isn't shown again until user does something which causes - // an QApplication::restoreOverrideCursor()-call... - mouseReleaseEvent( NULL ); - - QPointer contextMenu = new CaptionMenu( model()->displayName(), this ); - - // This condition is here just as a safety check, fxLineLcdSpinBox is aways - // created inside a TabWidget inside an InstrumentTrackWindow - if ( InstrumentTrackWindow* window = dynamic_cast( (QWidget *)this->parent()->parent() ) ) - { - QMenu *fxMenu = window->instrumentTrackView()->createFxMenu( tr( "Assign to:" ), tr( "New FX channel" ) ); - contextMenu->addMenu( fxMenu ); - - contextMenu->addSeparator(); - } - addDefaultActions( contextMenu ); - contextMenu->exec( QCursor::pos() ); - } - -}; - - - // #### ITW: InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : QWidget(), @@ -1415,7 +1370,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : // setup spinbox for selecting FX-channel - m_effectChannelNumber = new fxLineLcdSpinBox( 2, NULL, tr( "FX channel" ) ); + m_effectChannelNumber = new FxLineLcdSpinBox( 2, NULL, tr( "FX channel" ), m_itv ); basicControlsLayout->addWidget( m_effectChannelNumber, 0, 6 ); basicControlsLayout->setAlignment( m_effectChannelNumber, widgetAlignment ); @@ -1536,6 +1491,7 @@ void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView* view ) } m_itv = view; + m_effectChannelNumber->setTrackView(m_itv); } diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 8fa6fd50f..c965af140 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,8 @@ #include "MainWindow.h" #include "Mixer.h" #include "EffectRackView.h" +#include "FxMixerView.h" +#include "TabWidget.h" #include "TrackLabelButton.h" SampleTCO::SampleTCO( Track * _track ) : @@ -471,7 +474,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) bool muted = m_tco->getTrack()->isMuted() || m_tco->isMuted(); // state: selected, muted, normal - c = isSelected() ? selectedColor() : ( muted ? mutedBackgroundColor() + c = isSelected() ? selectedColor() : ( muted ? mutedBackgroundColor() : painter.background().color() ); lingrad.setColorAt( 1, c.darker( 300 ) ); @@ -515,7 +518,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) // inner border p.setPen( c.lighter( 160 ) ); - p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH, + p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH, rect().bottom() - TCO_BORDER_WIDTH ); // outer border @@ -531,7 +534,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) embed::getIconPixmap( "muted", size, size ) ); } - // recording sample tracks is not possible at the moment + // recording sample tracks is not possible at the moment /* if( m_tco->isRecord() ) { @@ -562,10 +565,14 @@ SampleTrack::SampleTrack( TrackContainer* tc ) : tr( "Volume" ) ), m_panningModel( DefaultPanning, PanningLeft, PanningRight, 0.1f, this, tr( "Panning" ) ), + m_effectChannelModel( 0, 0, 0, this, tr( "FX channel" ) ), m_audioPort( tr( "Sample track" ), true, &m_volumeModel, &m_panningModel, &m_mutedModel ) { setName( tr( "Sample track" ) ); m_panningModel.setCenterValue( DefaultPanning ); + m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels()-1, 1); + + connect( &m_effectChannelModel, SIGNAL( dataChanged() ), this, SLOT( updateEffectChannel() ) ); } @@ -693,6 +700,7 @@ void SampleTrack::saveTrackSpecificSettings( QDomDocument & _doc, #endif m_volumeModel.saveSettings( _doc, _this, "vol" ); m_panningModel.saveSettings( _doc, _this, "pan" ); + m_effectChannelModel.saveSettings( _doc, _this, "fxch" ); } @@ -715,6 +723,8 @@ void SampleTrack::loadTrackSpecificSettings( const QDomElement & _this ) } m_volumeModel.loadSettings( _this, "vol" ); m_panningModel.loadSettings( _this, "pan" ); + m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels() - 1 ); + m_effectChannelModel.loadSettings( _this, "fxch" ); } @@ -742,6 +752,14 @@ void SampleTrack::setPlayingTcos( bool isPlaying ) +void SampleTrack::updateEffectChannel() +{ + m_audioPort.setNextFxChannel( m_effectChannelModel.value() ); +} + + + + SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : @@ -749,13 +767,13 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : { setFixedHeight( 32 ); - TrackLabelButton * tlb = new TrackLabelButton( this, - getTrackSettingsWidget() ); - connect( tlb, SIGNAL( clicked( bool ) ), - this, SLOT( showEffects() ) ); - tlb->setIcon( embed::getIconPixmap( "sample_track" ) ); - tlb->move( 3, 1 ); - tlb->show(); + m_tlb = new TrackLabelButton(this, getTrackSettingsWidget()); + m_tlb->setCheckable(true); + connect(m_tlb, SIGNAL(clicked( bool )), + this, SLOT(showEffects())); + m_tlb->setIcon(embed::getIconPixmap("sample_track")); + m_tlb->move(3, 1); + m_tlb->show(); m_volumeKnob = new Knob( knobSmall_17, getTrackSettingsWidget(), tr( "Track volume" ) ); @@ -779,16 +797,10 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : m_panningKnob->setLabel( tr( "PAN" ) ); m_panningKnob->show(); - m_effectRack = new EffectRackView( _t->audioPort()->effects() ); - m_effectRack->setFixedSize( 240, 242 ); - - m_effWindow = gui->mainWindow()->addWindowedWidget( m_effectRack ); - m_effWindow->setAttribute( Qt::WA_DeleteOnClose, false ); - m_effWindow->layout()->setSizeConstraint( QLayout::SetFixedSize ); - m_effWindow->setWindowTitle( _t->name() ); - m_effWindow->hide(); - setModel( _t ); + + m_window = new SampleTrackWindow(this); + m_window->toggleVisibility(false); } @@ -796,7 +808,50 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : SampleTrackView::~SampleTrackView() { - m_effWindow->deleteLater(); + if(m_window != NULL) + { + m_window->setSampleTrackView(NULL); + m_window->parentWidget()->hide(); + } + m_window = NULL; +} + + + +QMenu * SampleTrackView::createFxMenu(QString title, QString newFxLabel) +{ + int channelIndex = model()->effectChannelModel()->value(); + + FxChannel *fxChannel = Engine::fxMixer()->effectChannel(channelIndex); + + // If title allows interpolation, pass channel index and name + if (title.contains("%2")) + { + title = title.arg(channelIndex).arg(fxChannel->m_name); + } + + QMenu *fxMenu = new QMenu(title); + + QSignalMapper * fxMenuSignalMapper = new QSignalMapper(fxMenu); + + fxMenu->addAction(newFxLabel, this, SLOT(createFxLine())); + fxMenu->addSeparator(); + + for (int i = 0; i < Engine::fxMixer()->numChannels(); ++i) + { + FxChannel * currentChannel = Engine::fxMixer()->effectChannel(i); + + if (currentChannel != fxChannel) + { + QString label = tr("FX %1: %2").arg(currentChannel->m_channelIndex).arg(currentChannel->m_name); + QAction * action = fxMenu->addAction(label, fxMenuSignalMapper, SLOT(map())); + fxMenuSignalMapper->setMapping(action, currentChannel->m_channelIndex); + } + } + + connect(fxMenuSignalMapper, SIGNAL(mapped(int)), this, SLOT(assignFxLine(int))); + + return fxMenu; } @@ -804,16 +859,7 @@ SampleTrackView::~SampleTrackView() void SampleTrackView::showEffects() { - if( m_effWindow->isHidden() ) - { - m_effectRack->show(); - m_effWindow->show(); - m_effWindow->raise(); - } - else - { - m_effWindow->hide(); - } + m_window->toggleVisibility(m_window->parentWidget()->isHidden()); } @@ -821,7 +867,261 @@ void SampleTrackView::showEffects() void SampleTrackView::modelChanged() { SampleTrack * st = castModel(); - m_volumeKnob->setModel( &st->m_volumeModel ); + m_volumeKnob->setModel(&st->m_volumeModel); TrackView::modelChanged(); } + + + +SampleTrackWindow::SampleTrackWindow(SampleTrackView * tv) : + QWidget(), + ModelView(NULL, this), + m_track(tv->model()), + m_stv(tv) +{ + // init own layout + widgets + setFocusPolicy(Qt::StrongFocus); + QVBoxLayout * vlayout = new QVBoxLayout(this); + vlayout->setMargin(0); + vlayout->setSpacing(0); + + TabWidget* generalSettingsWidget = new TabWidget(tr("GENERAL SETTINGS"), this); + + QVBoxLayout* generalSettingsLayout = new QVBoxLayout(generalSettingsWidget); + + generalSettingsLayout->setContentsMargins(8, 18, 8, 8); + generalSettingsLayout->setSpacing(6); + + QWidget* nameWidget = new QWidget(generalSettingsWidget); + QHBoxLayout* nameLayout = new QHBoxLayout(nameWidget); + nameLayout->setContentsMargins(0, 0, 0, 0); + nameLayout->setSpacing(2); + + // setup line edit for changing sample track name + m_nameLineEdit = new QLineEdit; + m_nameLineEdit->setFont(pointSize<9>(m_nameLineEdit->font())); + connect(m_nameLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(textChanged(const QString &))); + + m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred)); + nameLayout->addWidget(m_nameLineEdit); + + + generalSettingsLayout->addWidget(nameWidget); + + + QGridLayout* basicControlsLayout = new QGridLayout; + basicControlsLayout->setHorizontalSpacing(3); + basicControlsLayout->setVerticalSpacing(0); + basicControlsLayout->setContentsMargins(0, 0, 0, 0); + + QString labelStyleSheet = "font-size: 6pt;"; + Qt::Alignment labelAlignment = Qt::AlignHCenter | Qt::AlignTop; + Qt::Alignment widgetAlignment = Qt::AlignHCenter | Qt::AlignCenter; + + // set up volume knob + m_volumeKnob = new Knob(knobBright_26, NULL, tr("Sample volume")); + m_volumeKnob->setVolumeKnob(true); + m_volumeKnob->setHintText(tr("Volume:"), "%"); + + basicControlsLayout->addWidget(m_volumeKnob, 0, 0); + basicControlsLayout->setAlignment(m_volumeKnob, widgetAlignment); + + QLabel *label = new QLabel(tr("VOL"), this); + label->setStyleSheet(labelStyleSheet); + basicControlsLayout->addWidget(label, 1, 0); + basicControlsLayout->setAlignment(label, labelAlignment); + + + // set up panning knob + m_panningKnob = new Knob(knobBright_26, NULL, tr("Panning")); + m_panningKnob->setHintText(tr("Panning:"), ""); + + basicControlsLayout->addWidget(m_panningKnob, 0, 1); + basicControlsLayout->setAlignment(m_panningKnob, widgetAlignment); + + label = new QLabel(tr("PAN"),this); + label->setStyleSheet(labelStyleSheet); + basicControlsLayout->addWidget(label, 1, 1); + basicControlsLayout->setAlignment(label, labelAlignment); + + + basicControlsLayout->setColumnStretch(2, 1); + + + // setup spinbox for selecting FX-channel + m_effectChannelNumber = new FxLineLcdSpinBox(2, NULL, tr("FX channel"), m_stv); + + basicControlsLayout->addWidget(m_effectChannelNumber, 0, 3); + basicControlsLayout->setAlignment(m_effectChannelNumber, widgetAlignment); + + label = new QLabel(tr("FX"), this); + label->setStyleSheet(labelStyleSheet); + basicControlsLayout->addWidget(label, 1, 3); + basicControlsLayout->setAlignment(label, labelAlignment); + + generalSettingsLayout->addLayout(basicControlsLayout); + + m_effectRack = new EffectRackView(tv->model()->audioPort()->effects()); + m_effectRack->setFixedSize(240, 242); + + vlayout->addWidget(generalSettingsWidget); + vlayout->addWidget(m_effectRack); + + + setModel(tv->model()); + + QMdiSubWindow * subWin = gui->mainWindow()->addWindowedWidget(this); + Qt::WindowFlags flags = subWin->windowFlags(); + flags |= Qt::MSWindowsFixedSizeDialogHint; + flags &= ~Qt::WindowMaximizeButtonHint; + subWin->setWindowFlags(flags); + + // Hide the Size and Maximize options from the system menu + // since the dialog size is fixed. + QMenu * systemMenu = subWin->systemMenu(); + systemMenu->actions().at(2)->setVisible(false); // Size + systemMenu->actions().at(4)->setVisible(false); // Maximize + + subWin->setWindowIcon(embed::getIconPixmap("sample_track")); + subWin->setFixedSize(subWin->size()); + subWin->hide(); +} + + + +SampleTrackWindow::~SampleTrackWindow() +{ +} + + + +void SampleTrackWindow::setSampleTrackView(SampleTrackView* tv) +{ + if(m_stv && tv) + { + m_stv->m_tlb->setChecked(false); + } + + m_stv = tv; +} + + + +void SampleTrackWindow::modelChanged() +{ + m_track = castModel(); + + m_nameLineEdit->setText(m_track->name()); + + m_track->disconnect(SIGNAL(nameChanged()), this); + + connect(m_track, SIGNAL(nameChanged()), + this, SLOT(updateName())); + + m_volumeKnob->setModel(&m_track->m_volumeModel); + m_panningKnob->setModel(&m_track->m_panningModel); + m_effectChannelNumber->setModel(&m_track->m_effectChannelModel); + + updateName(); +} + + + +/*! \brief Create and assign a new FX Channel for this track */ +void SampleTrackView::createFxLine() +{ + int channelIndex = gui->fxMixerView()->addNewChannel(); + + Engine::fxMixer()->effectChannel(channelIndex)->m_name = getTrack()->name(); + + assignFxLine(channelIndex); +} + + + + +/*! \brief Assign a specific FX Channel for this track */ +void SampleTrackView::assignFxLine(int channelIndex) +{ + model()->effectChannelModel()->setValue(channelIndex); + + gui->fxMixerView()->setCurrentFxLine(channelIndex); +} + + + +void SampleTrackWindow::updateName() +{ + setWindowTitle(m_track->name().length() > 25 ? (m_track->name().left(24) + "...") : m_track->name()); + + if(m_nameLineEdit->text() != m_track->name()) + { + m_nameLineEdit->setText(m_track->name()); + } +} + + + +void SampleTrackWindow::textChanged(const QString& new_name) +{ + m_track->setName(new_name); + Engine::getSong()->setModified(); +} + + + +void SampleTrackWindow::toggleVisibility(bool on) +{ + if(on) + { + show(); + parentWidget()->show(); + parentWidget()->raise(); + } + else + { + parentWidget()->hide(); + } +} + + + + +void SampleTrackWindow::closeEvent(QCloseEvent* ce) +{ + ce->ignore(); + + if(gui->mainWindow()->workspace()) + { + parentWidget()->hide(); + } + else + { + hide(); + } + + m_stv->m_tlb->setFocus(); + m_stv->m_tlb->setChecked(false); +} + + + +void SampleTrackWindow::saveSettings(QDomDocument& doc, QDomElement & element) +{ + MainWindow::saveWidgetState(this, element); + Q_UNUSED(element) +} + + + +void SampleTrackWindow::loadSettings(const QDomElement& element) +{ + MainWindow::restoreWidgetState(this, element); + if(isVisible()) + { + m_stv->m_tlb->setChecked(true); + } +} + From 37290ace1d8824fc4e80779d9de7ebf5cfba4313 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 11 Mar 2019 23:03:43 +0100 Subject: [PATCH 75/79] Add info about LadspaControls::m_noLink --- plugins/LadspaEffect/LadspaControls.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/LadspaEffect/LadspaControls.cpp b/plugins/LadspaEffect/LadspaControls.cpp index 1a2f26a35..8e65e0e93 100644 --- a/plugins/LadspaEffect/LadspaControls.cpp +++ b/plugins/LadspaEffect/LadspaControls.cpp @@ -153,6 +153,9 @@ void LadspaControls::linkPort( int _port, bool _state ) { first->unlinkControls( m_controls[proc][_port] ); } + + // m_stereoLinkModel.setValue() will call updateLinkStatesFromGlobal() + // m_noLink will make sure that this will not unlink any other ports m_noLink = true; m_stereoLinkModel.setValue( false ); } From f8ba88d55a7f0069c54edb3b80a2ad8e7dc4187b Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 20:10:19 +0100 Subject: [PATCH 76/79] Make instrument window's piano optional --- include/Instrument.h | 2 ++ src/tracks/InstrumentTrack.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/Instrument.h b/include/Instrument.h index a373ae4ac..6ab8e0c66 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -63,6 +63,8 @@ public: // functions that can/should be re-implemented: // -------------------------------------------------------------------- + virtual bool hasNoteInput() const { return true; } + // 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 mixer-period diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 298430b03..6005402f1 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1650,6 +1650,8 @@ void InstrumentTrackWindow::updateInstrumentView() modelChanged(); // Get the instrument window to refresh m_track->dataChanged(); // Get the text on the trackButton to change + + m_pianoView->setVisible(m_track->m_instrument->hasNoteInput()); } } @@ -1704,7 +1706,9 @@ void InstrumentTrackWindow::closeEvent( QCloseEvent* event ) void InstrumentTrackWindow::focusInEvent( QFocusEvent* ) { - m_pianoView->setFocus(); + if(m_pianoView->isVisible()) { + m_pianoView->setFocus(); + } } @@ -1836,6 +1840,9 @@ void InstrumentTrackWindow::viewInstrumentInDirection(int d) // scroll the SongEditor/BB-editor to make sure the new trackview label is visible bringToFront->trackContainerView()->scrollToTrackView(bringToFront); + + // get the instrument window to refresh + modelChanged(); } bringToFront->getInstrumentTrackWindow()->setFocus(); } From aac516e27fb441bf754da145fb72a2705fa54a30 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 20:59:45 +0100 Subject: [PATCH 77/79] Forbid copying the Knob class --- include/Knob.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Knob.h b/include/Knob.h index 319b38184..245963ce2 100644 --- a/include/Knob.h +++ b/include/Knob.h @@ -74,6 +74,7 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView public: Knob( knobTypes _knob_num, QWidget * _parent = NULL, const QString & _name = QString() ); Knob( QWidget * _parent = NULL, const QString & _name = QString() ); //!< default ctor + Knob( const Knob& other ) = delete; virtual ~Knob(); // TODO: remove From 7e75a82f7ec5ef7f1d743d78c6bd68b6145ea54f Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 22:05:46 +0100 Subject: [PATCH 78/79] Always instantiate at least a dummy plugin --- src/core/Plugin.cpp | 36 ++++++++++++++++++++++------------ src/gui/EffectSelectDialog.cpp | 14 +++++++++---- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index b479d7d8d..12edb8644 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -90,10 +90,12 @@ AutomatableModel * Plugin::childModel( const QString & ) #include "PluginFactory.h" -Plugin * Plugin::instantiate( const QString& pluginName, Model * parent, - void * data ) +Plugin * Plugin::instantiate(const QString& pluginName, Model * parent, + void *data) { const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8()); + + Plugin* inst; if( pi.isNull() ) { if( gui ) @@ -104,23 +106,31 @@ Plugin * Plugin::instantiate( const QString& pluginName, Model * parent, arg( pluginName ).arg( pluginFactory->errorString(pluginName) ), QMessageBox::Ok | QMessageBox::Default ); } - return new DummyPlugin(); + inst = new DummyPlugin(); } - - InstantiationHook instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" ); - if( instantiationHook == NULL ) + else { - if( gui ) + InstantiationHook instantiationHook; + if ((instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" ))) { - QMessageBox::information( NULL, - tr( "Error while loading plugin" ), - tr( "Failed to load plugin \"%1\"!").arg( pluginName ), - QMessageBox::Ok | QMessageBox::Default ); + inst = instantiationHook(parent, data); + if(!inst) { + inst = new DummyPlugin(); + } + } + else + { + if( gui ) + { + QMessageBox::information( NULL, + tr( "Error while loading plugin" ), + tr( "Failed to load plugin \"%1\"!").arg( pluginName ), + QMessageBox::Ok | QMessageBox::Default ); + } + inst = new DummyPlugin(); } - return new DummyPlugin(); } - Plugin * inst = instantiationHook( parent, data ); return inst; } diff --git a/src/gui/EffectSelectDialog.cpp b/src/gui/EffectSelectDialog.cpp index 64b180d48..3c641acec 100644 --- a/src/gui/EffectSelectDialog.cpp +++ b/src/gui/EffectSelectDialog.cpp @@ -27,6 +27,7 @@ #include "ui_EffectSelectDialog.h" #include "gui_templates.h" +#include "DummyEffect.h" #include "embed.h" #include "PluginFactory.h" @@ -147,12 +148,17 @@ EffectSelectDialog::~EffectSelectDialog() Effect * EffectSelectDialog::instantiateSelectedPlugin( EffectChain * _parent ) { - if( !m_currentSelection.name.isEmpty() && m_currentSelection.desc ) + Effect* result = nullptr; + if(!m_currentSelection.name.isEmpty() && m_currentSelection.desc) { - return Effect::instantiate( m_currentSelection.desc->name, - _parent, &m_currentSelection ); + result = Effect::instantiate(m_currentSelection.desc->name, + _parent, &m_currentSelection); } - return NULL; + if(!result) + { + result = new DummyEffect(_parent, QDomElement()); + } + return result; } From 79524168b36dd1ecad9adb2585f88cc09bb6abe8 Mon Sep 17 00:00:00 2001 From: tresf Date: Mon, 18 Mar 2019 12:37:07 -0400 Subject: [PATCH 79/79] Bump zyn submodule Per #4642 --- plugins/zynaddsubfx/zynaddsubfx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/zynaddsubfx/zynaddsubfx b/plugins/zynaddsubfx/zynaddsubfx index c22acd61e..ccac06336 160000 --- a/plugins/zynaddsubfx/zynaddsubfx +++ b/plugins/zynaddsubfx/zynaddsubfx @@ -1 +1 @@ -Subproject commit c22acd61eb5d074988acea5fc1b6930151345c42 +Subproject commit ccac06336b363b9afe7ff4aea02bfa2d48187e1a